Functional 'Solve for calibration parameters' on Tools menu.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8127 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2017-09-28 01:35:09 +00:00
parent 58f11f9f22
commit 093a2834c3
5 changed files with 145 additions and 36 deletions

View File

@ -425,6 +425,7 @@ set (wsjt_FSRCS
lib/fil4.f90
lib/fil6521.f90
lib/filbig.f90
lib/fitcal.f90
lib/fix_contest_msg.f90
lib/flat1.f90
lib/flat1a.f90

View File

@ -1,31 +1,95 @@
subroutine calibrate(app_dir,data_dir)
subroutine calibrate(data_dir,iz,a,b,rms,sigmaa,sigmab,irc)
! Frequency calibration driver routine for WSJT-X
character*(*) app_dir
! Average groups of frequency-calibration measurements, then fit a
! straight line for slope and intercept.
parameter (NZ=1000)
implicit real*8 (a-h,o-z)
character*(*) data_dir
character*256 fmtave,fcal,infile,avefile,calfile
character*512 cmnd
fmtave=app_dir//'fmtave'
fcal=app_dir//'fcal'
infile=data_dir//'fmt.all'
avefile=data_dir//'fmtave.out '
calfile=data_dir//'fcal.out'
character*256 infile,outfile
character*8 cutc,cutc1
character*1 c1
real*8 fd(NZ),deltaf(NZ),r(NZ),rmsd(NZ)
integer nn(NZ)
print*,trim(fmtave)
print*,trim(fcal)
print*,trim(infile)
print*,trim(avefile)
print*,trim(calfile)
infile=trim(data_dir)//'fmt.all'
outfile=trim(data_dir)//'fcal2.out'
cmnd='"'//trim(fmtave)//' '//trim(infile)//' > '//avefile//'"'
print*,trim(cmnd)
call system(trim(cmnd))
open(10,file=trim(infile),status='old',err=996)
open(12,file=trim(outfile),status='unknown',err=997)
nkhz0=0
sum=0.d0
sumsq=0.d0
n=0
j=0
do i=1,99999
read(10,*,end=10) cutc,nkHz,ncal,noffset,faudio,df,dblevel,snr
if((nkHz.ne.nkHz0) .and. i.ne.1) then
ave=sum/n
rms=0.d0
if(n.gt.1) then
rms=sqrt(abs(sumsq - sum*sum/n)/(n-1.d0))
endif
fMHz=0.001d0*nkHz0
j=j+1
fd(j)=fMHz
deltaf(j)=ave
r(j)=0.d0
rmsd(j)=rms
nn(j)=n
sum=0.d0
sumsq=0.d0
n=0
endif
dial_error=faudio-noffset
sum=sum + dial_error
sumsq=sumsq + dial_error**2
n=n+1
if(n.eq.1) then
cutc1=cutc
ncal0=ncal
endif
nkHz0=nkHz
enddo
10 ave=sum/n
rms=0.d0
if(n.gt.0) then
rms=sqrt((sumsq - sum*sum/n)/(n-1.d0))
endif
fMHz=0.001d0*nkHz
j=j+1
fd(j)=fMHz
deltaf(j)=ave
r(j)=0.d0
rmsd(j)=rms
nn(j)=n
iz=j
if(iz.lt.2) go to 998
call fitcal(fd,deltaf,r,iz,a,b,sigmaa,sigmab,rms)
write(12,1002)
1002 format(' Freq DF Meas Freq N rms Resid'/ &
' (MHz) (Hz) (MHz) (Hz) (Hz)'/ &
'----------------------------------------------------')
irc=0
do i=1,iz
fm=fd(i) + 1.d-6*deltaf(i)
c1=' '
if(rmsd(i).gt.1.0d0) c1='*'
write(12,1012) fd(i),deltaf(i),fm,nn(i),rmsd(i),r(i),c1
1012 format(f8.3,f9.3,f14.9,i4,f7.2,f9.3,1x,a1)
enddo
go to 999
996 irc=-1; go to 999
997 irc=-2; go to 999
998 irc=-3
999 continue
close(10)
close(12)
cmnd='"'//trim(fcal)//' '//trim(avefile)//' > '//calfile//'"'
print*,trim(cmnd)
call system(trim(cmnd))
return
end subroutine calibrate

34
lib/fitcal.f90 Normal file
View File

@ -0,0 +1,34 @@
subroutine fitcal(x,y,r,iz,a,b,sigmaa,sigmab,rms)
implicit real*8 (a-h,o-z)
real*8 x(iz),y(iz),r(iz)
sx=0.d0
sy=0.d0
sxy=0.d0
sx2=0.d0
do i=1,iz
sx=sx + x(i)
sy=sy + y(i)
sxy=sxy + x(i)*y(i)
sx2=sx2 + x(i)*x(i)
enddo
delta=iz*sx2 - sx*sx
a=(sx2*sy - sx*sxy)/delta
b=(iz*sxy - sx*sy)/delta
sq=0.d0
do i=1,iz
r(i)=y(i) - (a + b*x(i))
sq=sq + r(i)**2
enddo
rms=0.
sigmaa=0.
sigmab=0.
if(iz.ge.3) then
rms=sqrt(sq/(iz-2))
sigmaa=sqrt(rms*rms*sx2/delta)
sigmab=sqrt(iz*rms*rms/delta)
endif
return
end subroutine fitcal

View File

@ -132,7 +132,8 @@ extern "C" {
void fix_contest_msg_(char* MyGrid, char* msg, int len1, int len2);
void calibrate_(char exe_dir[],char data_dir[], int len1, int len2);
void calibrate_(char data_dir[], int* iz, double* a, double* b, double* rms,
double* sigmaa, double* sigmab, int* irc, int len1);
}
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
@ -2121,16 +2122,23 @@ void MainWindow::on_actionFast_Graph_triggered()
void MainWindow::on_actionSolve_FreqCal_triggered()
{
QString apath{QDir::toNativeSeparators(m_appDir) + "\\"};
char app_dir[512];
int len1=apath.length();
strncpy(app_dir,apath.toLatin1(),len1);
QString dpath{QDir::toNativeSeparators(m_config.writeable_data_dir().absolutePath()) + "\\"};
QString dpath{QDir::toNativeSeparators(m_config.writeable_data_dir().absolutePath()+"/")};
char data_dir[512];
int len2=dpath.length();
strncpy(data_dir,dpath.toLatin1(),len2);
qDebug() << "AA" << len1 << len2 << dpath;
calibrate_(app_dir,data_dir,len1,len2);
int len=dpath.length();
int iz,irc;
double a,b,rms,sigmaa,sigmab;
strncpy(data_dir,dpath.toLatin1(),len);
calibrate_(data_dir,&iz,&a,&b,&rms,&sigmaa,&sigmab,&irc,len);
QString t1;
t1.sprintf("Slope: %8.4f ±%7.4f ppm\nIntercept: %7.2f ±%5.2f Hz\n\nStdDev: %8.3f Hz",
b,sigmab,a,sigmaa,rms);
QString t2{"Solution looks good."};
if(irc<0) t1="";
if(irc==-1) t2="Cannot open " + dpath + "fmt.all";
if(irc==-2) t2="Cannot open " + dpath + "fcal2.out";
if(irc==-3) t2="Insufficient data in fmt.all";
if(irc>0 or rms>1.0) t2="Check fmt.all for possible bad data.";
MessageBox::information_message(this,t1,t2,0);
}
// This allows the window to shrink by removing certain things

View File

@ -66,7 +66,8 @@ SOURCES += \
main.cpp decodedtext.cpp wsprnet.cpp messageaveraging.cpp \
echoplot.cpp echograph.cpp fastgraph.cpp fastplot.cpp Modes.cpp \
WSPRBandHopping.cpp MessageAggregator.cpp SampleDownloader.cpp qt_helpers.cpp\
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp \
EqualizationToolsDialog.cpp
HEADERS += qt_helpers.hpp \
pimpl_h.hpp pimpl_impl.hpp \
@ -82,7 +83,8 @@ HEADERS += qt_helpers.hpp \
logbook/logbook.h logbook/countrydat.h logbook/countriesworked.h logbook/adif.h \
messageaveraging.h echoplot.h echograph.h fastgraph.h fastplot.h Modes.hpp WSPRBandHopping.hpp \
WsprTxScheduler.h SampleDownloader.hpp MultiSettings.hpp PhaseEqualizationDialog.hpp \
IARURegions.hpp MessageBox.hpp
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp
INCLUDEPATH += qmake_only