Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1095 changed files with 31298 additions and 367679 deletions
@@ -1,279 +0,0 @@
#include "astro.h"
#include <stdio.h>
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QSettings>
#include <QDateTime>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>
#include "commons.h"
#include "MessageBox.hpp"
#include "Configuration.hpp"
#include "SettingsGroup.hpp"
#include "qt_helpers.hpp"
#include "ui_astro.h"
#include "moc_astro.cpp"
extern "C" {
void astrosub_(int* nyear, int* month, int* nday, double* uth, double* freqMoon,
const char* mygrid, const char* hisgrid, double* azsun,
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
double* xnr, double* techo, double* width1, double* width2,
bool* bTx, const char* AzElFileName, const char* jpleph,
int len1, int len2, int len3, int len4);
}
Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent)
: QDialog {parent, Qt::WindowTitleHint}
, settings_ {settings}
, configuration_ {configuration}
, ui_ {new Ui::Astro}
, m_DopplerMethod {0}
{
ui_->setupUi (this);
setWindowTitle (QApplication::applicationName () + " - " + tr ("Astronomical Data"));
setStyleSheet ("QWidget {background: white;}");
connect (ui_->cbDopplerTracking, &QAbstractButton::toggled, ui_->doppler_widget, &QWidget::setVisible);
read_settings ();
ui_->text_label->clear ();
}
Astro::~Astro ()
{
ui_->cbDopplerTracking->setChecked (false);
Q_EMIT tracking_update ();
if (isVisible ()) write_settings ();
}
void Astro::closeEvent (QCloseEvent * e)
{
write_settings ();
QWidget::closeEvent (e);
}
void Astro::read_settings ()
{
SettingsGroup g (settings_, "Astro");
ui_->doppler_widget->setVisible (ui_->cbDopplerTracking->isChecked ());
m_DopplerMethod=settings_->value("DopplerMethod",0).toInt();
switch (m_DopplerMethod)
{
case 0: ui_->rbNoDoppler->setChecked (true); break;
case 1: ui_->rbFullTrack->setChecked (true); break;
case 2: ui_->rbConstFreqOnMoon->setChecked (true); break;
case 3: ui_->rbRxOnly->setChecked (true); break;
}
move (settings_->value ("window/pos", pos ()).toPoint ());
}
void Astro::write_settings ()
{
SettingsGroup g (settings_, "Astro");
//settings_->setValue ("DopplerTracking", ui_->cbDopplerTracking->isChecked ());
settings_->setValue ("DopplerMethod",m_DopplerMethod);
settings_->setValue ("window/pos", pos ());
}
auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const& hisgrid, Frequency freq,
bool dx_is_self, bool bTx, bool no_tx_QSY, int TR_period) -> Correction
{
Frequency freq_moon {freq};
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
double ramoon,decmoon,dgrd,poloffset,xnr,techo,width1,width2;
int ntsky;
QString date {t.date().toString("yyyy MMM dd").trimmed ()};
QString utc {t.time().toString().trimmed ()};
int nyear {t.date().year()};
int month {t.date().month()};
int nday {t.date().day()};
int nhr {t.time().hour()};
int nmin {t.time().minute()};
double sec {t.time().second() + 0.001*t.time().msec()};
double uth {nhr + nmin/60.0 + sec/3600.0};
if(freq_moon < 1) freq_moon = 144000000;
int nfreq {static_cast<int> (freq_moon / 1000000u)};
double freq8 {static_cast<double> (freq_moon)};
auto const& AzElFileName = QDir::toNativeSeparators (configuration_->azel_directory ().absoluteFilePath ("azel.dat"));
auto const& jpleph = configuration_->data_dir ().absoluteFilePath ("JPLEPH");
int ndop;
int ndop00;
QString mygrid_padded {(mygrid + " ").left (6)};
QString hisgrid_padded {(hisgrid + " ").left (6)};
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
AzElFileName.toLatin1().constData(), jpleph.toLatin1().constData(), 6, 6,
AzElFileName.length(), jpleph.length());
if(hisgrid_padded==" ") {
azmoondx=0.0;
elmoondx=0.0;
ndop=0;
width2=0.0;
}
QString message;
{
QTextStream out {&message};
out << " " << date << "\n"
"UTC: " << utc << "\n"
<< fixed
<< qSetFieldWidth (6)
<< qSetRealNumberPrecision (1)
<< "Az: " << azmoon << "\n"
"El: " << elmoon << "\n"
"SelfDop:" << ndop00 << "\n"
"Width: " << int(width1) << "\n"
<< qSetRealNumberPrecision (2)
<< "Delay: " << techo << "\n"
<< qSetRealNumberPrecision (1)
<< "DxAz: " << azmoondx << "\n"
"DxEl: " << elmoondx << "\n"
"DxDop: " << ndop << "\n"
"DxWid: " << int(width2) << "\n"
"Dec: " << decmoon << "\n"
"SunAz: " << azsun << "\n"
"SunEl: " << elsun << "\n"
"Freq: " << nfreq << "\n";
if(nfreq>=50) { //Suppress data not relevant below VHF
out << "Tsky: " << ntsky << "\n"
"Dpol: " << poloffset << "\n"
"MNR: " << xnr << "\n"
"Dgrd: " << dgrd;
}
}
ui_->text_label->setText(message);
Correction correction;
if (ui_->cbDopplerTracking->isChecked ()) {
switch (m_DopplerMethod)
{
case 1: // All Doppler correction done here; DX station stays at nominal dial frequency.
case 3: // Both stations do full correction on Rx and none on Tx
correction.rx = dx_is_self ? ndop00 : ndop;
break;
case 2:
// Doppler correction to constant frequency on Moon
correction.rx = ndop00 / 2;
break;
}
if (3 != m_DopplerMethod) correction.tx = -correction.rx;
if(dx_is_self && m_DopplerMethod == 1) correction.rx = 0;
if (no_tx_QSY && 3 != m_DopplerMethod && 0 != m_DopplerMethod)
{
// calculate a single correction for transmit half way through
// the period as a compromise for rigs that can't CAT QSY
// while transmitting
//
// use a base time of (secs-since-epoch + 2) so as to be sure
// we do the next period if we calculate just before it starts
auto sec_since_epoch = t.toMSecsSinceEpoch () / 1000 + 2;
auto target_sec = sec_since_epoch - sec_since_epoch % TR_period + TR_period / 2;
auto target_date_time = QDateTime::fromMSecsSinceEpoch (target_sec * 1000);
QString date {target_date_time.date().toString("yyyy MMM dd").trimmed ()};
QString utc {target_date_time.time().toString().trimmed ()};
int nyear {target_date_time.date().year()};
int month {target_date_time.date().month()};
int nday {target_date_time.date().day()};
int nhr {target_date_time.time().hour()};
int nmin {target_date_time.time().minute()};
double sec {target_date_time.time().second() + 0.001*target_date_time.time().msec()};
double uth {nhr + nmin/60.0 + sec/3600.0};
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
"", jpleph.toLatin1().constData(), 6, 6,
0, jpleph.length());
FrequencyDelta offset {0};
switch (m_DopplerMethod)
{
case 1:
// All Doppler correction done here; DX station stays at nominal dial frequency.
offset = dx_is_self ? ndop00 : ndop;
break;
case 2:
// Doppler correction to constant frequency on Moon
offset = ndop00 / 2;
break;
}
correction.tx = -offset;
}
}
return correction;
}
void Astro::check_split ()
{
if (doppler_tracking () && !configuration_->split_mode ())
{
MessageBox::warning_message (this, tr ("Doppler Tracking Error"),
tr ("Split operating is required for Doppler tracking"),
tr ("Go to \"Menu->File->Settings->Radio\" to enable split operation"));
ui_->rbNoDoppler->click ();
}
}
void Astro::on_rbFullTrack_clicked()
{
m_DopplerMethod = 1;
check_split ();
Q_EMIT tracking_update ();
}
void Astro::on_rbRxOnly_clicked()
{
m_DopplerMethod = 3;
check_split ();
Q_EMIT tracking_update ();
}
void Astro::on_rbConstFreqOnMoon_clicked()
{
m_DopplerMethod = 2;
check_split ();
Q_EMIT tracking_update ();
}
void Astro::on_rbNoDoppler_clicked()
{
m_DopplerMethod = 0;
Q_EMIT tracking_update ();
}
bool Astro::doppler_tracking () const
{
return ui_->cbDopplerTracking->isChecked () && m_DopplerMethod;
}
void Astro::on_cbDopplerTracking_toggled(bool)
{
check_split ();
Q_EMIT tracking_update ();
}
void Astro::nominal_frequency (Frequency rx, Frequency tx)
{
ui_->sked_frequency_label->setText (Radio::pretty_frequency_MHz_string (rx));
ui_->sked_tx_frequency_label->setText (Radio::pretty_frequency_MHz_string (tx));
}
void Astro::hideEvent (QHideEvent * e)
{
Q_EMIT tracking_update ();
QWidget::hideEvent (e);
}
@@ -1,154 +0,0 @@
subroutine refspectrum(id2,bclear,brefspec,buseref,fname)
! Input:
! id2 i*2 Raw 16-bit integer data, 12000 Hz sample rate
! brefspec logical True when accumulating a reference spectrum
parameter (NFFT=6912,NH=NFFT/2,NPOLYLOW=400,NPOLYHIGH=2600)
integer*2 id2(NFFT)
logical*1 bclear,brefspec,buseref,blastuse
real x0(0:NH-1) !Input samples
real x1(0:NH-1) !Output samples (delayed by one block)
real x0s(0:NH-1) !Saved upper half of input samples
real x1s(0:NH-1) !Saved upper half of output samples
real x(0:NFFT-1) !Work array
real*4 w(0:NFFT-1) !Window function
real*4 s(0:NH) !Average spectrum
real*4 fil(0:NH)
real*8 xfit(1500),yfit(1500),sigmay(1500),a(5),chisqr !Polyfit arrays
logical first
complex cx(0:NH) !Complex frequency-domain work array
character*(*) fname
common/spectra/syellow(6827),ref(0:NH),filter(0:NH)
equivalence(x,cx)
data first/.true./,blastuse/.false./
save
if(first) then
pi=4.0*atan(1.0)
do i=0,NFFT-1
ww=sin(i*pi/NFFT)
w(i)=ww*ww/NFFT
enddo
nsave=0
s=0.0
filter=1.0
x0s=0.
x1s=0.
first=.false.
endif
if(bclear) s=0.
if(brefspec) then
x(0:NH-1)=0.001*id2(1:NH)
x(NH:NFFT-1)=0.0
call four2a(x,NFFT,1,-1,0) !r2c FFT
do i=1,NH
s(i)=s(i) + real(cx(i))**2 + aimag(cx(i))**2
enddo
nsave=nsave+1
fac0=0.9
if(mod(nsave,4).eq.0) then
df=12000.0/NFFT
ia=nint(1000.0/df)
ib=nint(2000.0/df)
avemid=sum(s(ia:ib))/(ib-ia+1)
do i=0,NH
fil(i)=0.
if(s(i).gt.0.0) then
fil(i)=sqrt(avemid/s(i))
endif
enddo
! Default range is 240 - 4000 Hz. For narrower filters, use frequencies
! at which gain is -20 dB relative to 1500 Hz.
ia=nint(240.0/df)
ib=nint(4000.0/df)
i0=nint(1500.0/df)
do i=i0,ia,-1
if(s(i)/s(i0).lt.0.01) exit
enddo
ia=i
do i=i0,ib,1
if(s(i)/s(i0).lt.0.01) exit
enddo
ib=i
fac=fac0
do i=ia,1,-1
fac=fac*fac0
fil(i)=fac*fil(i)
enddo
fac=fac0
do i=ib,NH
fac=fac*fac0
fil(i)=fac*fil(i)
enddo
do iter=1,100 !### ??? ###
call smo121(fil,NH)
enddo
do i=0,NH
filter(i)=-60.0
if(s(i).gt.0.0) filter(i)=20.0*log10(fil(i))
enddo
il=nint(NPOLYLOW/df)
ih=nint(NPOLYHIGH/df)
nfit=ih-il+1
mode=0
nterms=5
do i=1,nfit
xfit(i)=((i+il-1)*df-1500.0)/1000.0
yfit(i)=fil(i+il-1)
sigmay(i)=1.0
enddo
call polyfit(xfit,yfit,sigmay,nfit,nterms,mode,a,chisqr)
open(16,file=fname,status='unknown')
write(16,1003) NPOLYLOW,NPOLYHIGH,nterms,a
1003 format(3i5,5e25.16)
do i=1,NH
freq=i*df
ref(i)=db(s(i)/avemid)
write(16,1005) freq,s(i),ref(i),fil(i),filter(i)
1005 format(f10.3,e12.3,f12.6,e12.3,f12.6)
enddo
close(16)
endif
return
endif
if(buseref) then
if(blastuse.neqv.buseref) then !just enabled so read filter
fil=1.0
open(16,file=fname,status='old',err=110)
read(16,1003,err=20,end=100) ndummy,ndummy,nterms,a
goto 30
20 rewind(16) !allow for old style refspec.dat with no header
30 do i=1,NH
read(16,1005,err=100,end=100) freq,s(i),ref(i),fil(i),filter(i)
enddo
100 close(16)
110 continue
endif
x0=id2(1:NH)
x(0:NH-1)=x0s !Previous 2nd half to new 1st half
x(NH:NFFT-1)=x0 !New 2nd half
x0s=x0 !Save the new 2nd half
x=w*x !Apply window
call four2a(x,NFFT,1,-1,0) !r2c FFT (to frequency domain)
cx=fil*cx
call four2a(cx,NFFT,1,1,-1) !c2r FFT (back to time domain)
x1=x1s + x(0:NH-1) !Add previous segment's 2nd half
id2(1:NH)=nint(x1)
x1s=x(NH:NFFT-1) !Save the new 2nd half
endif
blastuse=buseref
return
end subroutine refspectrum
@@ -0,0 +1,61 @@
#ifndef WSJTX_CONFIG_H__
#define WSJTX_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
#define WSJTX_VERSION_MAJOR @WSJTX_VERSION_MAJOR@
#define WSJTX_VERSION_MINOR @WSJTX_VERSION_MINOR@
#define WSJTX_VERSION_PATCH @WSJTX_VERSION_PATCH@
#cmakedefine CMAKE_INSTALL_DATAROOTDIR "@CMAKE_INSTALL_DATAROOTDIR@"
#cmakedefine CMAKE_INSTALL_DOCDIR "@CMAKE_INSTALL_DOCDIR@"
#cmakedefine CMAKE_INSTALL_DATADIR "@CMAKE_INSTALL_DATADIR@"
#cmakedefine CMAKE_PROJECT_NAME "@CMAKE_PROJECT_NAME@"
#cmakedefine PROJECT_MANUAL "@PROJECT_MANUAL@"
#cmakedefine PROJECT_HOMEPAGE "@PROJECT_HOMEPAGE@"
#cmakedefine PROJECT_MANUAL_DIRECTORY_URL "@PROJECT_MANUAL_DIRECTORY_URL@"
#cmakedefine PROJECT_SAMPLES_URL "@PROJECT_SAMPLES_URL@"
#cmakedefine PROJECT_SUMMARY_DESCRIPTION "@PROJECT_SUMMARY_DESCRIPTION@"
#cmakedefine01 WSJT_SHARED_RUNTIME
#cmakedefine01 WSJT_QDEBUG_TO_FILE
#cmakedefine01 WSJT_QDEBUG_IN_RELEASE
#cmakedefine01 WSJT_TRACE_CAT
#cmakedefine01 WSJT_TRACE_CAT_POLLS
#cmakedefine01 WSJT_HAMLIB_TRACE
#cmakedefine01 WSJT_HAMLIB_VERBOSE_TRACE
#cmakedefine01 WSJT_SOFT_KEYING
#cmakedefine01 WSJT_ENABLE_EXPERIMENTAL_FEATURES
#cmakedefine01 WSJT_RIG_NONE_CAN_SPLIT
#define WSJTX_STRINGIZE1(x) #x
#define WSJTX_STRINGIZE(x) WSJTX_STRINGIZE1(x)
/* consistent UNICODE behaviour */
#ifndef UNICODE
# undef _UNICODE
#else
# ifndef _UNICODE
# define _UNICODE
# endif
#endif
/* typedef for consistent gfortran ABI for charlen type hidden arguments */
#if __GNUC__ > 7
#ifdef __cplusplus
#include <cstddef>
#else
#include <stddef.h>
#endif
typedef size_t fortran_charlen_t;
#else
typedef int fortran_charlen_t;
#endif
#ifdef __cplusplus
}
#endif
#endif