! $Id: ropp_pp_fsi.f90 2022 2022-07-05 19:27:28Z ychen $ !****s* bangle/ropp_pp_fsi * ! ! NAME ! ropp_pp_fsi - Calculate L1 and L2 bending angle profiles using ! full spectrum inversion (FSI). ! ! SYNOPSIS ! call ropp_pp_fsi(time, snr, phase, r_leo, r_gns, r_coc, roc, w_ls, ! w_smooth, hmax, filter, opt_DL2, cff, dsh, ! impact, bangle, ba_cov, diag) ! ! DESCRIPTION ! This routine calculates L1 and L2 bending angles using a FSI algorithm. ! ! INPUTS ! real(wp), dimension(:) :: time ! Relative time of samples (s) ! real(wp), dimension(:,:) :: snr ! L1,L2 amplitudes [channel, time] ! real(wp), dimension(:,:) :: phase ! L1,L2 excess phase (m) [ch, time] ! real(wp), dimension(:,:) :: r_leo ! LEO coordinates (m) (ECI or ECF) ! real(wp), dimension(:,:) :: r_gns ! GPS coordinates (m) (ECI or ECF) ! real(wp), dimension(:) :: r_coc ! Centre curvature coordinates (m) ! real(wp) :: roc ! Radius of curvature (m) ! integer :: month ! observation month ! real(wp) :: hmax ! Maximum height for WO processing ! character(len=*) :: filter ! Filter method ('optest','slpoly') ! real(wp), dimension(:,:) :: impact ! L1,L2 impact parameters (m) [ch,t] ! real(wp), dimension(:,:) :: bangle ! L1,L2 bending angles (rad) [ch,t] ! ! OUTPUT ! real(wp), dimension(:,:) :: impact ! L1,L2 impact parameters (m) [ch, t] ! real(wp), dimension(:,:) :: bangle ! L1,L2 bending angles (rad) [ch, ip] ! real(wp), dimension(:,:) :: ba_cov ! Estimate of bangle covariance ! type(PPdiag), optional :: diag ! Additional output diagnostics structure ! ! AUTHOR ! Yong Chen, NOAA/NESDIS/STAR, yong.chen@noaa.gov ! Loknath Adhikari, UMD/CISESS, loknath.adhikari@noaa.gov ! ! COPYRIGHT ! Copyright (c) 2022-2023 Yong Chen ! For further details please refer to the file COPYRIGHT ! which you should have received as part of this distribution. ! !**** SUBROUTINE ropp_pp_fsi(time, snr, phase, r_leo, r_gns, r_coc, roc, month, & hmax, opt_DL2, & impact, bangle, ba_cov, diag) !------------------------------------------------------------------------------- ! 1. Declarations !------------------------------------------------------------------------------- USE typesizes, ONLY: wp => EightByteReal USE ropp_pp, not_this => ropp_pp_fsi USE ropp_pp_constants, ONLY: c_light, pi, f_L1, f_L2 USE ropp_pp_spline USE ropp_pp_utils USE ropp_pp_types USE messages USE load_ciraq_model, only: read_ciraq_model USE star_fsi IMPLICIT NONE ! 1.1 Subroutine arguments REAL(wp), DIMENSION(:), INTENT(in) :: time ! Time of samples (s) REAL(wp), DIMENSION(:,:), INTENT(in) :: snr ! Amplitudes [ch, time] REAL(wp), DIMENSION(:,:), INTENT(in) :: phase ! Excess phase (m) [ch, t] REAL(wp), DIMENSION(:,:), INTENT(in) :: r_leo ! LEO coordinates (m) REAL(wp), DIMENSION(:,:), INTENT(in) :: r_gns ! GPS coordinates (m) REAL(wp), DIMENSION(:), INTENT(in) :: r_coc ! Centre of curvature (m) REAL(wp), INTENT(in) :: roc ! Radius of curvature (m) INTEGER, INTENT(in) :: month ! Observation momth REAL(wp), INTENT(in) :: hmax ! Maximum height for FSI LOGICAL, INTENT(in) :: opt_DL2 ! Degraded L2 REAL(wp), DIMENSION(:,:), INTENT(inout) :: impact ! Impact parameters (m) REAL(wp), DIMENSION(:,:), INTENT(inout) :: bangle ! Bending angles (rad) REAL(wp), DIMENSION(:,:), INTENT(inout) :: ba_cov ! Bending angle covariance TYPE(PPdiag), OPTIONAL, INTENT(inout) :: diag ! Additional diagnostics ! 1.2 Local parameters REAL(wp), PARAMETER :: PL = 1700.0_wp ! Lower estimate minimum ray height (meter) LOGICAL, PARAMETER :: opt_SH = .TRUE. ! Automatic shadow determination INTEGER, PARAMETER :: nmaxl1 = 65537 ! number of data point in the extended signal INTEGER, PARAMETER :: np_smooth = 3 ! Polynomial degree for smoothing regression REAL(wp), PARAMETER :: lowHSL = -50000.0_wp ! Low HSL for FSI smoothing (meter) REAL(wp), PARAMETER :: hws = 10000.0_wp ! impact height for different smoothing window size (meter) ! 1.3 Local scalars CHARACTER(len = 256) :: routine CHARACTER(len = 256) :: outstr CHARACTER(len = 256) :: benmod_file REAL(wp) :: Pmin, Pmax, Sec_LowSW ! min and max impact height, seconds using for smoothing below 10 km REAL(wp) :: dt, dx, dp, dE, df, pwmax, pwmin, dx_smooth, dpH INTEGER :: ocd, n, nc, ndf, ndf2, nx, i, ic INTEGER :: icw, imin, imax, ndE, nws, nr, nmaxlo, nmaxlsw REAL(wp), DIMENSION(:), ALLOCATABLE :: k ! Wave number [channel] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: dphdt ! doppler shift [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: dphdt_sm ! smoothed doppler shift [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: amp_sm ! smoothed amplitude [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: dph_sm ! reconstructed excess phase [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: full_phase ! full phase after adjustment to circular orbits (m) [ch, t] REAL(wp), DIMENSION(:), ALLOCATABLE :: teta ! central angle between 1st and 2nd radius-vectors REAL(wp) :: r10, r20 ! absolute radius for GNSS (m) for LEO (m) INTEGER :: iflag ! 0~teta increasing with time; 1~teta decreasing LOGICAL :: apply_SH ! flag to apply shadow height determination INTEGER, DIMENSION(:), ALLOCATABLE :: nout ! array size for impact height and bending angle [channel] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: pp ! impact parameter [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: ee ! bending angle [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: aa ! FSI amplitude [ch, t] INTEGER, DIMENSION(:), ALLOCATABLE :: noutL ! array size for impact height and bending angle [channel] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: ppL ! impact parameter [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: eeL ! bending angle [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: aaL ! FSI amplitude [ch, t] INTEGER, DIMENSION(:), ALLOCATABLE :: noutf ! array size for impact height and bending angle [channel] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: ppf ! impact parameter [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: eef ! bending angle [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: aaf ! FSI amplitude [ch, t] REAL(wp), DIMENSION(:), ALLOCATABLE :: spike_th ! spike threshold REAL(wp), DIMENSION(:), ALLOCATABLE :: pp_out ! impact parameter [t] REAL(wp), DIMENSION(:), ALLOCATABLE :: ee_out ! bending angle [t] REAL(wp), DIMENSION(:), ALLOCATABLE :: aa_out ! FSI amplitude [t] INTEGER, DIMENSION(:), ALLOCATABLE :: idx ! array index for the keeped impact parameter and bending angles INTEGER :: n_pe ! aaray size REAL(wp) :: spike_thresh ! spike threshold REAL(wp), DIMENSION(:), ALLOCATABLE :: ppL1 ! impact parameter [t] REAL(wp), DIMENSION(:), ALLOCATABLE :: eeL1 ! bending angle [t] REAL(wp), DIMENSION(:), ALLOCATABLE :: aaL1 ! FSI amplitude [t] INTEGER, DIMENSION(:), ALLOCATABLE :: idxL1 ! array index for the keeped impact parameter and bending angles INTEGER :: npts ! aaray size REAL(wp), DIMENSION(:, :), ALLOCATABLE :: ppLSW ! LSW mean impact height REAL(wp), DIMENSION(:, :), ALLOCATABLE :: eeLSW ! LSW mean bending angle REAL(wp), DIMENSION(:, :), ALLOCATABLE :: LSWMG ! bending angle LSW covariance using squared dalp [ch, t] REAL(wp), DIMENSION(:, :), ALLOCATABLE :: LSWSS ! bending angle LSW covariance using absolute dalp [ch, t] INTEGER, DIMENSION(:), ALLOCATABLE :: noutlws ! array size for LSW impact height and bending REAL(wp), DIMENSION(:), ALLOCATABLE :: PminC ! Estimate of shadow border REAL(wp), DIMENSION(:), ALLOCATABLE :: EW ! Bangle for re-interpolation REAL(wp), DIMENSION(:), ALLOCATABLE :: ECW ! Ba cov for re-interpolation LOGICAL, DIMENSION(:), ALLOCATABLE :: MW ! Mask for computation of dE REAL(wp), DIMENSION(:), ALLOCATABLE :: smooth_ba ! 1.4 Local arrays CALL message_get_routine(routine) CALL message_set_routine('ropp_pp_fsi') !------------------------------------------------------------------------------- ! 2. Initialization !------------------------------------------------------------------------------- ! 2.1 Determination of data sizes n = SIZE(time) nc = SIZE(snr,1) nr = CEILING(REAL(n,wp)/8000.0_wp) ALLOCATE(k(nc)) ! Computation of wave vectors k(1) = 2*pi*f_L1/C_Light k(2) = 2*pi*f_L2/C_Light ! Use CIRA+Q bending angle model to propogate to circular orbits benmod_file='BENMOD' call read_ciraq_model(benmod_file) ! rising/setting flag (rising 1, setting -1) ocd = NINT(SIGN(1.0_wp, impact(1, n) - impact(1, 1))) ! Determine the sampling frequency (normally 50 Hz, for COMSIC-2, 100 Hz) dt = abs(time(n) - time(1))/n ! For impact height above 10 km, using sampling rate as smoothing window ndf = NINT(1.0_wp/dt) ! Yong Chen 11/08/2023 to increasing the smoothing window size below 10 km for RO data rate of 50 Hz ! for RO data rate of 50 Hz IF (ndf < 55 ) THEN Sec_LowSW = 0.3_wp ! for RO data rate of 100 Hz ELSE Sec_LowSW = 0.1_wp ENDIF ndf2 = NINT(1.0_wp*ndf/2) ! lower HSL (-50 km) position for raising/setting profile if (ocd == 1 ) THEN imax = MIN(SUM(MINLOC(impact(1,:), impact(1,:) >= roc + lowHSL)), & SUM(MAXLOC(impact(1,:), impact(1,:) >= roc + lowHSL))) ELSE imax = MAX(SUM(MINLOC(impact(1,:), impact(1,:) >= roc + lowHSL)), & SUM(MAXLOC(impact(1,:), impact(1,:) >= roc + lowHSL))) ENDIF ! array size for raising/setting profile above HSL -50 km IF (ocd == 1) THEN nmaxlo = n - imax + 1 ELSE nmaxlo = imax ENDIF write(*, *) 'n, imax, nmaxlo=', ocd, n, imax, nmaxlo, impact(1,1), impact(1,n), roc + lowHSL ! Determine the Doppler ALLOCATE(dphdt(nc, nmaxlo)) ALLOCATE(dphdt_sm(nc,nmaxlo)) ALLOCATE(amp_sm(nc,nmaxlo)) ALLOCATE(dph_sm(nc,nmaxlo)) ALLOCATE(full_phase(nc,nmaxlo)) ALLOCATE(teta(nmaxlo)) ! Apply Fourier smoothing of the excess phase ! Reconstruct phase from smoothed Doppler ! Rising profile IF (ocd == 1) THEN CALL phs2dop(phase(:,n:n-nmaxlo+1:-1), dphdt(:,:)) DO ic=1,nc CALL fsi_fourier_filter(nmaxlo, ndf2, dphdt(ic, :), dphdt_sm(ic, :)) CALL fsi_fourier_filter(nmaxlo, ndf, snr(ic, n:n-nmaxlo+1:-1), amp_sm(ic, :)) ENDDO CALL dop2phs(phase(:,n:n-nmaxlo+1:-1), dphdt_sm, dph_sm) ELSE ! Setting profile CALL phs2dop(phase(:,1:nmaxlo), dphdt) DO ic=1,nc CALL fsi_fourier_filter(nmaxlo, ndf2, dphdt(ic, :), dphdt_sm(ic, :)) CALL fsi_fourier_filter(nmaxlo, ndf, snr(ic, 1:nmaxlo), amp_sm(ic, :)) ENDDO CALL dop2phs(phase(:,1:nmaxlo), dphdt_sm, dph_sm) ENDIF ! adjustment phase for circular orbits IF (ocd == 1) THEN CALL gpsleofix(nmaxlo, r_gns(n:n-nmaxlo+1:-1, :), r_leo(n:n-nmaxlo+1:-1, :), r_coc, & dph_sm, month, r10, r20, teta, full_phase, iflag) IF (iflag /= 0) THEN CALL message(msg_error,'Rising profile is not recognised. Check gpsleofix. ') ENDIF ELSE CALL gpsleofix(nmaxlo, r_gns(1:nmaxlo, :), r_leo(1:nmaxlo, :), r_coc, & dph_sm, month, r10, r20, teta, full_phase, iflag) IF (iflag /= 0) THEN CALL message(msg_error,'Setting profile is not recognised. Check gpsleofix. ') ENDIF ENDIF ! minimun and maximum impact height from L1 (10 km to hmax (25) km) Pmax = MIN(hmax, MAXVAL(impact(1,:)) - roc) Pmin = PL ! hws ! Full-Spectrum-Inversion (FSI) (using open angle as a basic variable instead of time) ! teta should increasing with time (already treated as setting profile) ALLOCATE(pp(nc,nmaxl1)) ALLOCATE(ee(nc,nmaxl1)) ALLOCATE(aa(nc,nmaxl1)) ALLOCATE(nout(nc)) !apply_SH = .FALSE. apply_SH = .TRUE. CALL fsi_leo(teta, full_phase, amp_sm, r10, r20, pp, ee, aa, Pmin+roc, Pmax+roc, apply_SH, nout) write(*,*)'min max impH after fsi_leo', pp(1, 1)-roc, pp(1, nout(1))-roc, & pp(2, 1)-roc, pp(2, nout(2))-roc DEALLOCATE(dphdt) DEALLOCATE(dphdt_sm) DEALLOCATE(amp_sm) DEALLOCATE(dph_sm) DEALLOCATE(full_phase) DEALLOCATE(teta) ! only apply to L1 signal to remove spikes ALLOCATE(ppL1(nmaxl1)) ALLOCATE(eeL1(nmaxl1)) ALLOCATE(aaL1(nmaxl1)) ALLOCATE(idxL1(nmaxl1)) dx = 250.0_wp dp = abs(pp(1, nout(1)) - pp(1, 1))/(nout(1) -1) nx = NINT(dx/dp) spike_thresh = 0.5_wp IF ( MOD(nx,2) /= 1) THEN nx = nx-1 ENDIF CALL remove_spikes(pp(1, 1:nout(1)), ee(1, 1:nout(1)), & nx, spike_thresh, ppL1, eeL1, idxL1, npts) write(*,*) 'npts', npts, nout(1) DO i=1, npts aaL1(i) = aa(1, idxL1(i)) ENDDO ! For lower level of data below 10 km impact height with smaller smoothing window size !ndf = NINT(0.1_wp/dt) ! Yong Chen 11/08/2023 to change smoothing window size below 10 km based on RO data rate of 50 Hz or 100 Hz ndf = NINT(Sec_LowSW/dt) ndf2 = NINT(1.0_wp * ndf/2) ! Determine the Doppler ALLOCATE(dphdt(nc, n)) ALLOCATE(dphdt_sm(nc,n)) ALLOCATE(amp_sm(nc,n)) ALLOCATE(dph_sm(nc,n)) ALLOCATE(full_phase(nc,n)) ALLOCATE(teta(n)) ! Apply Fourier smoothing of the excess phase ! Reconstruct phase from smoothed Doppler ! Rising profile IF (ocd == 1) THEN CALL phs2dop(phase(:,n:1:-1), dphdt(:,:)) DO ic=1,nc CALL fsi_fourier_filter(n, ndf2, dphdt(ic, :), dphdt_sm(ic, :)) CALL fsi_fourier_filter(n, ndf, snr(ic, n:1:-1), amp_sm(ic, :)) ENDDO CALL dop2phs(phase(:,n:1:-1), dphdt_sm, dph_sm) ELSE ! Setting profile CALL phs2dop(phase, dphdt) DO ic=1,nc CALL fsi_fourier_filter(n, ndf2, dphdt(ic, :), dphdt_sm(ic, :)) CALL fsi_fourier_filter(n, ndf, snr(ic, :), amp_sm(ic, :)) ENDDO CALL dop2phs(phase, dphdt_sm, dph_sm) ENDIF ! adjustment phase for circular orbits IF (ocd == 1) THEN CALL gpsleofix(n, r_gns(n:1:-1, :), r_leo(n:1:-1, :), r_coc, & dph_sm, month, r10, r20, teta, full_phase, iflag) IF (iflag /= 0) THEN CALL message(msg_error,'Rising profile is not recognised. Check gpsleofix. ') ENDIF ELSE CALL gpsleofix(n, r_gns, r_leo, r_coc, dph_sm, month, r10, r20, teta, full_phase, iflag) IF (iflag /= 0) THEN CALL message(msg_error,'Setting profile is not recognised. Check gpsleofix. ') ENDIF ENDIF ! maximum impact height from L1 Pmax = MIN(hmax, MAXVAL(impact(1,:)) - roc) Pmin = PL !MIN(PL, MINVAL(impact(1,:)) - roc) ! Full-Spectrum-Inversion (FSI) (using open angle as a basic variable instead of time) ! teta should increasing with time (already treated as setting profile) ALLOCATE(ppL(nc,nmaxl1)) ALLOCATE(eeL(nc,nmaxl1)) ALLOCATE(aaL(nc,nmaxl1)) ALLOCATE(noutL(nc)) apply_SH = .TRUE. CALL fsi_leo(teta, full_phase, amp_sm, r10, r20, ppL, eeL, aaL, Pmin+roc, Pmax+roc, apply_SH, noutL) write(*,*)'min max impH after fsi_leo', ppL(1, 1)-roc, ppL(1, noutL(1))-roc, & ppL(2, 1)-roc, ppL(2, noutL(2))-roc ! calculate the LSW covariance nmaxlsw = MAXVAL(noutL) ALLOCATE(ppLSW(nc, nmaxlsw)) ALLOCATE(eeLSW(nc, nmaxlsw)) ALLOCATE(LSWMG(nc, nmaxlsw)) ALLOCATE(LSWSS(nc, nmaxlsw)) ALLOCATE(noutlws(nc)) DO ic=1,nc CALL fsi_lsw(roc, ppL(ic, 1:noutL(ic)), eeL(ic, 1:noutL(ic)), & ppLSW(ic, :), eeLSW(ic, :), LSWMG(ic, :), LSWSS(ic, :), noutlws(ic)) ENDDO DEALLOCATE(dphdt) DEALLOCATE(dphdt_sm) DEALLOCATE(amp_sm) DEALLOCATE(dph_sm) DEALLOCATE(full_phase) DEALLOCATE(teta) ALLOCATE(ppf(nc,nmaxl1)) ALLOCATE(eef(nc,nmaxl1)) ALLOCATE(aaf(nc,nmaxl1)) ALLOCATE(noutf(nc)) ! combine the data from Pmin to Pmax, with seperation at 10 km for L1 ! upper level from 10 km to 25 km using large smoothing window ! lower level below 10 km using small smmothing window ! for L2 using the large smoothing window pp, ee, and aa DO ic=1,nc IF(ic == 1) THEN imin = SUM(MAXLOC(ppL1(1:npts), ppL1(1:npts) <= hws+roc)) IF(imin > 0) THEN write(*, *) '10 km impact height imin =', imin, ppL1(imin+1), hws+roc ppf(ic, 1:imin) = ppL1(1:imin) eef(ic, 1:imin) = eeL1(1:imin) aaf(ic, 1:imin) = aaL1(1:imin) noutf(ic) = imin ELSE ! all impact heights are higher than 10 km ppf(ic, 1:npts) = ppL1(1:npts) eef(ic, 1:npts) = eeL1(1:npts) aaf(ic, 1:npts) = aaL1(1:npts) noutf(ic) = npts ENDIF imax = SUM(MAXLOC(ppL(ic, 1:noutL(ic)), ppL(ic, 1:noutL(ic)) <= hws+roc)) IF ( imax > 0) THEN !imapct height are lower than 10 km write(*, *) '10 km impact height imax =', imin, ppL(ic, imax-1), hws+roc ppf(ic, noutf(ic)+1:noutf(ic)+noutL(ic)-imax) = ppL(ic, imax+1:noutL(ic)) eef(ic, noutf(ic)+1:noutf(ic)+noutL(ic)-imax) = eeL(ic, imax+1:noutL(ic)) aaf(ic, noutf(ic)+1:noutf(ic)+noutL(ic)-imax) = aaL(ic, imax+1:noutL(ic)) noutf(ic) = noutf(ic)+noutL(ic)-imax ENDIF ELSE ! L2 using the large smoothing window pp, ee, and aa ppf(ic, 1:nout(ic)) = pp(ic, 1:nout(ic)) eef(ic, 1:nout(ic)) = ee(ic, 1:nout(ic)) aaf(ic, 1:nout(ic)) = aa(ic, 1:nout(ic)) noutf(ic) = nout(ic) ENDIF ENDDO DEALLOCATE(pp) DEALLOCATE(ee) DEALLOCATE(aa) DEALLOCATE(nout) DEALLOCATE(ppL) DEALLOCATE(eeL) DEALLOCATE(aaL) DEALLOCATE(noutL) DEALLOCATE(ppL1) DEALLOCATE(eeL1) DEALLOCATE(aaL1) DEALLOCATE(idxL1) ALLOCATE(PminC(nc)) ALLOCATE(spike_th(nc)) PminC(1) = Pmin PminC(2) = Pmin ! 250 m segment length ! set threshold at +- 75% (100%) of mean spike_th(1) = 0.75_wp spike_th(2) = 1.0_wp dx = 250.0_wp dx_smooth = 250.0_wp Channels: DO ic=1,nc ALLOCATE(pp_out(nmaxl1)) ALLOCATE(ee_out(nmaxl1)) ALLOCATE(aa_out(nmaxl1)) ALLOCATE(idx(nmaxl1)) ! remove outliers before applying smoothing dp = abs(ppf(ic, noutf(ic)) - ppf(ic, 1))/(noutf(ic) -1) nx = NINT(dx/dp) IF ( MOD(nx,2) /= 1) THEN nx = nx-1 ENDIF CALL remove_spikes(ppf(ic, 1:noutf(ic)), eef(ic, 1:noutf(ic)), & nx, spike_th(ic), pp_out, ee_out, idx, n_pe) write(*,*) 'n_pe', n_pe write(*,*) 'ee_out', ee_out(n_pe-10:n_pe) ALLOCATE(smooth_ba(n_pe)) DO i=1, n_pe aa_out(i) = aaf(ic, idx(i)) ENDDO pwmax = MAXVAL(pp_out(1:n_pe)) pwmin = MINVAL(pp_out(1:n_pe)) dpH = nr* ABS(pwmax - pwmin)/(n_pe - 1) nws = NINT(REAL(dx_smooth,wp) / dpH) write(*,*) 'dph, nws, nr', dph, nws, nr CALL ropp_pp_sliding_polynomial(pp_out(1:n_pe:nr), ee_out(1:n_pe:nr), & nws, np_smooth, smooth_ba(1:n_pe:nr)) IF (nr > 1) THEN CALL ropp_pp_interpol(pp_out(1:n_pe:nr), pp_out(1:n_pe), & smooth_ba(1:n_pe:nr), smooth_ba(1:n_pe)) ENDIF !write(*,*) 'smooth_ba', smooth_ba(n_pe-10:n_pe) ! Re-define Pmin IF (opt_SH) THEN PminC(ic) = min(pp_out(1),pp_out(n_pe)) - roc ELSE PminC(ic) = Pmin ENDIF IF(opt_DL2) THEN Pmin = PminC(ic) ELSE Pmin = PminC(1) ENDIF WRITE(outstr, '(2(A,F10.3))') 'Pmin = ', Pmin, ' Pmax= ', Pmax CALL message(msg_diag, outstr) WRITE(outstr, '(2(A,F18.3))') 'pp_out(1) = ', pp_out(1), ' pp_out(n_pe)= ', pp_out(n_pe) CALL message(msg_diag, outstr) ! 11.5 Redefenition of impact parameter grid imax = SUM(MAXLOC(impact(ic,:), impact(ic,:) < roc + Pmax)) IF (imax > n .OR. imax < 1) THEN CALL message(msg_warn, 'No data for FSI processing - will not process') RETURN ENDIF IF (impact(ic,1) < roc + Pmax) THEN imin = 1 ELSE imin = n ENDIF DO i=imin,imax,SIGN(1,imax-imin) impact(ic,i) = roc + (Pmin*REAL(imax-i,wp) + Pmax*REAL(i-imin,wp)) / & REAL(imax-imin,wp) ENDDO ! 11.6 Interpolation of bending angle and covariances onto impact grid ba_cov(ic,:) = 0.0_wp DO i=1,n IF (impact(ic,i) - roc < Pmax) THEN CALL ropp_pp_interpol(pp_out(1:n_pe), impact(ic,i), & smooth_ba(1:n_pe), bangle(ic,i)) IF ( noutlws(ic) > 0 ) THEN CALL ropp_pp_interpol(ppLSW(ic, 1:noutlws(ic)), impact(ic,i), & LSWMG(ic, 1:noutlws(ic)), ba_cov(ic,i)) ENDIF ENDIF ENDDO ! Interpolation amplititude to standard grid or output amplitude to diag DEALLOCATE(pp_out) DEALLOCATE(ee_out) DEALLOCATE(aa_out) DEALLOCATE(idx) DEALLOCATE(smooth_ba) ENDDO Channels DEALLOCATE(ppLSW) DEALLOCATE(eeLSW) DEALLOCATE(LSWMG) DEALLOCATE(LSWSS) DEALLOCATE(noutlws) DEALLOCATE(ppf) DEALLOCATE(eef) DEALLOCATE(aaf) DEALLOCATE(noutf) !------------------------------------------------------------------------------- ! 13. Synchronizing grids for all channels !------------------------------------------------------------------------------- IF (opt_DL2) THEN ! 13.1 Determination of Pmin from best channel icw = 1 Pmin = PminC(icw) WRITE(outstr, '(2X,A,I2,A,F10.3)') 'ICW = ', ICW, ' Pmin = ', Pmin CALL message(msg_diag, outstr) ! 13.2 Grid redefinition and interpolation ALLOCATE(EW(n)) ALLOCATE(ECW(n)) ALLOCATE(MW(n)) DO ic=1,nc CALL ropp_pp_interpol(impact(ic,:), impact(icw,:), bangle(ic,:), EW(:), & Cext=.true.) CALL ropp_pp_interpol(impact(ic,:), impact(icw,:), ba_cov(ic,:), ECW(:), & Cext=.true.) MW(:) = (impact(icw,:) >= roc + PminC(ic) + 1000.0 .AND. & impact(icw,:) <= roc + PminC(ic) + 6000.0) ndE = COUNT(Mask = MW(:)) IF (ndE > 20) THEN dE = SUM(EW(:) - bangle(icw,:), Mask = MW(:))/ndE ELSE dE = 0.0_wp ENDIF WHERE (impact(icw,:) < roc+PminC(ic)) bangle(ic,:) = bangle(icw,:) + dE ba_cov(ic,:) = ba_cov(icw,:) ELSEWHERE bangle(ic,:) = EW(:) ba_cov(ic,:) = ECW(:) END WHERE impact(ic,:) = impact(icw,:) ENDDO DEALLOCATE(EW) DEALLOCATE(ECW) DEALLOCATE(MW) ENDIF !------------------------------------------------------------------------------- ! 14. Clean up !------------------------------------------------------------------------------- DEALLOCATE(PminC) DEALLOCATE(k) DEALLOCATE(spike_th) END SUBROUTINE ropp_pp_fsi