C++********************************************************************* C C ALRQ_MS.F MODIFIED FOR FFTW USE MAR 2008 ARDEAN LEITH C NO RETURN IN || ON INTEL FORT JUL 2008 ARDEAN LEITH C C ********************************************************************** C=* FROM: SPIDER - MODULAR IMAGE PROCESSING SYSTEM. AUTHOR: J.FRANK * C=* Copyright (C) 1985-2008 Health Research Inc. * C=* * C=* HEALTH RESEARCH INCORPORATED (HRI), * C=* ONE UNIVERSITY PLACE, RENSSELAER, NY 12144-3455. * C=* * C=* Email: spider@wadsworth.org * C=* * C=* This program is free software; you can redistribute it and/or * C=* modify it under the terms of the GNU General Public License as * C=* published by the Free Software Foundation; either version 2 of the * C=* License, or (at your option) any later version. * C=* * C=* This program is distributed in the hope that it will be useful, * C=* but WITHOUT ANY WARRANTY; without even the implied warranty of * C=* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * C=* General Public License for more details. * C=* * C=* You should have received a copy of the GNU General Public License * C=* along with this program; if not, write to the * C=* Free Software Foundation, Inc., * C=* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * C=* * C ********************************************************************** C C ALRQ_MS(XIM, NSAM,NROW, CNS2,CNR2, NUMR,CIRC,LCIRC, NRING,MODE) C C PURPOSE: INTERPOLATES: XIM IMAGE INTO POLAR COORDINATES AND STACKS C THE RINGS INTO: CIRC OUTPUT ARRAY. C FFTW3 WILL BE USED ON RINGS. C C PARAMETERS: C XIM IMAGE ARRAY (INPUT) C NSAM,NROW MAGE DIMENSIONS (INPUT) C CNS2,CNR2 PREDEFINED CENTERS (INPUT) C NUMR RING CONTROL ARRAY (INPUT) C CIRC POLAR ARRAY (OUTPUT) C LCIRC LENGTH OF CIRC ARRAY (INPUT) C NRING NUMBER OF RINGS (INPUT) C MODE HALF OR FULL CIRCLE (INPUT) C C NOTE: THIS ROUTINE AND THE CALLED QUADRI FUNCTION TAKE 17% C OF TIME IN: 'AP SH' C C23456789012345678901234567890123456789012345678901234567890123456789012 C--********************************************************************* C --------------------- ALRQ_MS_NEW -------------------------- SUBROUTINE ALRQ_MS_NEW(XIM, NSAM,NROW, CNS2,CNR2, & NUMR,CIRC,LCIRC, & NRING,MODE,NEWFFT,USE_OMP_PARALLEL, & AVO,VRIN) REAL, INTENT(INOUT) :: XIM(NSAM,NROW), CIRC(LCIRC) INTEGER, INTENT(IN) :: NUMR(3,NRING), NRING,LCIRC CHARACTER*1 :: MODE LOGICAL, INTENT(IN) :: NEWFFT LOGICAL, INTENT(IN) :: USE_OMP_PARALLEL DOUBLE PRECISION, INTENT(IN) :: AVO,VRIN DOUBLE PRECISION :: PI,DFI REAL :: CIRCT INCLUDE 'CMBLOCK.INC' C CNS2 AND CNR2 ARE PREDEFINED CENTERS C USING NORMALIZATION JUST FROM RINGS GIVES DIFFERENT ANSWERS C FROM NORMASC, PROBABLY OK BUT I WILL NOT USE IT. PI = 2 * DATAN(1.0D0) C FILL ALL THE RINGS IF (USE_OMP_PARALLEL) THEN c$omp parallel do private(it,inr,yq,igo,nval,lt,nsim,dfi,xold,yold, c$omp& circt,jt,fi,x,y) DO IT=1,NRING INR = NUMR(1,IT) ! RADIUS OF THE CURRENT RING YQ = INR ! FLOATING POINT RADIUS IGO = NUMR(2,IT) ! STARTING LOCATION FOR RING NVAL = NUMR(3,IT) ! LENGTH OF THIS RING IF (NEWFFT) THEN C THE ACTUAL, POWER-OF-TWO LENGTH IS NUMR(3,I)-2, ADDITIONAL C TWO LOCATIONS ARE ONLY FOR THE NEW FFT. CIRC(IGO+NVAL-1) = 0.0 CIRC(IGO+NVAL-2) = 0.0 NVAL = NVAL - 2 ENDIF IF (MODE .EQ. 'H') THEN LT = NVAL / 2 ELSEIF (MODE.EQ.'F') THEN LT = NVAL / 4 ENDIF LTIGO = LT + IGO LTLTIGO = LT + LT + IGO LTLTLTIGO = LT + LT + LT + IGO NSIM = LT - 1 DFI = PI / (NSIM+1) C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = CNS2 Y = INR + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN WRITE(NOUT,*) 'For image size1: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y 90 FORMAT(' FOR LOCATION: (',F7.1,',',F7.1,')') CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) C RETURN NOT POSSIBLE WITH INTEL PARALLEL COMPILER ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(IGO) = (CIRCT - AVO) * VRIN C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = INR + CNS2 Y = + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN WRITE(NOUT,*) 'For image size2: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) C RETURN NOT POSSIBLE WITH INTEL PARALLEL COMPILER ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTIGO) = (CIRCT - AVO) * VRIN IF (MODE .EQ. 'F') THEN C FILL OTHER HALF OF CIRCLE C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = 0.0 + CNS2 Y = -INR + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN WRITE(NOUT,*) 'For image size3: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) C RETURN NOT POSSIBLE WITH INTEL PARALLEL COMPILER ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTLTIGO) = (CIRCT - AVO) * VRIN C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = -INR + CNS2 Y = 0.0 + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN WRITE(NOUT,*) 'For image size4: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) C RETURN NOT POSSIBLE WITH INTEL PARALLEL COMPILER ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTLTLTIGO) = (CIRCT - AVO) * VRIN ENDIF DO JT=1,NSIM ! LOOP NSIM TIMES TO FILL RING FI = DFI * JT X = SIN(FI) * YQ Y = COS(FI) * YQ CIRCT = QUADRI_FAST(X+CNS2,Y+CNR2,NSAM,NROW,XIM) CIRC(JT+IGO) = (CIRCT - AVO) * VRIN CIRCT = QUADRI_FAST(Y+CNS2,-X+CNR2,NSAM,NROW,XIM) CIRC(JT+LTIGO) = (CIRCT - AVO) * VRIN IF (MODE .EQ. 'F') THEN C FILL OTHER HALF OF CIRCLE CIRCT = QUADRI_FAST(-X+CNS2,-Y+CNR2,NSAM,NROW,XIM) CIRC(JT+LTLTIGO) = (CIRCT - AVO) * VRIN CIRCT = QUADRI_FAST(-Y+CNS2,X+CNR2,NSAM,NROW,XIM) CIRC(JT+LTLTLTIGO) = (CIRCT - AVO) * VRIN ENDIF ENDDO ENDDO ELSE C FILL ALL THE RINGS DO IT=1,NRING INR = NUMR(1,IT) ! RADIUS OF THE CURRENT RING YQ = INR ! FLOATING POINT RADIUS IGO = NUMR(2,IT) ! STARTING LOCATION FOR RING NVAL = NUMR(3,IT) ! LENGTH OF THIS RING IF (NEWFFT) THEN C THE ACTUAL, POWER-OF-TWO LENGTH IS NUMR(3,I)-2, ADDITIONAL C TWO LOCATIONS ARE ONLY FOR THE NEW FFT. CIRC(IGO+NVAL-1) = 0.0 CIRC(IGO+NVAL-2) = 0.0 NVAL = NVAL - 2 ENDIF IF (MODE .EQ. 'H') THEN LT = NVAL / 2 ELSEIF (MODE.EQ.'F') THEN LT = NVAL / 4 ENDIF LTIGO = LT + IGO LTLTIGO = LT + LT + IGO LTLTLTIGO = LT + LT + LT + IGO NSIM = LT - 1 DFI = PI / (NSIM+1) C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = CNS2 Y = INR + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN !WRITE(NOUT,*) 'For image size1: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) RETURN ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(IGO) = (CIRCT - AVO) * VRIN C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = INR + CNS2 Y = + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN !WRITE(NOUT,*) 'For image size2: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) RETURN ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTIGO) = (CIRCT - AVO) * VRIN IF (MODE .EQ. 'F') THEN C FILL OTHER HALF OF CIRCLE C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = 0.0 + CNS2 Y = -INR + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN !WRITE(NOUT,*) 'For image size3: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) RETURN ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTLTIGO) = (CIRCT - AVO) * VRIN C TO AVOID SLOW BOUNDARY TESTS IN QUADRI_FAST, PUT THEM HERE X = -INR + CNS2 Y = 0.0 + CNR2 IF (X .LE. 2.0 .OR. X .GE. (FLOAT(NSAM)-1.0) .OR. & Y .LE. 2.0 .OR. Y .GE. (FLOAT(NROW)-1.0) ) THEN !WRITE(NOUT,*) 'For image size4: ',NSAM,NROW,INR WRITE(NOUT,90) X,Y CALL ERRT(101,'RING GOES OUTSIDE IMAGE',NE) RETURN ENDIF CIRCT = QUADRI_FAST(X,Y,NSAM,NROW,XIM) CIRC(LTLTLTIGO) = (CIRCT - AVO) * VRIN ENDIF DO JT=1,NSIM ! LOOP NSIM TIMES TO FILL RING FI = DFI * JT X = SIN(FI) * YQ Y = COS(FI) * YQ XT = X+CNS2 YT = Y+CNR2 CIRCT = QUADRI_FAST(XT,YT,NSAM,NROW,XIM) CIRC(JT+IGO) = (CIRCT - AVO) * VRIN XT = Y+CNS2 YT = -X+CNR2 CIRCT = QUADRI_FAST(XT,YT,NSAM,NROW,XIM) CIRC(JT+LTIGO) = (CIRCT - AVO) * VRIN IF (MODE .EQ. 'F') THEN C FILL OTHER HALF OF CIRCLE XT = -X+CNS2 YT = -Y+CNR2 CIRCT = QUADRI_FAST(XT,YT,NSAM,NROW,XIM) CIRC(JT+LTLTIGO) = (CIRCT - AVO) * VRIN XT = -Y+CNS2 YT = X+CNR2 CIRCT = QUADRI_FAST(XT,YT,NSAM,NROW,XIM) CIRC(JT+LTLTLTIGO) = (CIRCT - AVO) * VRIN ENDIF ENDDO ENDDO ENDIF END