mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-10-31 15:47:10 -04:00
216 lines
6.3 KiB
Fortran
216 lines
6.3 KiB
Fortran
subroutine timf2(k,nxpol,nfft,nwindow,nb,peaklimit,iqadjust,iqapply,faclim, &
|
|
cx0,cy0,gainx,gainy,phasex,phasey,cx1,cy1,slimit,lstrong,px,py,nzap)
|
|
|
|
! Sequential processing of time-domain I/Q data, using Linrad-like
|
|
! "first FFT" and "first backward FFT".
|
|
|
|
! cx0,cy0 - complex input data
|
|
! nfft - length of FFTs
|
|
! nwindow - 0 for no window, 2 for sin^2 window
|
|
! iqapply - 0/1 determines if I/Q phase and amplitude corrections applied
|
|
! gainx,y - gain error in Q channel, relative to I
|
|
! phasex,y - phase error
|
|
! cx1,cy1 - output data
|
|
|
|
! Non-windowed processing means no overlap, so kstep=nfft.
|
|
! Sin^2 window has 50% overlap, kstep=nfft/2.
|
|
|
|
! Frequencies with strong signals are identified and separated. The back
|
|
! transforms are done separately for weak and strong signals, so that
|
|
! noise blanking can be applied to the weak-signal portion. Strong and
|
|
! weak are finally re-combined in the time domain.
|
|
|
|
parameter (MAXFFT=1024,MAXNH=MAXFFT/2)
|
|
parameter (MAXSIGS=100)
|
|
complex cx0(0:nfft-1),cx1(0:nfft-1)
|
|
complex cy0(0:nfft-1),cy1(0:nfft-1)
|
|
complex cx(0:MAXFFT-1),cxt(0:MAXFFT-1)
|
|
complex cy(0:MAXFFT-1),cyt(0:MAXFFT-1)
|
|
complex cxs(0:MAXFFT-1),covxs(0:MAXNH-1) !Strong X signals
|
|
complex cys(0:MAXFFT-1),covys(0:MAXNH-1) !Strong Y signals
|
|
complex cxw(0:MAXFFT-1),covxw(0:MAXNH-1) !Weak X signals
|
|
complex cyw(0:MAXFFT-1),covyw(0:MAXNH-1) !Weak Y signals
|
|
real*4 w(0:MAXFFT-1)
|
|
real*4 s(0:MAXFFT-1)
|
|
logical*1 lstrong(0:MAXFFT-1),lprev
|
|
integer ia(MAXSIGS),ib(MAXSIGS)
|
|
complex h,u,v
|
|
logical first
|
|
data first/.true./
|
|
data k0/99999999/
|
|
save
|
|
|
|
if(faclim+iqadjust.eq.-9999.0) iqadjust=0 !Silence compiler warning.
|
|
if(first) then
|
|
pi=4.0*atan(1.0)
|
|
do i=0,nfft-1
|
|
w(i)=(sin(i*pi/nfft))**2
|
|
enddo
|
|
s=0.
|
|
nh=nfft/2
|
|
kstep=nfft
|
|
if(nwindow.eq.2) kstep=nh
|
|
fac=1.0/nfft
|
|
slimit=1.e30
|
|
first=.false.
|
|
endif
|
|
|
|
if(k.lt.k0) then
|
|
covxs=0.
|
|
covxw=0.
|
|
covys=0.
|
|
covyw=0.
|
|
endif
|
|
k0=k
|
|
|
|
cx(0:nfft-1)=cx0
|
|
if(nwindow.eq.2) cx(0:nfft-1)=w(0:nfft-1)*cx(0:nfft-1)
|
|
call four2a(cx,nfft,1,1,1) !First forward FFT (X)
|
|
|
|
if(nxpol.ne.0) then
|
|
cy(0:nfft-1)=cy0
|
|
if(nwindow.eq.2) cy(0:nfft-1)=w(0:nfft-1)*cy(0:nfft-1)
|
|
call four2a(cy,nfft,1,1,1) !First forward FFT (Y)
|
|
endif
|
|
|
|
if(iqapply.ne.0) then !Apply I/Q corrections (X)
|
|
h=gainx*cmplx(cos(phasex),sin(phasex))
|
|
v=0.
|
|
do i=0,nfft-1
|
|
u=cx(i)
|
|
if(i.gt.0) v=cx(nfft-i)
|
|
x=real(u) + real(v) - (aimag(u) + aimag(v))*aimag(h) + &
|
|
(real(u) - real(v))*real(h)
|
|
y=aimag(u) - aimag(v) + (aimag(u) + aimag(v))*real(h) + &
|
|
(real(u) - real(v))*aimag(h)
|
|
cxt(i)=0.5*cmplx(x,y)
|
|
enddo
|
|
else
|
|
cxt(0:nfft-1)=cx(0:nfft-1)
|
|
endif
|
|
|
|
if(nxpol.ne.0) then
|
|
if(iqapply.ne.0) then !Apply I/Q corrections (Y)
|
|
h=gainy*cmplx(cos(phasey),sin(phasey))
|
|
v=0.
|
|
do i=0,nfft-1
|
|
u=cy(i)
|
|
if(i.gt.0) v=cy(nfft-i)
|
|
x=real(u) + real(v) - (aimag(u) + aimag(v))*aimag(h) + &
|
|
(real(u) - real(v))*real(h)
|
|
y=aimag(u) - aimag(v) + (aimag(u) + aimag(v))*real(h) + &
|
|
(real(u) - real(v))*aimag(h)
|
|
cyt(i)=0.5*cmplx(x,y)
|
|
enddo
|
|
else
|
|
cyt(0:nfft-1)=cy(0:nfft-1)
|
|
endif
|
|
endif
|
|
|
|
! Identify frequencies with strong signals, copy frequency-domain
|
|
! data into array cs (strong) or cw (weak).
|
|
|
|
do i=0,nfft-1
|
|
p=real(cxt(i))**2 + aimag(cxt(i))**2
|
|
if(nxpol.ne.0) p=p + real(cyt(i))**2 + aimag(cyt(i))**2
|
|
s(i)=p
|
|
enddo
|
|
ave=sum(s(0:nfft-1))/nfft
|
|
lstrong(0:nfft-1)=s(0:nfft-1).gt.10.0*ave
|
|
|
|
nsigs=0
|
|
lprev=.false.
|
|
iwid=1
|
|
ib=-99
|
|
do i=0,nfft-1
|
|
if(lstrong(i) .and. (.not.lprev)) then
|
|
if(nsigs.lt.MAXSIGS) nsigs=nsigs+1
|
|
ia(nsigs)=i-iwid
|
|
if(ia(nsigs).lt.0) ia(nsigs)=0
|
|
endif
|
|
if(.not.lstrong(i) .and. lprev) then
|
|
ib(nsigs)=i-1+iwid
|
|
if(ib(nsigs).gt.nfft-1) ib(nsigs)=nfft-1
|
|
endif
|
|
lprev=lstrong(i)
|
|
enddo
|
|
|
|
if(nsigs.gt.0) then
|
|
do i=1,nsigs
|
|
ja=ia(i)
|
|
jb=ib(i)
|
|
if(ja.lt.0 .or. ja.gt.nfft-1 .or. jb.lt.0 .or. jb.gt.nfft-1) then
|
|
cycle
|
|
endif
|
|
if(jb.eq.-99) jb=ja + min(2*iwid,nfft-1)
|
|
lstrong(ja:jb)=.true.
|
|
enddo
|
|
endif
|
|
|
|
do i=0,nfft-1
|
|
if(lstrong(i)) then
|
|
cxs(i)=fac*cxt(i)
|
|
cxw(i)=0.
|
|
if(nxpol.ne.0) then
|
|
cys(i)=fac*cyt(i)
|
|
cyw(i)=0.
|
|
endif
|
|
else
|
|
cxw(i)=fac*cxt(i)
|
|
cxs(i)=0.
|
|
if(nxpol.ne.0) then
|
|
cyw(i)=fac*cyt(i)
|
|
cys(i)=0.
|
|
endif
|
|
endif
|
|
enddo
|
|
|
|
call four2a(cxw,nfft,1,-1,1) !Transform weak and strong X
|
|
call four2a(cxs,nfft,1,-1,1) !back to time domain, separately
|
|
|
|
if(nxpol.ne.0) then
|
|
call four2a(cyw,nfft,1,-1,1) !Transform weak and strong Y
|
|
call four2a(cys,nfft,1,-1,1) !back to time domain, separately
|
|
endif
|
|
|
|
if(nwindow.eq.2) then
|
|
cxw(0:nh-1)=cxw(0:nh-1)+covxw(0:nh-1) !Add previous segment's 2nd half
|
|
covxw(0:nh-1)=cxw(nh:nfft-1) !Save 2nd half
|
|
cxs(0:nh-1)=cxs(0:nh-1)+covxs(0:nh-1) !Ditto for strong signals
|
|
covxs(0:nh-1)=cxs(nh:nfft-1)
|
|
|
|
if(nxpol.ne.0) then
|
|
cyw(0:nh-1)=cyw(0:nh-1)+covyw(0:nh-1) !Add previous segment's 2nd half
|
|
covyw(0:nh-1)=cyw(nh:nfft-1) !Save 2nd half
|
|
cys(0:nh-1)=cys(0:nh-1)+covys(0:nh-1) !Ditto for strong signals
|
|
covys(0:nh-1)=cys(nh:nfft-1)
|
|
endif
|
|
endif
|
|
|
|
! Apply noise blanking to weak data
|
|
if(nb.ne.0) then
|
|
do i=0,kstep-1
|
|
peak=abs(cxw(i))
|
|
if(nxpol.ne.0) peak=max(peak,abs(cyw(i)))
|
|
if(peak.gt.peaklimit) then
|
|
cxw(i)=0.
|
|
if(nxpol.ne.0) cyw(i)=0.
|
|
nzap=nzap+1
|
|
endif
|
|
enddo
|
|
endif
|
|
|
|
! Compute power levels from weak data only
|
|
do i=0,kstep-1
|
|
px=px + real(cxw(i))**2 + aimag(cxw(i))**2
|
|
if(nxpol.ne.0) py=py + real(cyw(i))**2 + aimag(cyw(i))**2
|
|
enddo
|
|
|
|
cx1(0:kstep-1)=cxw(0:kstep-1) + cxs(0:kstep-1) !Weak + strong (X)
|
|
if(nxpol.ne.0) then
|
|
cy1(0:kstep-1)=cyw(0:kstep-1) + cys(0:kstep-1) !Weak + strong (Y)
|
|
endif
|
|
|
|
return
|
|
end subroutine timf2
|