Improve sensitivity of waterfall for detecting weak narrowband signals.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@8403 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2018-01-12 20:40:15 +00:00
parent 2697ad1d56
commit b27f51bbe3
6 changed files with 107 additions and 16 deletions

View File

@ -523,6 +523,7 @@ set (wsjt_FSRCS
lib/pctile.f90 lib/pctile.f90
lib/peakdt9.f90 lib/peakdt9.f90
lib/peakup.f90 lib/peakup.f90
lib/plotsave.f90
lib/polyfit.f90 lib/polyfit.f90
lib/fsk4hf/polyfit4.f90 lib/fsk4hf/polyfit4.f90
lib/prog_args.f90 lib/prog_args.f90

38
lib/plotsave.f90 Normal file
View File

@ -0,0 +1,38 @@
subroutine plotsave(splot,ka,nbpp,irow,jz,swide)
parameter (NSMAX=6827,NYMAX=64)
real splot(NSMAX)
real spsave(NSMAX,NYMAX)
real swide(jz)
real s(NSMAX),tmp(NSMAX)
data ncall/0/
save ncall,spsave
if(irow.lt.0) then
! Save a new row of data
ncall=ncall+1
k=mod(ncall-1,NYMAX) + 1
spsave(1:NSMAX,k)=splot
else
! Process and return the saved "irow" as swide(), for a waterfall replot.
k=mod(NYMAX+ncall-1-irow,NYMAX) + 1
if(nbpp.eq.1) then
swide=spsave(1:jz,k)
else
s=spsave(1:NSMAX,k)
call smo(s,NSMAX,tmp,nbpp)
k=ka
do j=1,jz
smax=0.
do i=1,nbpp
k=k+1
if(k.lt.1 .or. k.gt.NSMAX) exit
smax=max(smax,s(k))
enddo
swide(j)=smax
enddo
endif
endif
return
end subroutine plotsave

View File

@ -116,12 +116,13 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
double fac = sqrt(m_binsPerPixel*m_waterfallAvg/15.0); double fac = sqrt(m_binsPerPixel*m_waterfallAvg/15.0);
double gain = fac*pow(10.0,0.02*m_plotGain); double gain = fac*pow(10.0,0.02*m_plotGain);
double gain2d = pow(10.0,0.02*(m_plot2dGain)); double gain2d = pow(10.0,0.02*(m_plot2dGain));
bool bReplot=swide[MAX_SCREENSIZE-1] == -99.0;
if(m_bReference != m_bReference0) resizeEvent(NULL); if(m_bReference != m_bReference0) resizeEvent(NULL);
m_bReference0=m_bReference; m_bReference0=m_bReference;
//move current data down one line (must do this before attaching a QPainter object) //move current data down one line (must do this before attaching a QPainter object)
if(bScroll) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1); if(bScroll and !bReplot) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
QPainter painter1(&m_WaterfallPixmap); QPainter painter1(&m_WaterfallPixmap);
m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2); m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2);
QPainter painter2D(&m_2DPixmap); QPainter painter2D(&m_2DPixmap);
@ -146,15 +147,15 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
int jz=iz*m_binsPerPixel; int jz=iz*m_binsPerPixel;
m_fMax=FreqfromX(iz); m_fMax=FreqfromX(iz);
m_line++; if(bScroll and swide[0]<1.e29) {
if(bScroll) {
flat4_(swide,&iz,&m_Flatten); flat4_(swide,&iz,&m_Flatten);
flat4_(&dec_data.savg[j0],&jz,&m_Flatten); if(!bReplot) flat4_(&dec_data.savg[j0],&jz,&m_Flatten);
} }
ymin=1.e30; ymin=1.e30;
if(swide[0]>1.e29 and swide[0]< 1.5e30) painter1.setPen(Qt::green); if(swide[0]>1.e29 and swide[0]< 1.5e30) painter1.setPen(Qt::green);
if(swide[0]>1.4e30) painter1.setPen(Qt::yellow); if(swide[0]>1.4e30) painter1.setPen(Qt::yellow);
if(!bReplot) m_j=0;
for(int i=0; i<iz; i++) { for(int i=0; i<iz; i++) {
y=swide[i]; y=swide[i];
if(y<ymin) ymin=y; if(y<ymin) ymin=y;
@ -162,9 +163,11 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
if (y1<0) y1=0; if (y1<0) y1=0;
if (y1>254) y1=254; if (y1>254) y1=254;
if (swide[i]<1.e29) painter1.setPen(g_ColorTbl[y1]); if (swide[i]<1.e29) painter1.setPen(g_ColorTbl[y1]);
painter1.drawPoint(i,0); painter1.drawPoint(i,m_j);
} }
if(bReplot) return;
m_line++;
float y2min=1.e30; float y2min=1.e30;
float y2max=-1.e30; float y2max=-1.e30;
for(int i=0; i<iz; i++) { for(int i=0; i<iz; i++) {
@ -283,6 +286,13 @@ void CPlotter::drawRed(int ia, int ib, float swide[])
draw(swide,false,true); draw(swide,false,true);
} }
void CPlotter::replot(float swide[], bool bScroll, bool bRed, int irow)
{
m_j=irow;
draw(swide,bScroll,bRed);
update(); //trigger a new paintEvent
}
void CPlotter::DrawOverlay() //DrawOverlay() void CPlotter::DrawOverlay() //DrawOverlay()
{ {
if(m_OverlayPixmap.isNull()) return; if(m_OverlayPixmap.isNull()) return;

View File

@ -37,6 +37,7 @@ public:
QSize sizeHint() const; QSize sizeHint() const;
void draw(float swide[], bool bScroll, bool bRed); //Update the waterfall void draw(float swide[], bool bScroll, bool bRed); //Update the waterfall
void replot(float swide[], bool bScroll, bool bRed, int irow);
void SetRunningState(bool running); void SetRunningState(bool running);
void setPlotZero(int plotZero); void setPlotZero(int plotZero);
int plotZero(); int plotZero();
@ -170,6 +171,7 @@ private:
qint32 m_fMax; qint32 m_fMax;
qint32 m_startFreq; qint32 m_startFreq;
qint32 m_tol; qint32 m_tol;
qint32 m_j;
char m_sutc[6]; char m_sutc[6];
}; };

View File

@ -169,12 +169,16 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dat
int i=int(ui->widePlot->startFreq()/df3 + 0.5); int i=int(ui->widePlot->startFreq()/df3 + 0.5);
int jz=5000.0/(nbpp*df3); int jz=5000.0/(nbpp*df3);
if(jz>MAX_SCREENSIZE) jz=MAX_SCREENSIZE; if(jz>MAX_SCREENSIZE) jz=MAX_SCREENSIZE;
m_jz=jz;
for (int j=0; j<jz; j++) { for (int j=0; j<jz; j++) {
float ss=0; float ss=0.0;
float smax=0;
for (int k=0; k<nbpp; k++) { for (int k=0; k<nbpp; k++) {
if(splot[i]>ss) ss=splot[i]; float sp=splot[i++];
i++; ss += sp;
smax=qMax(smax,sp);
} }
// swide[j]=nbpp*smax;
swide[j]=nbpp*ss; swide[j]=nbpp*ss;
} }
@ -184,25 +188,33 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dat
if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && ntr<m_ntr0)) { if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && ntr<m_ntr0)) {
float flagValue=1.0e30; float flagValue=1.0e30;
if(m_bHaveTransmitted) flagValue=2.0e30; if(m_bHaveTransmitted) flagValue=2.0e30;
for (int i=0; i<2048; i++) { for(int i=0; i<MAX_SCREENSIZE; i++) {
swide[i] = flagValue; swide[i] = flagValue;
} }
for(int i=0; i<NSMAX; i++) {
splot[i] = flagValue;
}
m_bHaveTransmitted=false; m_bHaveTransmitted=false;
} }
m_ntr0=ntr; m_ntr0=ntr;
ui->widePlot->draw(swide,true,false); ui->widePlot->draw(swide,true,false);
int irow=-1;
int ka=0;
plotsave_(splot,&ka,&nbpp,&irow,&jz,swide);
} }
} }
void WideGraph::on_bppSpinBox_valueChanged(int n) //bpp void WideGraph::on_bppSpinBox_valueChanged(int n) //bpp
{ {
ui->widePlot->setBinsPerPixel(n); ui->widePlot->setBinsPerPixel(n);
replot();
} }
void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n) //Navg void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n) //Navg
{ {
m_waterfallAvg = n; m_waterfallAvg = n;
ui->widePlot->setWaterfallAvg(n); ui->widePlot->setWaterfallAvg(n);
replot();
} }
void WideGraph::keyPressEvent(QKeyEvent *e) //F11, F12 void WideGraph::keyPressEvent(QKeyEvent *e) //F11, F12
@ -362,6 +374,7 @@ void WideGraph::setRxBand (QString const& band)
void WideGraph::on_fStartSpinBox_valueChanged(int n) //fStart void WideGraph::on_fStartSpinBox_valueChanged(int n) //fStart
{ {
ui->widePlot->setStartFreq(n); ui->widePlot->setStartFreq(n);
replot();
} }
void WideGraph::readPalette () //readPalette void WideGraph::readPalette () //readPalette
@ -387,6 +400,7 @@ void WideGraph::on_paletteComboBox_activated (QString const& palette) //palet
{ {
m_waterfallPalette = palette; m_waterfallPalette = palette;
readPalette(); readPalette();
replot();
} }
void WideGraph::on_cbFlatten_toggled(bool b) //Flatten On/Off void WideGraph::on_cbFlatten_toggled(bool b) //Flatten On/Off
@ -397,6 +411,7 @@ void WideGraph::on_cbFlatten_toggled(bool b) //Flatten
ui->cbRef->setChecked(false); ui->cbRef->setChecked(false);
} }
ui->widePlot->setFlatten(m_bFlatten,m_bRef); ui->widePlot->setFlatten(m_bFlatten,m_bRef);
replot();
} }
void WideGraph::on_cbRef_toggled(bool b) void WideGraph::on_cbRef_toggled(bool b)
@ -407,6 +422,7 @@ void WideGraph::on_cbRef_toggled(bool b)
ui->cbFlatten->setChecked(false); ui->cbFlatten->setChecked(false);
} }
ui->widePlot->setFlatten(m_bFlatten,m_bRef); ui->widePlot->setFlatten(m_bFlatten,m_bRef);
replot();
} }
void WideGraph::on_cbControls_toggled(bool b) void WideGraph::on_cbControls_toggled(bool b)
@ -444,11 +460,26 @@ bool WideGraph::useRef() //Flatten
void WideGraph::on_gainSlider_valueChanged(int value) //Gain void WideGraph::on_gainSlider_valueChanged(int value) //Gain
{ {
ui->widePlot->setPlotGain(value); ui->widePlot->setPlotGain(value);
replot();
}
void WideGraph::replot()
{
if(!ui->widePlot->scaleOK()) return;
int nbpp = ui->widePlot->binsPerPixel();
float splot=0.0;
int ka=int(ui->widePlot->startFreq()/0.732422 + 0.5) - 1;
for(int irow=0; irow<64; irow++) {
plotsave_(&splot,&ka,&nbpp,&irow,&m_jz,swide);
swide[MAX_SCREENSIZE-1]=-99.0;
ui->widePlot->replot(swide,true,false,irow);
}
} }
void WideGraph::on_zeroSlider_valueChanged(int value) //Zero void WideGraph::on_zeroSlider_valueChanged(int value) //Zero
{ {
ui->widePlot->setPlotZero(value); ui->widePlot->setPlotZero(value);
replot();
} }
void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2 void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2

View File

@ -86,30 +86,39 @@ private slots:
private: private:
void readPalette (); void readPalette ();
void setRxRange (); void setRxRange ();
void replot();
QScopedPointer<Ui::WideGraph> ui; QScopedPointer<Ui::WideGraph> ui;
QSettings * m_settings; QSettings * m_settings;
QDir m_palettes_path; QDir m_palettes_path;
WFPalette m_userPalette; WFPalette m_userPalette;
QHash<QString, QVariant> m_fMinPerBand;
qint32 m_waterfallAvg; qint32 m_waterfallAvg;
qint32 m_TRperiod; qint32 m_TRperiod;
qint32 m_nsps; qint32 m_nsps;
qint32 m_ntr0; qint32 m_ntr0;
QHash<QString, QVariant> m_fMinPerBand;
qint32 m_fMax; qint32 m_fMax;
QString m_rxBand;
qint32 m_nSubMode; qint32 m_nSubMode;
qint32 m_nsmo; qint32 m_nsmo;
qint32 m_Percent2DScreen; qint32 m_Percent2DScreen;
qint32 m_jz=MAX_SCREENSIZE;
qint32 m_n;
bool m_bFlatten; bool m_bFlatten;
bool m_bRef; bool m_bRef;
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
QString m_rxBand;
QString m_mode; QString m_mode;
QString m_modeTx; QString m_modeTx;
QString m_waterfallPalette; QString m_waterfallPalette;
int m_n;
}; };
extern "C" {
void plotsave_(float splot[], int* ka, int* nbpp, int* irow, int* jz, float swide[]);
}
#endif // WIDEGRAPH_H #endif // WIDEGRAPH_H