Merged master 8748
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,92 @@
|
||||
subroutine afc65b(cx,npts,fsample,nflip,mode65,a,ccfbest,dtbest)
|
||||
|
||||
! Find delta f, f1, f2 ==> a(1:3)
|
||||
|
||||
complex cx(npts)
|
||||
real a(5),deltaa(5)
|
||||
|
||||
a=0.
|
||||
i2=8*mode65
|
||||
i1=-i2
|
||||
j2=8*mode65
|
||||
j1=-j2
|
||||
ccfmax=0.
|
||||
istep=2*mode65
|
||||
do iter=1,2
|
||||
do i=i1,i2,istep
|
||||
a(1)=i
|
||||
do j=j1,j2,istep
|
||||
a(2)=j
|
||||
chisq=fchisq65(cx,npts,fsample,nflip,a,ccf,dtmax)
|
||||
if(ccf.gt.ccfmax) then
|
||||
a1=a(1)
|
||||
a2=a(2)
|
||||
ccfmax=ccf
|
||||
endif
|
||||
! write(81,3081) istep,i1,i2,j1,j2,i,j,ccf,ccfmax,dtmax,a1,a2
|
||||
!3081 format(7i4,5f8.2)
|
||||
enddo
|
||||
enddo
|
||||
i1=a1-istep
|
||||
i2=a1+istep
|
||||
j1=a2-istep
|
||||
j2=a2+istep
|
||||
istep=1
|
||||
enddo
|
||||
|
||||
! a(1)=0.
|
||||
! a(2)=0.
|
||||
a(1)=a1
|
||||
a(2)=a2
|
||||
a(3)=0.
|
||||
a(4)=0.
|
||||
deltaa(1)=2.0*mode65
|
||||
deltaa(2)=2.0*mode65
|
||||
deltaa(3)=1.0
|
||||
nterms=2 !Maybe 2 is enough?
|
||||
|
||||
! Start the iteration
|
||||
chisqr=0.
|
||||
chisqr0=1.e6
|
||||
do iter=1,100 !How many iters is enough?
|
||||
do j=1,nterms
|
||||
chisq1=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
fn=0.
|
||||
delta=deltaa(j)
|
||||
10 a(j)=a(j)+delta
|
||||
chisq2=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
if(chisq2.eq.chisq1) go to 10
|
||||
if(chisq2.gt.chisq1) then
|
||||
delta=-delta !Reverse direction
|
||||
a(j)=a(j)+delta
|
||||
tmp=chisq1
|
||||
chisq1=chisq2
|
||||
chisq2=tmp
|
||||
endif
|
||||
20 fn=fn+1.0
|
||||
a(j)=a(j)+delta
|
||||
chisq3=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
if(chisq3.lt.chisq2) then
|
||||
chisq1=chisq2
|
||||
chisq2=chisq3
|
||||
go to 20
|
||||
endif
|
||||
|
||||
! Find minimum of parabola defined by last three points
|
||||
delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5)
|
||||
a(j)=a(j)-delta
|
||||
deltaa(j)=deltaa(j)*fn/3.
|
||||
! write(*,4000) iter,j,a(1:2),-chisq2
|
||||
!4000 format(2i2,4f9.4)
|
||||
enddo
|
||||
chisqr=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
fdiff=chisqr/chisqr0-1.0
|
||||
! write(*,4000) 0,0,a(1:2),-chisqr,fdiff
|
||||
if(abs(fdiff).lt.0.0001) exit
|
||||
chisqr0=chisqr
|
||||
enddo
|
||||
ccfbest=ccfmax * (1378.125/fsample)**2
|
||||
dtbest=dtmax
|
||||
|
||||
return
|
||||
end subroutine afc65b
|
||||
@@ -1,28 +0,0 @@
|
||||
subroutine fix_contest_msg(mycall,mygrid,hiscall,msg)
|
||||
|
||||
! If msg is "mycall hiscall grid1" and distance from mygrid to grid1 is more
|
||||
! thsn 10000 km, change "grid1" to "R grid2" where grid2 is the antipodes
|
||||
! of grid1.
|
||||
|
||||
character*6 mycall,mygrid,hiscall
|
||||
character*22 msg
|
||||
character*6 g1,g2
|
||||
logical isgrid
|
||||
|
||||
n=len(trim(msg))
|
||||
if(n.lt.4) return
|
||||
g1=msg(n-3:n)//' '
|
||||
if(isgrid(g1)) then
|
||||
call azdist(mygrid,g1,0.d0,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
|
||||
if(ndkm.gt.10000) then
|
||||
call grid2deg(g1,dlong,dlat)
|
||||
dlong=dlong+180.0
|
||||
if(dlong.gt.180.0) dlong=dlong-360.0
|
||||
dlat=-dlat
|
||||
call deg2grid(dlong,dlat,g2)
|
||||
msg=msg(1:n-4)//'R '//g2(1:4)
|
||||
endif
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine fix_contest_msg
|
||||
@@ -1,213 +0,0 @@
|
||||
#include "adif.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
|
||||
/*
|
||||
<CALL:4>W1XT<BAND:3>20m<FREQ:6>14.076<GRIDSQUARE:4>DM33<MODE:4>JT65<RST_RCVD:3>-21<RST_SENT:3>-14<QSO_DATE:8>20110422<TIME_ON:6>041712<TIME_OFF:6>042435<TX_PWR:1>4<COMMENT:34>1st JT65A QSO. Him: mag loop 20W<STATION_CALLSIGN:6>VK3ACF<MY_GRIDSQUARE:6>qf22lb<eor>
|
||||
<CALL:6>IK1SOW<BAND:3>20m<FREQ:6>14.076<GRIDSQUARE:4>JN35<MODE:4>JT65<RST_RCVD:3>-19<RST_SENT:3>-11<QSO_DATE:8>20110422<TIME_ON:6>052501<TIME_OFF:6>053359<TX_PWR:1>3<STATION_CALLSIGN:6>VK3ACF<MY_GRIDSQUARE:6>qf22lb<eor>
|
||||
<CALL:6:S>W4ABC> ...
|
||||
*/
|
||||
|
||||
void ADIF::init(QString const& filename)
|
||||
{
|
||||
_filename = filename;
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
|
||||
QString ADIF::_extractField(QString const& line, QString const& fieldName)
|
||||
{
|
||||
int fieldNameIndex = line.indexOf(fieldName,0,Qt::CaseInsensitive);
|
||||
if (fieldNameIndex >=0)
|
||||
{
|
||||
int closingBracketIndex = line.indexOf('>',fieldNameIndex);
|
||||
int fieldLengthIndex = line.indexOf(':',fieldNameIndex); // find the size delimiter
|
||||
int dataTypeIndex = -1;
|
||||
if (fieldLengthIndex >= 0)
|
||||
{
|
||||
dataTypeIndex = line.indexOf(':',fieldLengthIndex+1); // check for a second : indicating there is a data type
|
||||
if (dataTypeIndex > closingBracketIndex)
|
||||
dataTypeIndex = -1; // second : was found but it was beyond the closing >
|
||||
}
|
||||
|
||||
if ((closingBracketIndex > fieldNameIndex) && (fieldLengthIndex > fieldNameIndex) && (fieldLengthIndex< closingBracketIndex))
|
||||
{
|
||||
int fieldLengthCharCount = closingBracketIndex - fieldLengthIndex -1;
|
||||
if (dataTypeIndex >= 0)
|
||||
fieldLengthCharCount -= 2; // data type indicator is always a colon followed by a single character
|
||||
QString fieldLengthString = line.mid(fieldLengthIndex+1,fieldLengthCharCount);
|
||||
int fieldLength = fieldLengthString.toInt();
|
||||
if (fieldLength > 0)
|
||||
{
|
||||
QString field = line.mid(closingBracketIndex+1,fieldLength);
|
||||
return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ADIF::load()
|
||||
{
|
||||
_data.clear();
|
||||
QFile inputFile(_filename);
|
||||
if (inputFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&inputFile);
|
||||
while ( !in.atEnd() )
|
||||
{
|
||||
QString line = in.readLine();
|
||||
QSO q;
|
||||
q.call = _extractField(line,"CALL:");
|
||||
q.band = _extractField(line,"BAND:");
|
||||
q.mode = _extractField(line,"MODE:");
|
||||
q.date = _extractField(line,"QSO_DATE:");
|
||||
if (q.call != "")
|
||||
_data.insert(q.call,q);
|
||||
}
|
||||
inputFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ADIF::add(QString const& call, QString const& band, QString const& mode, QString const& date)
|
||||
{
|
||||
QSO q;
|
||||
q.call = call;
|
||||
q.band = band;
|
||||
q.mode = mode;
|
||||
q.date = date;
|
||||
_data.insert(q.call,q);
|
||||
//qDebug() << "Added as worked:" << call << band << mode << date;
|
||||
}
|
||||
|
||||
// return true if in the log same band and mode (where JT65 == JT9)
|
||||
bool ADIF::match(QString const& call, QString const& band, QString const& mode)
|
||||
{
|
||||
QList<QSO> qsos = _data.values(call);
|
||||
if (qsos.size()>0)
|
||||
{
|
||||
QSO q;
|
||||
foreach(q,qsos)
|
||||
{
|
||||
if ( (band.compare(q.band,Qt::CaseInsensitive) == 0)
|
||||
|| (band=="")
|
||||
|| (q.band==""))
|
||||
{
|
||||
if (
|
||||
(
|
||||
((mode.compare("JT65",Qt::CaseInsensitive)==0) ||
|
||||
(mode.compare("JT9",Qt::CaseInsensitive)==0) ||
|
||||
(mode.compare("FT8",Qt::CaseInsensitive)==0))
|
||||
&&
|
||||
((q.mode.compare("JT65",Qt::CaseInsensitive)==0) ||
|
||||
(q.mode.compare("JT9",Qt::CaseInsensitive)==0) ||
|
||||
(q.mode.compare("FT8",Qt::CaseInsensitive)==0))
|
||||
)
|
||||
|| (mode.compare(q.mode,Qt::CaseInsensitive)==0)
|
||||
|| (mode=="")
|
||||
|| (q.mode=="")
|
||||
)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QString> ADIF::getCallList()
|
||||
{
|
||||
QList<QString> p;
|
||||
QMultiHash<QString,QSO>::const_iterator i = _data.constBegin();
|
||||
while (i != _data.constEnd())
|
||||
{
|
||||
p << i.key();
|
||||
++i;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int ADIF::getCount()
|
||||
{
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
|
||||
// open ADIF file and append the QSO details. Return true on success
|
||||
bool ADIF::addQSOToFile(QString const& hisCall, QString const& hisGrid, QString const& mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, QString const& band,
|
||||
QString const& comments, QString const& name, QString const& strDialFreq, QString const& m_myCall, QString const& m_myGrid, QString const& m_txPower)
|
||||
{
|
||||
QFile f2(_filename);
|
||||
if (!f2.open(QIODevice::Text | QIODevice::Append))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
QTextStream out(&f2);
|
||||
if (f2.size()==0)
|
||||
out << "WSJT-X ADIF Export<eoh>" << endl; // new file
|
||||
|
||||
QString t;
|
||||
t="<call:" + QString::number(hisCall.length()) + ">" + hisCall;
|
||||
t+=" <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
|
||||
t+=" <mode:" + QString::number(mode.length()) + ">" + mode;
|
||||
t+=" <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
|
||||
t+=" <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
|
||||
t+=" <qso_date:8>" + dateTimeOn.date ().toString ("yyyyMMdd");
|
||||
t+=" <time_on:6>" + dateTimeOn.time ().toString ("hhmmss");
|
||||
t+=" <qso_date_off:8>" + dateTimeOff.date ().toString ("yyyyMMdd");
|
||||
t+=" <time_off:6>" + dateTimeOff.time ().toString ("hhmmss");
|
||||
t+=" <band:" + QString::number(band.length()) + ">" + band;
|
||||
t+=" <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
|
||||
t+=" <station_callsign:" + QString::number(m_myCall.length()) + ">" +
|
||||
m_myCall;
|
||||
t+=" <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
|
||||
m_myGrid;
|
||||
if(m_txPower!="") t+= " <tx_pwr:" + QString::number(m_txPower.length()) +
|
||||
">" + m_txPower;
|
||||
if(comments!="") t+=" <comment:" + QString::number(comments.length()) +
|
||||
">" + comments;
|
||||
if(name!="") t+=" <name:" + QString::number(name.length()) +
|
||||
">" + name;
|
||||
t+=" <eor>";
|
||||
out << t << endl;
|
||||
f2.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ADIF::bandFromFrequency(double dialFreq)
|
||||
{
|
||||
QString band="";
|
||||
if(dialFreq>0.135 and dialFreq<0.139) band="2200m";
|
||||
else if(dialFreq>0.45 and dialFreq<0.55) band="630m";
|
||||
else if(dialFreq>1.8 and dialFreq<2.0) band="160m";
|
||||
else if(dialFreq>3.5 and dialFreq<4.0) band="80m";
|
||||
else if(dialFreq>5.1 and dialFreq<5.45) band="60m";
|
||||
else if(dialFreq>7.0 and dialFreq<7.3) band="40m";
|
||||
else if(dialFreq>10.0 and dialFreq<10.15) band="30m";
|
||||
else if(dialFreq>14.0 and dialFreq<14.35) band="20m";
|
||||
else if(dialFreq>18.068 and dialFreq<18.168) band="17m";
|
||||
else if(dialFreq>21.0 and dialFreq<21.45) band="15m";
|
||||
else if(dialFreq>24.890 and dialFreq<24.990) band="12m";
|
||||
else if(dialFreq>28.0 and dialFreq<29.7) band="10m";
|
||||
else if(dialFreq>50.0 and dialFreq<54.0) band="6m";
|
||||
else if(dialFreq>70.0 and dialFreq<71.0) band="4m";
|
||||
else if(dialFreq>144.0 and dialFreq<148.0) band="2m";
|
||||
else if(dialFreq>222.0 and dialFreq<225.0) band="1.25m";
|
||||
else if(dialFreq>420.0 and dialFreq<450.0) band="70cm";
|
||||
else if(dialFreq>902.0 and dialFreq<928.0) band="33cm";
|
||||
else if(dialFreq>1240.0 and dialFreq<1300.0) band="23cm";
|
||||
else if(dialFreq>2300.0 and dialFreq<2450.0) band="13cm";
|
||||
else if(dialFreq>3300.0 and dialFreq<3500.0) band="9cm";
|
||||
else if(dialFreq>5650.0 and dialFreq<5925.0) band="6cm";
|
||||
else if(dialFreq>10000.0 and dialFreq<10500.0) band="3cm";
|
||||
else if(dialFreq>24000.0 and dialFreq<24250.0) band="1.25cm";
|
||||
else if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm";
|
||||
else if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm";
|
||||
return band;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2001 - 2016 by Joe Taylor, K1JT.
|
||||
|
||||
WSJT-X is a computer program designed to facilitate basic amateur
|
||||
radio communication using very weak signals. The first four letters in
|
||||
the program name stand for “Weak Signal communication by K1JT,” while
|
||||
the suffix “-X” indicates that WSJT-X started as an extended (and
|
||||
experimental) branch of the program WSJT.
|
||||
|
||||
WSJT-X Version 1.6 offers five protocols or “modes”: JT4, JT9, JT65
|
||||
WSPR, and Echo. The first three are designed for making reliable QSOs
|
||||
under extreme weak-signal conditions. They use nearly identical
|
||||
message structure and source encoding. JT65 was designed for EME
|
||||
(“moonbounce”) on the VHF/UHF bands and has also proven very effective
|
||||
for worldwide QRP communication on the HF bands. JT9 is optimized for
|
||||
the LF, MF, and lower HF bands. It is 2 dB more sensitive than JT65
|
||||
while using less than 10% of the bandwidth. JT4 offers a wide variety
|
||||
of tone spacings and has proved very effective for EME on microwave
|
||||
bands up to 24 GHz. All three of these modes use one-minute timed
|
||||
sequences of alternating transmission and reception, so a minimal QSO
|
||||
takes four to six minutes — two or three transmissions by each
|
||||
station, one sending in odd UTC minutes and the other even. On the HF
|
||||
bands, world-wide QSOs are possible using power levels of a few watts
|
||||
and compromise antennas. On VHF bands and higher, QSOs are possible
|
||||
(by EME and other propagation types) at signal levels 10 to 15 dB
|
||||
below those required for CW.
|
||||
|
||||
WSPR (pronounced “whisper”) stands for Weak Signal Propagation
|
||||
Reporter. The WSPR protocol was designed for probing potential
|
||||
propagation paths using low-power transmissions. WSPR messages
|
||||
normally carry the transmitting station’s callsign, grid locator, and
|
||||
transmitter power in dBm, and they can be decoded at signal-to-noise
|
||||
ratios as low as -28 dB in a 2500 Hz bandwidth. WSPR users with
|
||||
internet access can automatically upload their reception reports to a
|
||||
central database called {wsprnet} that provides a mapping facility,
|
||||
archival storage, and many other features.
|
||||
|
||||
Echo mode allows you to detect and measure your own lunar echoes, even
|
||||
if they are far below the audible threshold.
|
||||
|
||||
WSJT-X provides spectral displays for passbands up to 5 kHz, flexible
|
||||
rig control for nearly all modern radios used by amateurs, and a wide
|
||||
variety of special aids such as automatic Doppler tracking for EME
|
||||
QSOs and Echo testing. The program runs equally well on Windows,
|
||||
Macintosh, and Linux systems, and installation packages are available
|
||||
for all three platforms.
|
||||
|
||||
WSJT-X is an open-source project released under the GPL license (See
|
||||
COPYING). If you have programming or documentation skills or would
|
||||
like to contribute to the project in other ways, please make your
|
||||
interests known to the development team. The project’s source-code
|
||||
repository can be found at https://sourceforge.net/projects/wsjt, and
|
||||
most communication among the developers takes place on the email
|
||||
reflector https://sourceforge.net/p/wsjt/mailman. User-level
|
||||
questions and answers, and general communication among users is found
|
||||
on the https://groups.yahoo.com/neo/groups/wsjtgroup/info email
|
||||
reflector.
|
||||
|
||||
|
||||
Project web site:
|
||||
|
||||
http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
Project mailing list (shared with other applications from the same
|
||||
team):
|
||||
|
||||
https://groups.yahoo.com/neo/groups/wsjtgroup
|
||||
|
||||
Reference in New Issue
Block a user