From 093a2834c337319856d32731936c7b067955df70 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Thu, 28 Sep 2017 01:35:09 +0000 Subject: [PATCH] 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 --- CMakeLists.txt | 1 + lib/calibrate.f90 | 112 ++++++++++++++++++++++++++++++++++++---------- lib/fitcal.f90 | 34 ++++++++++++++ mainwindow.cpp | 28 +++++++----- wsjtx.pro | 6 ++- 5 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 lib/fitcal.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index fa914b889..d5e64f89d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/lib/calibrate.f90 b/lib/calibrate.f90 index 0ecef3805..199beba1f 100644 --- a/lib/calibrate.f90 +++ b/lib/calibrate.f90 @@ -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 diff --git a/lib/fitcal.f90 b/lib/fitcal.f90 new file mode 100644 index 000000000..f85ccf457 --- /dev/null +++ b/lib/fitcal.f90 @@ -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 diff --git a/mainwindow.cpp b/mainwindow.cpp index bc14a953e..e4c45d5f3 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -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 diff --git a/wsjtx.pro b/wsjtx.pro index d552336f3..1a327c919 100644 --- a/wsjtx.pro +++ b/wsjtx.pro @@ -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