Tidy up command line processing in Fortran tools

Build script now  builds jt65. The tools jt65 and  jt65sim usilize the
options module for all comamnd line parsing.

The  tool  jt65sim  now  has  conventinal  command  line  options  and
switchs. Default values have been  added where appropriate and options
documentation  updated. An  option to  disable PRNG  seeding has  been
added.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6276 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2015-12-15 15:35:04 +00:00
parent eedb6d3458
commit 5f9ed5a5ac
4 changed files with 148 additions and 80 deletions

View File

@ -937,6 +937,9 @@ add_executable (wsprsim ${wsprsim_CSRCS})
add_executable (jt4code lib/jt4code.f90 wsjtx.rc) add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
target_link_libraries (jt4code wsjt_fort wsjt_cxx) target_link_libraries (jt4code wsjt_fort wsjt_cxx)
add_executable (jt65 lib/jt65.f90 ${jt65_CXXSRCS} wsjtx.rc)
target_link_libraries (jt65 wsjt_fort wsjt_cxx ${FFTW3_LIBRARIES})
add_executable (jt9 lib/jt9.f90 lib/jt9a.f90 lib/jt9b.f90 lib/jt9c.f90 ${jt9_CXXSRCS} wsjtx.rc) add_executable (jt9 lib/jt9.f90 lib/jt9a.f90 lib/jt9b.f90 lib/jt9c.f90 ${jt9_CXXSRCS} wsjtx.rc)
if (${OPENMP_FOUND} OR APPLE) if (${OPENMP_FOUND} OR APPLE)
if (APPLE) if (APPLE)

View File

@ -4,7 +4,7 @@ program jt65
use options use options
character c character c
logical :: display_help=.false.,err logical :: display_help=.false.
parameter (NZMAX=60*12000) parameter (NZMAX=60*12000)
integer*4 ihdr(11) integer*4 ihdr(11)
integer*2 id2(NZMAX) integer*2 id2(NZMAX)
@ -14,11 +14,11 @@ logical :: display_help=.false.,err
common/tracer/limtrace,lu common/tracer/limtrace,lu
equivalence (lenfile,ihdr(2)) equivalence (lenfile,ihdr(2))
type (option) :: long_options(5) = [ & type (option) :: long_options(5) = [ &
option ('freq',.true.,'n','default=1270',''), & option ('freq',.true.,'f','signal frequency, default FREQ=1270','FREQ'), &
option ('help',.false.,'h','Display this help message',''), & option ('help',.false.,'h','Display this help message',''), &
option ('ntrials',.true.,'n','default=1000',''), & option ('ntrials',.true.,'n','number of trials, default TRIALS=10000','TRIALS'), &
option ('robust sync',.false.,'n','default: disabled',''), & option ('robust-sync',.false.,'r','robust sync',''), &
option ('single-signal mode',.false.,'s','default: disabled','') ] option ('single-signal-mode',.false.,'s','decode at signal frequency only','') ]
limtrace=0 limtrace=0
lu=12 lu=12
@ -33,7 +33,7 @@ n2pass=2
nrobust=0 nrobust=0
do do
call getopt('f:hn:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,err) call getopt('f:hn:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
if( nstat .ne. 0 ) then if( nstat .ne. 0 ) then
exit exit
end if end if
@ -53,11 +53,17 @@ nrobust=0
end select end select
end do end do
nargs=iargc() if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then
if(display_help .or. (nargs.lt.1)) then print *, ''
print*,'Usage: jt65 [-f freq] [-n ntrials] [-s] file1 [file2 ...]' print *, 'Usage: jt65 [OPTIONS] file1 [file2 ...]'
print*,' -r robust sync' print *, ''
print*,' -s single-signal mode' print *, ' JT65 decode pre-recorded .WAV file(s)'
print *, ''
print *, 'OPTIONS:'
print *, ''
do i = 1, size (long_options)
call long_options(i) % print (6)
end do
go to 999 go to 999
endif endif
@ -65,12 +71,12 @@ nrobust=0
call timer('jt65 ',0) call timer('jt65 ',0)
ndecoded=0 ndecoded=0
do ifile=1,nargs do ifile=noffset+1,noffset+nremain
newdat=1 newdat=1
nfa=nlow nfa=nlow
nfb=nhigh nfb=nhigh
call getarg(ifile+noffset,infile) call get_command_argument(ifile,optarg,narglen)
if( infile.eq.'' ) goto 900 infile=optarg(:narglen)
open(10,file=infile,access='stream',status='old',err=998) open(10,file=infile,access='stream',status='old',err=998)
call timer('read ',0) call timer('read ',0)
read(10) ihdr read(10) ihdr
@ -93,7 +99,7 @@ nrobust=0
call timer('jt65a ',1) call timer('jt65a ',1)
enddo enddo
900 call timer('jt65 ',1) call timer('jt65 ',1)
call timer('jt65 ',101) call timer('jt65 ',101)
! call four2a(a,-1,1,1,1) !Free the memory used for plans ! call four2a(a,-1,1,1,1) !Free the memory used for plans
! call filbig(a,-1,1,0.0,0,0,0,0,0) ! (ditto) ! call filbig(a,-1,1,0.0,0,0,0,0,0) ! (ditto)

View File

@ -4,6 +4,7 @@ program jt65sim
use wavhdr use wavhdr
use packjt use packjt
use options
parameter (NMAX=54*12000) ! = 648,000 parameter (NMAX=54*12000) ! = 648,000
parameter (NFFT=10*65536,NH=NFFT/2) parameter (NFFT=10*65536,NH=NFFT/2)
type(hdr) h !Header for .wav file type(hdr) h !Header for .wav file
@ -17,7 +18,19 @@ program jt65sim
complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading
complex z complex z
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq,sps real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq,sps
character msg*22,arg*8,fname*11,csubmode*1,call1*5,call2*5 character msg*22,fname*11,csubmode*1,call1*5,call2*5,c,optarg*500,numbuf*32
logical :: display_help=.false.,seed_prngs=.true.
type (option) :: long_options(8) = [ &
option ('help',.false.,'h','Display this help message',''), &
option ('sub-mode',.true.,'m','sub mode, default MODE=A','MODE'), &
option ('num-sigs',.true.,'n','number of signals per file, default SIGNALS=10','SIGNALS'), &
option ('doppler-spread',.true.,'d','Doppler spread, default SPREAD=0.0','SPREAD'), &
option ('time-offset',.true., &
't','Time delta, use \ to escape -ve values, default SECONDS=0.0','SECONDS'), &
option ('num-files',.true.,'f','Number of files to generate, default FILES=1','FILES'), &
option ('no-prng-seed',.false.,'p','Do not seed PRNGs (use for reproducible tests)',''), &
option ('strength',.true.,'s', &
'S/N in dB (2500Hz reference b/w), use 0 for a range, use \ to escape -ve values, default SNR=0','SNR') ]
integer nprc(126) !Sync pattern integer nprc(126) !Sync pattern
data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, & data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, & 0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
@ -27,32 +40,75 @@ program jt65sim
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, & 0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
1,1,1,1,1,1/ 1,1,1,1,1,1/
nargs=iargc() csubmode='A'
if(nargs.ne.6) then mode65=1
print*,'Usage: jt65sim mode nsigs fspread SNR DT nfiles' nsigs=10
print*,'Example: jt65sim A 10 0.2 -24.5 0.0 1' fspread=0.
print*,'Enter SNR = 0 to generate a range of SNRs.' xdt=0.
snrdb=0.
nfiles=1
do
call getopt('hm:n:d:t:f:ps:',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
if( nstat .ne. 0 ) then
exit
end if
select case (c)
case ('h')
display_help = .true.
case ('m')
read (optarg(:narglen), *) csubmode
if(csubmode.eq.'A') mode65=1
if(csubmode.eq.'B') mode65=2
if(csubmode.eq.'C') mode65=4
case ('n')
read (optarg(:narglen), *,err=10) nsigs
case ('d')
read (optarg(:narglen), *,err=10) fspread
case ('t')
read (optarg(:narglen), *) numbuf
if (numbuf(1:1) == '\') then
read (numbuf(2:), *,err=10) xdt
else
read (numbuf, *,err=10) xdt
end if
case ('f')
read (optarg(:narglen), *,err=10) nfiles
case ('p')
seed_prngs=.false.
case ('s')
read (optarg(:narglen), *) numbuf
if (numbuf(1:1) == '\') then
read (numbuf(2:), *,err=10) snrdb
else
read (numbuf, *,err=10) snrdb
end if
end select
cycle
10 display_help=.true.
print *, 'Optional argument format error for option -', c
end do
if(display_help .or. nstat.lt.0 .or. nremain.ge.1) then
print *, ''
print *, 'Usage: jt65sim [OPTIONS]'
print *, ''
print *, ' Generate one or more simulated JT65 signals in .WAV file(s)'
print *, ''
print *, 'Example: jt65sim -m B -n 10 -d 0.2 -s \-24.5 -t 0.0 -f 4'
print *, ''
print *, 'OPTIONS:'
print *, ''
do i = 1, size (long_options)
call long_options(i) % print (6)
end do
go to 999 go to 999
endif endif
call init_random_seed() ! seed Fortran RANDOM_NUMBER generator if (seed_prngs) then
call sgran() ! see C rand generator (used in gran) call init_random_seed() ! seed Fortran RANDOM_NUMBER generator
call sgran() ! see C rand generator (used in gran)
csubmode='A' end if
call getarg(1,csubmode)
mode65=1
if(csubmode.eq.'B') mode65=2
if(csubmode.eq.'C') mode65=4
call getarg(2,arg)
read(arg,*) nsigs !Number of signals in each file
call getarg(3,arg)
read(arg,*) fspread !Doppler spread (Hz)
call getarg(4,arg)
read(arg,*) snrdb !S/N in dB (2500 hz reference BW)
call getarg(5,arg)
read(arg,*) xdt !Generated DT
call getarg(6,arg)
read(arg,*) nfiles !Number of files
rms=100. rms=100.
fsample=12000.d0 !Sample rate (Hz) fsample=12000.d0 !Sample rate (Hz)

View File

@ -18,36 +18,39 @@ program jt9
character wisfile*80 character wisfile*80
integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, & integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, &
fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=60001 fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=60001
logical :: shmem = .false., read_files = .false., have_args = .false., & logical :: shmem = .false., read_files = .false., &
tx9 = .false., display_help = .false. tx9 = .false., display_help = .false.
type (option) :: long_options(17) = [ & type (option) :: long_options(17) = [ &
option ('help', .false., 'h', 'Display this help message', ''), & option ('help', .false., 'h', 'Display this help message', ''), &
option ('shmem',.true.,'s','Use shared memory for sample data','<key>'), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), &
option ('tr-period', .true., 'p', 'Tx/Rx period, default=1', '<minutes>'), & option ('tr-period', .true., 'p', 'Tx/Rx period, default MINUTES=1', &
option ('executable-path', .true., 'e', & 'MINUTES'), &
'Location of subordinate executables (KVASD) default="."', '<path>'), & option ('executable-path', .true., 'e', &
option ('data-path', .true., 'a', & 'Location of subordinate executables (KVASD) default PATH="."', &
'Location of writeable data files, default="."', '<path>'), & 'PATH'), &
option ('temp-path', .true., 't', 'Temporary files path, default="."', & option ('data-path', .true., 'a', &
'<path>'), & 'Location of writeable data files, default PATH="."', 'PATH'), &
option ('lowest', .true., 'L', & option ('temp-path', .true., 't', &
'Lowest frequency decoded (JT65), default=200Hz', '<hertz>'), & 'Temporary files path, default PATH="."', 'PATH'), &
option ('highest', .true., 'H', & option ('lowest', .true., 'L', &
'Highest frequency decoded, default=4007Hz', '<hertz>'), & 'Lowest frequency decoded (JT65), default HERTZ=200', 'HERTZ'), &
option ('split', .true., 'S', & option ('highest', .true., 'H', &
'Lowest JT9 frequency decoded, default=2700Hz', '<hertz>'), & 'Highest frequency decoded, default HERTZ=4007', 'HERTZ'), &
option ('rx-frequency', .true., 'f', & option ('split', .true., 'S', &
'Receive frequency offset, default=1500', '<hertz>'), & 'Lowest JT9 frequency decoded, default HERTZ=2700', 'HERTZ'), &
option ('patience', .true., 'w', & option ('rx-frequency', .true., 'f', &
'FFTW3 planing patience (0-4), default=1', '<patience>'), & 'Receive frequency offset, default HERTZ=1500', 'HERTZ'), &
option ('fft-threads', .true., 'm', & option ('patience', .true., 'w', &
'Number of threads to process large FFTs, default=1', '<number>'), & 'FFTW3 planing patience (0-4), default PATIENCE=1', 'PATIENCE'), &
option ('jt65', .false., '6', 'JT65 mode', ''), & option ('fft-threads', .true., 'm', &
option ('jt9', .false., '9', 'JT9 mode', ''), & 'Number of threads to process large FFTs, default THREADS=1', &
option ('jt4', .false., '4', 'JT4 mode', ''), & 'THREADS'), &
option ('depth', .true., 'd', 'JT9 decoding depth (1-3), default=1', & option ('jt65', .false., '6', 'JT65 mode', ''), &
'<number>'), & option ('jt9', .false., '9', 'JT9 mode', ''), &
option ('tx-jt9', .false., 'T', 'Tx mode is JT9, default=JT65', '') ] option ('jt4', .false., '4', 'JT4 mode', ''), &
option ('depth', .true., 'd', &
'JT9 decoding depth (1-3), default DEPTH=1', 'DEPTH'), &
option ('tx-jt9', .false., 'T', 'Tx mode is JT9', '') ]
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6 character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, & common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
@ -63,11 +66,10 @@ program jt9
do do
call getopt('hs:e:a:r:m:p:d:f:w:t:964TL:S:H:',long_options,c, & call getopt('hs:e:a:r:m:p:d:f:w:t:964TL:S:H:',long_options,c, &
optarg,arglen,stat,offset,remain) optarg,arglen,stat,offset,remain,.true.)
if (stat .ne. 0) then if (stat .ne. 0) then
exit exit
end if end if
have_args = .true.
select case (c) select case (c)
case ('h') case ('h')
display_help = .true. display_help = .true.
@ -117,19 +119,20 @@ program jt9
end select end select
end do end do
if (display_help .or. .not. have_args .or. & if (display_help .or. stat .lt. 0 &
(stat .lt. 0 .or. (shmem .and. remain .gt. 0) & .or. (shmem .and. remain .gt. 0) &
.or. (read_files .and. remain .eq. 0) .or. & .or. (read_files .and. remain .lt. 1) &
(shmem .and. read_files))) then .or. (shmem .and. read_files)) then
print*,'Usage: jt9 -p <per> OPTIONS file1 [file2 ...]'
print*,' Reads data from *.wav files.'
print*,''
print*,' jt9 -s <key> [-w n] [-m n] [-e path] [-a path] [-t path]'
print*,' Gets data from shared memory region with key==<key>'
print *, 'Usage: jt9 [OPTIONS] file1 [file2 ...]'
print *, ' Reads data from *.wav files.'
print *, ''
print *, ' jt9 -s <key> [-w patience] [-m threads] [-e path] [-a path] [-t path]'
print *, ' Gets data from shared memory region with key==<key>'
print *, ''
print *, 'OPTIONS:'
print *, ''
do i = 1, size (long_options) do i = 1, size (long_options)
print*,''
call long_options(i) % print (6) call long_options(i) % print (6)
end do end do
go to 999 go to 999