9 #include "qwt_plot_marker.h"
13 QVector< EqScanFit >& a_scanfits,
23 scanfits ( a_scanfits ),
27 ereporter ( a_ereporter ),
30 fWidget ( a_fWidget ),
33 qDebug() <<
"EFC: IN";
34 setAttribute ( Qt::WA_DeleteOnClose );
35 setWindowTitle( tr(
"Equilibrium Fitting Control Window" ) );
37 setMinimumSize( 200, 100 );
40 QBoxLayout*
main =
new QHBoxLayout(
this );
41 main->setContentsMargins( 2, 2, 2, 2 );
42 main->setSpacing ( 2 );
45 QBoxLayout* lsideLayout =
new QVBoxLayout;
46 QBoxLayout* rsideLayout =
new QVBoxLayout;
49 QGridLayout* eqfitLayout =
new QGridLayout;
50 QGridLayout* gplotLayout =
new QGridLayout;
51 QGridLayout* ftuneLayout =
new QGridLayout;
56 tr(
"Radius^2 - Radius(ref)^2 (cm)" ),
57 tr(
"Optical Density Difference" ) );
58 QGridLayout* statsLayout =
new QGridLayout;
62 tr(
"Nonlinear Least Squares\n"
63 "Global Equilibrium Fitting Control" ) );
64 QLabel* lb_iternbr =
us_label( tr(
"Iteration Number:" ) );
67 QLabel* lb_varianc =
us_label( tr(
"Variance:" ) );
70 QLabel* lb_stddev =
us_label( tr(
"Std.Deviation:" ) );
73 QLabel* lb_improve =
us_label( tr(
"Improvement:" ) );
76 QLabel* lb_funceva =
us_label( tr(
"Function Evaluations:" ) );
79 QLabel* lb_decompo =
us_label( tr(
"Decompositions:" ) );
82 QLabel* lb_clambda =
us_label( tr(
"Current Lambda:" ) );
85 QLabel* lb_nbrpars =
us_label( tr(
"# of Parameters:" ) );
87 QLabel* lb_nbrsets =
us_label( tr(
"# of Datasets in Fit:" ) );
90 QLabel* lb_nbrdpts =
us_label( tr(
"# of Datapoints in Fit:" ) );
95 eqfitLayout->addWidget( lb_fbanner, row, 0, 2, 6 );
97 eqfitLayout->addWidget( lb_iternbr, row, 0, 1, 2 );
98 eqfitLayout->addWidget(
le_iternbr, row, 2, 1, 2 );
99 eqfitLayout->addWidget(
pb_strtfit, row++, 4, 1, 2 );
100 eqfitLayout->addWidget( lb_varianc, row, 0, 1, 2 );
101 eqfitLayout->addWidget(
le_varianc, row, 2, 1, 2 );
102 eqfitLayout->addWidget(
pb_pause, row++, 4, 1, 2 );
103 eqfitLayout->addWidget( lb_stddev, row, 0, 1, 2 );
104 eqfitLayout->addWidget(
le_stddev, row, 2, 1, 2 );
105 eqfitLayout->addWidget(
pb_resume, row++, 4, 1, 2 );
106 eqfitLayout->addWidget( lb_improve, row, 0, 1, 2 );
107 eqfitLayout->addWidget(
le_improve, row, 2, 1, 2 );
108 eqfitLayout->addWidget(
pb_savefit, row++, 4, 1, 2 );
109 eqfitLayout->addWidget( lb_funceva, row, 0, 1, 2 );
110 eqfitLayout->addWidget(
le_funceva, row, 2, 1, 2 );
111 eqfitLayout->addWidget(
pb_viewrep, row++, 4, 1, 2 );
112 eqfitLayout->addWidget( lb_decompo, row, 0, 1, 2 );
113 eqfitLayout->addWidget(
le_decompo, row, 2, 1, 2 );
114 eqfitLayout->addWidget(
pb_resids, row++, 4, 1, 2 );
115 eqfitLayout->addWidget( lb_clambda, row, 0, 1, 2 );
116 eqfitLayout->addWidget(
le_clambda, row, 2, 1, 2 );
117 eqfitLayout->addWidget(
pb_ovrlays, row++, 4, 1, 2 );
118 eqfitLayout->addWidget( lb_nbrpars, row, 0, 1, 2 );
119 eqfitLayout->addWidget(
le_nbrpars, row++, 2, 1, 2 );
120 eqfitLayout->addWidget( lb_nbrsets, row, 0, 1, 2 );
121 eqfitLayout->addWidget(
le_nbrsets, row, 2, 1, 2 );
122 eqfitLayout->addWidget(
pb_help, row++, 4, 1, 2 );
123 eqfitLayout->addWidget( lb_nbrdpts, row, 0, 1, 2 );
124 eqfitLayout->addWidget(
le_nbrdpts, row, 2, 1, 2 );
125 eqfitLayout->addWidget(
pb_close, row++, 4, 1, 2 );
129 connect(
pb_pause, SIGNAL( clicked() ),
141 connect(
pb_close, SIGNAL( clicked() ),
143 connect(
pb_help, SIGNAL( clicked() ),
144 this, SLOT(
help() ) );
154 tr(
"Graph Plotting Controls" ) );
161 QButtonGroup* plotgrp =
new QButtonGroup(
this );
165 QLabel* lb_plotscn =
us_label( tr(
"Scan (start):" ) );
167 QLayout* lo_monfitg =
us_checkbox( tr(
"Monitor Fit Graphically" ),
171 gplotLayout->addWidget( lb_gbanner, row++, 0, 1, 6 );
172 gplotLayout->addLayout( lo_pltalld, row, 0, 1, 2 );
173 gplotLayout->addLayout( lo_pltgrp5, row, 2, 1, 2 );
174 gplotLayout->addLayout( lo_pltsscn, row++, 4, 1, 2 );
175 gplotLayout->addWidget( lb_plotscn, row, 0, 1, 3 );
176 gplotLayout->addWidget(
ct_plotscn, row++, 3, 1, 3 );
177 gplotLayout->addLayout( lo_monfitg, row++, 2, 1, 4 );
186 tr(
"NLSQ Fit Tuning Controls" ) );
187 QLabel* lb_lincnst =
us_label( tr(
"Linear Constraints:" ) );
190 QHBoxLayout* lo_lincbox =
new QHBoxLayout;
191 QButtonGroup* lcnsgrp =
new QButtonGroup(
this );
192 lo_lincbox->setSpacing ( 0 );
193 lo_lincbox->setContentsMargins( 0, 0, 0, 0 );
194 lo_lincbox->addLayout( lo_lincnsn );
195 lo_lincbox->addLayout( lo_lincnsy );
198 lcnsgrp->setExclusive(
true );
199 QLabel* lb_autocnv =
us_label( tr(
"Autoconverge:" ) );
202 QHBoxLayout* lo_autcbox =
new QHBoxLayout;
203 QButtonGroup* autcgrp =
new QButtonGroup(
this );
204 lo_autcbox->setSpacing ( 0 );
205 lo_autcbox->setContentsMargins( 0, 0, 0, 0 );
206 lo_autcbox->addLayout( lo_autocnn );
207 lo_autcbox->addLayout( lo_autocny );
210 autcgrp->setExclusive(
true );
211 QLabel* lb_nlsalgo =
us_label( tr(
"NLS Algorithm:" ) );
213 QLabel* lb_lamstrt =
us_label( tr(
"Lambda Start:" ) );
216 QLabel* lb_lamsize =
us_label( tr(
"Lambda Step Size:" ) );
219 QLabel* lb_mxiters =
us_label( tr(
"Maximum Iterations:" ) );
222 QLabel* lb_fittolr =
us_label( tr(
"Fit Tolerance:" ) );
225 QLabel* lb_fprogres =
us_label( tr(
"Fitting Progress:" ) );
229 ftuneLayout->addWidget( lb_tbanner, row++, 0, 1, 6 );
230 ftuneLayout->addWidget( lb_lincnst, row, 0, 1, 2 );
231 ftuneLayout->addLayout( lo_lincbox, row++, 2, 1, 4 );
232 ftuneLayout->addWidget( lb_autocnv, row, 0, 1, 2 );
233 ftuneLayout->addLayout( lo_autcbox, row++, 2, 1, 4 );
234 ftuneLayout->addWidget( lb_nlsalgo, row, 0, 1, 2 );
235 ftuneLayout->addWidget(
cb_nlsalgo, row++, 2, 1, 4 );
236 ftuneLayout->addWidget( lb_lamstrt, row, 0, 1, 2 );
237 ftuneLayout->addWidget(
le_lamstrt, row, 2, 1, 2 );
238 ftuneLayout->addWidget(
pb_lnvsr2, row++, 4, 1, 2 );
239 ftuneLayout->addWidget( lb_lamsize, row, 0, 1, 2 );
240 ftuneLayout->addWidget(
le_lamsize, row, 2, 1, 2 );
241 ftuneLayout->addWidget(
pb_mwvsr2, row++, 4, 1, 2 );
242 ftuneLayout->addWidget( lb_mxiters, row, 0, 1, 2 );
243 ftuneLayout->addWidget(
le_mxiters, row, 2, 1, 2 );
244 ftuneLayout->addWidget(
pb_mwvscv, row++, 4, 1, 2 );
245 ftuneLayout->addWidget( lb_fittolr, row, 0, 1, 2 );
246 ftuneLayout->addWidget(
le_fittolr, row, 2, 1, 2 );
247 ftuneLayout->addWidget(
pb_cmments, row++, 4, 1, 2 );
248 ftuneLayout->addWidget( lb_fprogres, row, 0, 1, 2 );
249 ftuneLayout->addWidget(
progress, row++, 2, 1, 4 );
251 cb_nlsalgo->addItem( tr(
"Levenberg-Marquardt" ) );
252 cb_nlsalgo->addItem( tr(
"Modified Gauss-Newton" ) );
254 cb_nlsalgo->addItem( tr(
"Quasi-Newton Method" ) );
255 cb_nlsalgo->addItem( tr(
"Generalized Linear LS" ) );
256 cb_nlsalgo->addItem( tr(
"NonNegative constrained LS" ) );
265 QLabel* lb_status =
us_label( tr(
"Status:" ) );
267 tr(
"Waiting for Input - Please click on \"Fit\" to start"
268 " the fitting process..." ) );
269 QLabel* lb_inform =
us_label( tr(
"Information:" ) );
273 statsLayout->addWidget( lb_status, row, 0, 1, 2 );
274 statsLayout->addWidget(
le_status, row++, 2, 1, 8 );
275 statsLayout->addWidget( lb_inform, row, 0, 1, 2 );
276 statsLayout->addWidget(
le_inform, row++, 2, 1, 8 );
279 lsideLayout->addLayout( eqfitLayout );
280 lsideLayout->addLayout( gplotLayout );
281 lsideLayout->addLayout( ftuneLayout );
282 lsideLayout->addStretch();
284 rsideLayout->addLayout(
dplot );
285 rsideLayout->addLayout( statsLayout );
286 rsideLayout->setStretchFactor(
dplot, 1 );
287 rsideLayout->setStretchFactor( statsLayout, 0 );
289 main->addLayout( lsideLayout );
290 main->addLayout( rsideLayout );
291 main->setStretchFactor( lsideLayout, 2 );
292 main->setStretchFactor( rsideLayout, 4 );
295 setMinimumSize( 1000, 600 );
304 qDebug() <<
"EFC: init_fit return";
328 qDebug() <<
"START_FIT";
329 const char* cmeth[] = {
"L-M",
"M G-N",
"Hybrid",
"Q-N",
"GLLS",
"NNLS" };
331 if (
pb_strtfit->text().contains( tr(
"Abort" ) ) )
341 le_inform->setText( tr(
"Fitting ABORTED by user request!" ) );
348 le_inform->setText( tr(
"Fitting iterations have begun" ) );
376 connect(
fitwork, SIGNAL( work_progress(
int ) ),
378 connect(
fitwork, SIGNAL( work_complete() ),
389 qDebug() <<
"PAUSE_FIT";
399 qDebug() <<
"RESUME_FIT";
409 qDebug() <<
"SAVE_FIT";
414 qDebug() <<
"VIEW_REPORT";
424 qDebug() <<
" V_REP filename" << filename;
430 qDebug() <<
"PLOT_RESIDUALS";
435 qDebug() <<
"PL_R: mxspts" <<
mxspts <<
"ipscnn" <<
ipscnn;
437 QVector< double > v_xplot;
438 QVector< double > v_yplot;
439 v_xplot.fill( 0.0,
mxspts );
440 v_yplot.fill( 0.0,
mxspts );
441 double* xplot = v_xplot.data();
442 double* yplot = v_yplot.data();
447 double yoffi = (
plotgrpf == 5 ) ? 0.03 : 0.0;
449 qDebug() <<
" ydelta0" << ydelta[0] <<
" ydeltan" << ydelta[ntpts-1];
452 data_plot->setTitle( tr(
"Residuals" ) );
454 tr(
"Optical Density Difference" ) );
455 data_plot->setAxisTitle( QwtPlot::xBottom,
456 tr(
"Radius^2 - Radius(ref)^2 (cm)" ) );
458 grid->enableYMin(
true );
459 grid->enableY (
true );
464 sym.setStyle( QwtSymbol::Ellipse );
465 sym.setPen ( QPen ( Qt::blue ) );
466 sym.setBrush( QBrush( Qt::yellow ) );
467 sym.setSize (
plotgrpf < 0 ? 8 : 5 );
469 QPen lnpen( QBrush( Qt::green ), 1 );
470 QPen zlpen( QBrush( Qt::red ), 2 );
477 for (
int ii = 0; ii <
scanfits.size(); ii++ )
486 int jdsx =
dscnx[ ii ];
488 int nspts = scnf->
stop_ndx - jvxy + 1;
489 double xmsq =
sq( scnf->
xvs[ jvxy ] );
493 for (
int jj = 0; jj < nspts; jj++ )
495 xplot[ jj ] =
sq( scnf->
xvs[ jvxy ] ) - xmsq;
497 yplot[ jj ] = ydelta[ jdsx ] + yoffs;
504 xmax =
max( xmax, xplot[ nspts - 1 ] );
505 xmin =
min( xmin, -xpad );
507 QString(
"RLine-%1" ).arg( scnn ) );
509 lcurve->setStyle ( QwtPlotCurve::Lines );
510 lcurve->setPen ( lnpen );
511 lcurve->setData ( xplot, yplot, nspts );
514 QString(
"RSymb-%1" ).arg( scnn ) );
515 scurve->setStyle ( QwtPlotCurve::NoCurve );
516 scurve->setSymbol( sym );
517 scurve->setData ( xplot, yplot, nspts );
521 if (
plotgrpf == 5 ) sns[ ksn++ ] = scnn;
525 data_plot->setAxisScale( QwtPlot::xBottom, xmin, xmax );
526 data_plot->setAxisAutoScale( QwtPlot::yLeft );
531 double yofmx = yoffs;
536 xpzero[ 1 ] = xmax - xpad;
539 while ( yoffs < yofmx )
541 int scnn = sns[ ksn++ ];
543 QString(
"RZero-%1" ).arg( scnn ) );
546 zcurve->setStyle ( QwtPlotCurve::Lines );
547 zcurve->setPen ( zlpen );
548 zcurve->setData ( xpzero, ypzero, 2 );
549 QwtPlotMarker* marker =
new QwtPlotMarker;
551 mlabel.setText( QString::number( scnn ) );
552 mlabel.setFont( lbfont );
553 mlabel.setColor( Qt::red );
554 mlabel.setBackgroundBrush( QBrush( Qt::white ) );
555 marker->setValue( xmax, yoffs );
556 marker->setLabel( mlabel );
557 marker->setLabelAlignment( Qt::AlignLeft | Qt::AlignVCenter );
571 zcurve->setStyle ( QwtPlotCurve::Lines );
572 zcurve->setPen ( zlpen );
573 zcurve->setData ( xpzero, ypzero, 2 );
582 qDebug() <<
"PLOT_OVERLAYS";
587 qDebug() <<
"PL_O: mxspts" <<
mxspts <<
"ipscnn" <<
ipscnn;
589 QVector< double > v_xplot;
590 v_xplot.fill( 0.0,
mxspts );
591 double* xplot = v_xplot.data();
594 double* ypraw = yraw;
595 double* ypfit = yguess;
597 qDebug() <<
" yguess0" << yguess[0] <<
" yguessn" << yguess[ntpts-1];
601 tr(
"Overlays for fitted Scan %1" ).arg( ipscnn ) :
602 tr(
"Overlays for fitted Scans %1 - %2" ).arg( ipscnn ).arg(
lpscnn ) );
604 tr(
"Optical Density Difference" ) );
605 data_plot->setAxisTitle( QwtPlot::xBottom,
606 tr(
"Radius^2 - Radius(ref)^2 (cm)" ) );
608 grid->enableYMin(
true );
609 grid->enableY (
true );
614 sym.setStyle( QwtSymbol::Ellipse );
615 sym.setPen ( QPen ( Qt::blue ) );
616 sym.setBrush( QBrush( Qt::yellow ) );
619 QPen lnpen( QBrush( Qt::red ), 1 );
624 for (
int ii = 0; ii <
scanfits.size(); ii++ )
633 int jdsx =
dscnx[ ii ];
635 int nspts = scnf->
stop_ndx - jvxy + 1;
636 double xmsq =
sq( scnf->
xvs[ jvxy ] );
638 ypfit = yguess + jdsx;
642 for (
int jj = 0; jj < nspts; jj++,jvxy++ )
644 xplot[ jj ] =
sq( scnf->
xvs[ jvxy ] ) - xmsq;
649 xmax =
max( xmax, xplot[ nspts - 1 ] );
650 xmin =
min( xmin, -xpad );
653 QString(
"RSymb-%1" ).arg( scnn ) );
654 scurve->setStyle ( QwtPlotCurve::NoCurve );
655 scurve->setSymbol( sym );
656 scurve->setData ( xplot, ypraw, nspts );
659 QString(
"RLine-%1" ).arg( scnn ) );
660 lcurve->setStyle ( QwtPlotCurve::Lines );
661 lcurve->setPen ( lnpen );
662 lcurve->setData ( xplot, ypfit, nspts );
666 data_plot->setAxisScale( QwtPlot::xBottom, xmin, xmax );
667 data_plot->setAxisAutoScale( QwtPlot::yLeft );
675 qDebug() <<
"PLOT_TWO";
682 qDebug() <<
"PLOT_THREE";
689 qDebug() <<
"PLOT_FOUR";
696 qDebug() <<
"NEW_PROGRESS" << step;
718 qDebug() <<
"FIT_COMPLETED";
724 iinform = tr(
"Fitting ABORTED!" );
727 iinform = tr(
"Fitting CONVERGED!" );
730 iinform = tr(
"Fitting iterations COMPLETED!" );
764 for (
int ii = 0; ii < ntscns; ii++ )
769 if ( ! scnf->
scanFit )
continue;
783 if ( kpscns > 0 && kpscns < 6 )
791 for (
int jj = 0; jj < nspts; jj++ )
793 ydelta[ dssx ] = yraw[ dssx ] - yguess[ dssx ];