1 #include <QApplication>
22 int main(
int argc,
char* argv[] )
24 QApplication application( argc, argv );
32 return application.exec();
38 setWindowTitle( tr(
"Global Equilibrium Analysis" ) );
42 QBoxLayout* mainLayout =
new QHBoxLayout(
this );
43 mainLayout->setSpacing ( 2 );
44 mainLayout->setContentsMargins ( 2, 2, 2, 2 );
47 QVBoxLayout* leftLayout =
new QVBoxLayout;
48 QVBoxLayout* rightLayout =
new QVBoxLayout;
50 QGridLayout* dataSelLayout =
new QGridLayout;
51 QGridLayout* scnListLayout =
new QGridLayout;
52 QGridLayout* modlFitLayout =
new QGridLayout;
53 QGridLayout* paramLayout =
new QGridLayout;
54 QGridLayout* statusLayout =
new QGridLayout;
57 QLabel* lb_datasel =
us_banner( tr(
"Data Selection" ) );
58 QPushButton* pb_loadExp =
us_pushbutton( tr(
"Load Experiment" ) );
60 QLayout* lo_edlast =
us_checkbox( tr(
"Lastest Data Edit" ),
70 QLabel* lb_prjname =
us_label( tr(
"Project Name:" ) );
82 connect( pb_loadExp, SIGNAL( clicked() ),
86 connect(
pb_view, SIGNAL( clicked() ),
98 connect(
le_prjname, SIGNAL( textChanged(
const QString& ) ),
102 dataSelLayout->addWidget( lb_datasel, row++, 0, 1, 2 );
103 dataSelLayout->addWidget( pb_loadExp, row, 0, 1, 1 );
104 dataSelLayout->addWidget(
pb_details, row++, 1, 1, 1 );
105 dataSelLayout->addLayout( lo_edlast, row, 0, 1, 1 );
106 dataSelLayout->addLayout(
dkdb_cntrls, row++, 1, 1, 1 );
107 dataSelLayout->addWidget(
pb_unload, row, 0, 1, 1 );
108 dataSelLayout->addWidget(
pb_view, row++, 1, 1, 1 );
109 dataSelLayout->addWidget(
pb_scdiags, row, 0, 1, 1 );
110 dataSelLayout->addWidget(
pb_ckscfit, row++, 1, 1, 1 );
111 dataSelLayout->addWidget(
pb_conchist, row, 0, 1, 1 );
112 dataSelLayout->addWidget(
pb_resetsl, row++, 1, 1, 1 );
113 dataSelLayout->addWidget( lb_prjname, row, 0, 1, 1 );
114 dataSelLayout->addWidget(
le_prjname, row++, 1, 1, 1 );
117 QLabel* lb_equiscns =
us_banner( tr(
"List of available Equilibrium"
123 QFontMetrics fm( font );
124 int rowHgt = fm.lineSpacing();
134 iconw = bapix.width();
139 scnListLayout->addWidget( lb_equiscns, row++, 0, 1, 2 );
140 scnListLayout->addWidget(
tw_equiscns, row, 0, 5, 2 );
142 lb_equiscns->setMaximumHeight( lb_prjname->height() );
145 QLabel* lb_mfitinfo =
us_banner( tr(
"Model and Fitting"
170 modlFitLayout->addWidget( lb_mfitinfo, row++, 0, 1, 2 );
171 modlFitLayout->addWidget(
pb_selModel, row, 0, 1, 1 );
172 modlFitLayout->addWidget(
pb_modlCtrl, row++, 1, 1, 1 );
173 modlFitLayout->addWidget(
pb_loadFit, row, 0, 1, 1 );
174 modlFitLayout->addWidget(
pb_fitcntrl, row++, 1, 1, 1 );
175 modlFitLayout->addWidget(
pb_monCarlo, row, 1, 1, 1 );
178 QLabel* lb_parminfo =
us_banner( tr(
"Parameter Information:" ) );
183 QLabel* lb_scselect =
us_label( tr(
"Scan Selector:" ) );
196 connect( pb_help, SIGNAL( clicked() ),
198 connect( pb_close, SIGNAL( clicked() ),
200 connect(
ct_scselect, SIGNAL( valueChanged(
double ) ),
204 paramLayout ->addWidget( lb_parminfo, row++, 0, 1, 4 );
205 paramLayout ->addWidget(
pb_floatPar, row, 0, 1, 2 );
206 paramLayout ->addWidget(
pb_initPars, row++, 2, 1, 2 );
207 paramLayout ->addWidget( pb_help, row, 0, 1, 2 );
208 paramLayout ->addWidget( pb_close, row++, 2, 1, 2 );
209 paramLayout ->addWidget( lb_scselect, row, 0, 1, 2 );
210 paramLayout ->addWidget(
ct_scselect, row++, 2, 1, 2 );
212 leftLayout->addLayout( dataSelLayout );
213 leftLayout->addLayout( scnListLayout );
214 leftLayout->addLayout( modlFitLayout );
215 leftLayout->addLayout( paramLayout );
216 leftLayout->setStretchFactor( scnListLayout, 10 );
217 leftLayout->setStretchFactor( modlFitLayout, 1 );
221 tr(
"Experiment Equilibrium Data" ),
223 tr(
"Absorbance (280 nm)" ) );
227 equil_plot->setAxisScale( QwtPlot::yLeft , 0.1, 0.601 );
228 equil_plot->setAxisScale( QwtPlot::xBottom, 5.8, 7.2 );
231 QLabel* lb_status =
us_label( tr(
"Status/Information:" ) );
233 te_status->setWordWrapMode( QTextOption::WordWrap );
234 te_status->setText( tr(
"Please select an edited Equilibrium"
235 " Dataset with \"Load Experiment\"" ) );
236 QLabel* lb_currmodl =
us_label( tr(
"Current Model:" ) );
238 QLabel* lb_mxfringe =
us_label( tr(
"Max. OD/Fringe:" ) );
240 QLabel* lb_mxfnotes =
us_label( tr(
"(set to zero to inactivate"
241 " high conc. limits)" ) );
242 te_status ->setAlignment( Qt::AlignCenter );
246 te_status ->setMinimumHeight( rowHgt * 2 + 12 );
247 te_status ->setFixedHeight( rowHgt * 2 + 12 );
250 statusLayout ->addWidget( lb_status, row, 0, 1, 2 );
251 statusLayout ->addWidget(
te_status, row++, 2, 1, 4 );
252 statusLayout ->addWidget( lb_currmodl, row, 0, 1, 2 );
253 statusLayout ->addWidget(
le_currmodl, row++, 2, 1, 4 );
254 statusLayout ->addWidget( lb_mxfringe, row, 0, 1, 2 );
255 statusLayout ->addWidget(
le_mxfringe, row, 2, 1, 1 );
256 statusLayout ->addWidget( lb_mxfnotes, row++, 3, 1, 3 );
258 connect(
le_mxfringe, SIGNAL( textChanged(
const QString& ) ),
261 rightLayout->addLayout(
eplot );
262 rightLayout->addLayout( statusLayout );
263 rightLayout->setStretchFactor(
eplot, 10 );
264 rightLayout->setStretchFactor( statusLayout, 2 );
266 mainLayout->addLayout( leftLayout );
267 mainLayout->addLayout( rightLayout );
268 mainLayout->setStretchFactor( leftLayout, 3 );
269 mainLayout->setStretchFactor( rightLayout, 5 );
318 connect( dialog, SIGNAL( changed(
bool ) ),
321 if ( dialog->exec() != QDialog::Accepted )
return;
339 qApp->processEvents();
342 if (
dataList[ 0 ].expType !=
"Equilibrium" )
344 QMessageBox::critical(
this, tr(
"Non-Equilibrium Data" ),
345 tr(
"The selected data is not of type \"Equilibrium\"!\n"
346 "Please select Equilibrium data." ) );
354 for (
int jd = 0; jd <
dataList.size(); jd++ )
359 QString s_dens = QString::number(
DENS_20W );
366 s_vbar, s_dens, s_visc, s_comp, s_manu, s_emsg );
374 DbgLv(1) <<
" jd vbar20 density" << nn <<
ds_vbar20s[nn] << ds_densits[nn];
387 QFontMetrics fm( font );
388 int rowHgt = fm.lineSpacing();
389 QString hdr1 = tr(
"Scan" );
390 QString hdr2 = tr(
"CCW Triple" );
391 QString hdr3 = tr(
"Speed" );
392 QString hdr4 = tr(
"scan of set" );
393 int whd1 = fm.width( hdr1 +
"W" );
394 int whd2 = fm.width( hdr2 +
"W" );
395 int whd3 = fm.width( hdr3 +
"W" );
396 int whd4 = fm.width( hdr4 +
"W" );
397 int whd0 = (
iconw * 3 ) / 2;
399 headers <<
"" << hdr1 << hdr2 << hdr3 << hdr4;
405 tw_equiscns->setSelectionBehavior( QAbstractItemView::SelectRows );
419 for (
int jd = 0; jd <
dataList.size(); jd++ )
422 QString triple =
triples[ jd ];
427 QTableWidgetItem* item;
434 for (
int js = iscn; js < iscn + kscn; js++ )
437 item =
new QTableWidgetItem(
blue_arrow,
"" );
438 item->setToolTip( tdesc );
443 item =
new QTableWidgetItem( QString::number( jsscn + 1 ) );
444 item->setFlags( item->flags() ^ Qt::ItemIsEditable );
445 item->setToolTip( tdesc );
448 item =
new QTableWidgetItem( triple );
449 item->setFlags( item->flags() ^ Qt::ItemIsEditable );
450 item->setToolTip( tdesc );
453 item =
new QTableWidgetItem( QString::number( drpm ) );
454 item->setFlags( item->flags() ^ Qt::ItemIsEditable );
455 item->setToolTip( tdesc );
458 item =
new QTableWidgetItem( QString::number( js ) );
459 item->setFlags( item->flags() ^ Qt::ItemIsEditable );
460 item->setToolTip( tdesc );
471 scedits[ jsscn ].edited =
false;
472 DbgLv(1) <<
" jsscn jd js" << jsscn << jd << js
482 DbgLv(1) <<
" LD: setup_runfit";
484 DbgLv(1) <<
" LD: assign_scanfit";
487 DbgLv(1) <<
" LD: update_limit";
493 connect(
tw_equiscns, SIGNAL( itemDoubleClicked( QTableWidgetItem* ) ),
495 connect(
tw_equiscns, SIGNAL( itemSelectionChanged( ) ),
498 te_status->setText( tr(
"To edit (exclude points): Ctrl-click-hold,"
499 " move, and release mouse button in the plot area;"
500 " then release Ctrl key." ) );
519 qApp->processEvents();
523 {
DbgLv(1) <<
"VIEW_REPORT()"; }
537 equil_plot->setTitle( tr(
"Experiment Equilibrium Data" ) );
547 connect(
tw_equiscns, SIGNAL( itemDoubleClicked( QTableWidgetItem* ) ),
549 connect(
tw_equiscns, SIGNAL( itemSelectionChanged( ) ),
556 DbgLv(1) <<
"SCAN_DIAGS()";
567 for (
int jes = 0; jes <
scedits.size(); jes++ )
584 DbgLv(1) <<
"CHECK_SCAN_FIT()";
592 DbgLv(1) <<
" CkScFit: modelx crit" <<
modelx << crit;
599 DbgLv(1) <<
"CONC_HISTOGRAM()";
607 DbgLv(1) <<
"RESET_SCAN_LIMS()";
621 {
DbgLv(1) <<
"LOAD_MODEL()"; }
624 DbgLv(1) <<
"NEW_PROJECT_NAME()" << newpname;
631 DbgLv(1) <<
"SELECT_MODEL()";
637 DbgLv(1) <<
" modelx" <<
modelx <<
" nbr aud params" << na;
646 if(na==4)
DbgLv(1) <<
" par1-4: " << aud_params[0] << aud_params[1]
647 << aud_params[2] << aud_params[3];
664 DbgLv(1) <<
"MODEL_CONTROL()";
683 connect(
emodctrl, SIGNAL( update_scan(
int ) ),
692 DbgLv(1) <<
"FITTING_CONTROL()";
722 {
DbgLv(1) <<
"LOAD_FIT()"; }
724 {
DbgLv(1) <<
"MONTE_CARLO()"; }
728 DbgLv(1) <<
"FLOAT_PARAMS()";
738 DbgLv(1) <<
"INIT_PARAMS()";
745 bool update_mw =
true;
747 for (
int ii = 0; ii <
scanfits.size(); ii++ )
748 if (
scanfits[ ii ].scanFit && fitx < 0 )
751 DbgLv(1) <<
"IP: fitx" << fitx;
756 QMessageBox::warning(
this, tr(
"Scan Fits" ),
757 tr(
"There are no scans to fit!\n\n"
758 "Please select one or more scans to be fitted." ) );
771 msgBox.setWindowTitle( tr(
"Molecular Weight" ) );
773 tr(
"Do you want to use the currently defined molecular"
774 " weight for the parameter\n"
775 "initialization or calculate a newly initialized"
776 " molecular weight?" ) );
777 msgBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No
778 | QMessageBox::Cancel );
779 msgBox.setButtonText( QMessageBox::Yes,
780 tr(
"New Molecular Weight" ) );
781 msgBox.setButtonText( QMessageBox::No,
782 tr(
"Current Molecular Weight" ) );
784 switch( msgBox.exec() )
786 case QMessageBox::Yes:
787 case QMessageBox::Default:
794 case QMessageBox::No:
799 case QMessageBox::Cancel:
804 DbgLv(1) <<
"IP: update_mw" << update_mw;
807 DbgLv(1) <<
"IP: em init_params call";
827 QString triple =
tw_equiscns->item( sscanx, 2 )->text();
828 double drpm =
tw_equiscns->item( sscanx, 3 )->text().toDouble();
833 bool found =
findData( triple, drpm, jdx, jrx );
840 connect(
ct_scselect, SIGNAL( valueChanged(
double ) ),
897 DbgLv(1) <<
"itemRowChanged";
904 int row = item->row();
905 bool fit = !
scanfits[ row ].scanFit;
906 bool excl =
scanfits[ row ].autoExcl;
909 DbgLv(1) <<
"TableItemDoubleClicked row col" << row << item->column();
935 while ( ++jrx <
dataList[ jdx ].speedData.size() )
938 if (
dataList[ jdx ].speedData[ jrx ].speed == drpm )
972 if ( jscan < iscan || jscan >= ( iscan + kscan ) )
974 QMessageBox::warning(
this, tr(
"Scan Problem" ),
975 tr(
"Scan %1 is not within speed data scan range: %2 for %3" )
976 .arg( jscan ).arg( iscan ).arg( kscan ) );
984 DbgLv(1) <<
"EdataPlot: radl radr" << radl << radr;
994 tr(
"Run: " ) + runID + tr(
" Edit: " ) + editID +
"\n" +
995 tr(
"Cell " ) + cell + tr(
", Channel " ) + chan +
996 tr(
", " ) + QString::number( drpm ) + tr(
" rpm, Scan " ) +
997 QString::number(
sscann ) );
999 tr(
"Absorbance (" ) + waveln + tr(
" nm)" ) );
1003 grid->enableYMin(
true );
1004 grid->enableY (
true );
1010 pick->setRubberBand( QwtPicker::CrossRubberBand );
1011 connect( pick, SIGNAL( cMouseDown(
const QwtDoublePoint& ) ),
1012 SLOT(
pMouseDown(
const QwtDoublePoint& ) ) );
1013 connect( pick, SIGNAL( cMouseUp(
const QwtDoublePoint& ) ),
1014 SLOT(
pMouseUp(
const QwtDoublePoint& ) ) );
1015 connect( pick, SIGNAL( cMouseDrag(
const QwtDoublePoint& ) ),
1032 DbgLv(1) <<
"EdataPlot: radl radr" << radl << radr
1036 rvec.fill( 0.0, nrpts );
1037 vvec.fill( 0.0, nrpts );
1038 double* ra =
rvec.data();
1039 double* va =
vvec.data();
1041 int isc = jscan - 1;
1044 double rhi = -9e+10;
1046 double vhi = -9e+10;
1049 for (
int jj = 0; jj < krpt; jj++ )
1053 if ( rv >= radl && rv <= radr )
1058 rlo =
min( rlo, rv );
1059 rhi =
max( rhi, rv );
1060 vlo =
min( vlo, vv );
1061 vhi =
max( vhi, vv );
1069 DbgLv(1) <<
"EdataPlot: ra0 rak" << ra[0] << ra[count-1];
1070 DbgLv(1) <<
"EdataPlot: va0 vak" << va[0] << va[count-1];
1071 DbgLv(1) <<
"EdataPlot: count" << count;
1074 double rpad = ( rhi - rlo ) * 0.05;
1075 double vpad = ( vhi - vlo ) * 0.05;
1082 equil_plot->setAxisScale( QwtPlot::xBottom, rlo, rhi );
1083 equil_plot->setAxisScale( QwtPlot::yLeft, vlo, vhi );
1086 sym.setStyle( QwtSymbol::Ellipse );
1087 sym.setPen ( QPen( Qt::blue ) );
1088 sym.setBrush( QBrush( Qt::yellow ) );
1092 curve->setStyle( QwtPlotCurve::NoCurve );
1093 curve->setSymbol( sym );
1094 curve->setData( ra, va, count );
1103 double* ru =
rvec.data();
1104 double* vu =
vvec.data();
1111 for (
int jj = 0; jj <
vecknt; jj++ )
1124 equil_plot->detachItems( QwtPlotItem::Rtti_PlotCurve );
1128 symu.setStyle( QwtSymbol::Ellipse );
1129 symu.setPen ( QPen( Qt::blue ) );
1130 symu.setBrush( QBrush( Qt::yellow ) );
1131 symu.setSize ( 10 );
1133 syme.setStyle( QwtSymbol::Ellipse );
1134 syme.setPen ( QPen( Qt::white ) );
1135 syme.setBrush( QBrush( Qt::red ) );
1136 syme.setSize ( 10 );
1139 curvu->setStyle( QwtPlotCurve::NoCurve );
1140 curvu->setSymbol( symu );
1142 curve->setStyle( QwtPlotCurve::NoCurve );
1143 curve->setSymbol( syme );
1149 countu = vecknt - counte;
1156 counte = vecknt - countu;
1161 curvu->setData( ru, vu, countu );
1162 curve->setData( re, ve, counte );
1239 int mcomp =
max( 4, ncomp );
1242 for (
int jes = 0; jes <
scedits.size(); jes++ )
1244 int jdx =
scedits[ jes ].dsindex;
1245 int jrx =
scedits[ jes ].speedx;
1246 int jsx =
scedits[ jes ].scannbr - 1;
1247 double radlo =
scedits[ jes ].rad_lo;
1248 double radhi =
scedits[ jes ].rad_hi;
1251 QString trip =
triples[ jdx ];
1252 QString chan = trip.section(
"/", 1, 1 ).simplified();
1254 if ( ! channs.contains( chan ) )
1277 scanfit.
cell = trip.section(
"/", 0, 0 ).simplified().toInt();
1278 scanfit.
channel = channs.indexOf( chan ) + 1;
1279 scanfit.
wavelen = trip.section(
"/", 2, 2 ).simplified().toInt();
1285 scanfit.
amp_vals.fill( 0.0, mcomp );
1287 scanfit.
amp_rngs.fill( 0.0, mcomp );
1288 scanfit.
amp_fits.fill(
true, mcomp );
1289 scanfit.
amp_bnds.fill(
false, mcomp );
1290 scanfit.
extincts.fill( 1.0, nintg );
1291 scanfit.
integral.fill( 0.0, nintg );
1293 for (
int jj = 0; jj < scanfit.
points; jj++ )
1303 DbgLv(1) <<
"AsnSF: points xvs0 xvsN" << scanfit.
points
1379 double dvrng = dvval * 0.2;
1396 for (
int ii = 0; ii < 4; ii++ )
1413 while ( ++r_index < l_index )
1415 if ( radius <= edat->radius( r_index ) )
1435 for (
int ii = 0; ii <
scanfits.size(); ii++ )
1438 int jdx =
scedits[ ii ].dsindex;
1439 double radhi =
scedits[ ii ].rad_hi;
1447 for (
int ii = 0; ii <
scanfits.size(); ii++ )
1449 int jdx =
scedits[ ii ].dsindex;
1450 double radhi =
scedits[ ii ].rad_hi;
1463 if ( scanfit.
yvs[ jj ] > odlim )
1482 for (
int ii = 0; ii <
scanfits.size(); ii++ )
1487 scanfits[ ii ].amp_fits[ jj ] =
true;
1499 for (
int ii = 0; ii <
scanfits.size(); ii++ )
1504 scanfits[ ii ].amp_fits[ jj ] =
false;