3 #include <QApplication>
16 #define SEDC_NOVAL -9999.0
19 int main(
int argc,
char* argv[] )
21 QApplication application( argc, argv );
29 return application.exec();
37 setWindowTitle( tr(
"Enhanced van Holde - Weischet Analysis:" ) );
58 connect(
ck_modelpl, SIGNAL( toggled(
bool ) ),
60 connect(
ck_vhw_enh, SIGNAL( toggled(
bool ) ),
62 connect(
ck_use_fed, SIGNAL( toggled(
bool ) ),
64 connect(
pb_save, SIGNAL( clicked() ),
66 connect(
pb_view, SIGNAL( clicked() ),
78 QLabel* lb_analysis =
us_banner( tr(
"Analysis Controls" ) );
79 QLabel* lb_scan =
us_banner( tr(
"Scan Control" ) );
80 QLabel* lb_smoothing =
us_label ( tr(
"Data Smoothing:" ) );
81 QLabel* lb_boundPercent =
us_label ( tr(
"% of Boundary:" ) );
82 QLabel* lb_boundPos =
us_label ( tr(
"Boundary Position (%):" ) );
84 QLabel* lb_from =
us_label ( tr(
"Scan focus from:" ) );
85 QLabel* lb_to =
us_label ( tr(
"to:" ) );
88 lb_tolerance->setAlignment( Qt::AlignVCenter | Qt::AlignLeft );
98 lb_division->setAlignment( Qt::AlignVCenter | Qt::AlignLeft );
103 connect(
ct_division, SIGNAL( valueChanged(
double ) ),
126 connect(
pb_help, SIGNAL( clicked() ),
127 this, SLOT(
help() ) );
137 setMaximumSize( qApp->desktop()->size() - QSize( 80, 80 ) );
153 if (
dataList[ 0 ].expType ==
"Equilibrium" )
155 QMessageBox::warning(
this, tr(
"Wrong Data Type" ),
156 tr(
"You have selected Equilibrium data, which is not\n"
157 "appropriate for van Holde - Weischet analysis." ) );
161 le_id ->disconnect();
183 int mxht = qApp->desktop()->height() - bord;
184 int p1ht = ( mxht * 400 ) / 650;
185 int p2ht = mxht - p1ht;
186 p1ht = qMin( p1ht, 400 );
187 p2ht = qMin( p2ht, 250 );
188 DbgLv(1) <<
"vhw: mxht p1ht p2ht" << mxht << p1ht << p2ht;
191 data_plot2->setAxisAutoScale( QwtPlot::yLeft );
192 data_plot2->setAxisAutoScale( QwtPlot::xBottom );
195 gpick->setSelectionFlags( QwtPicker::PointSelection
196 | QwtPicker::ClickSelection );
197 connect(
gpick, SIGNAL( mouseDown(
const QwtDoublePoint& ) ),
198 this, SLOT(
groupClick(
const QwtDoublePoint& ) ) );
210 for (
int ii = 0; ii <
triples.size(); ii++ )
219 DbgLv(1) <<
"vhw: init: ii" << ii;
221 DbgLv(1) <<
"vhw: init: init'd simraw (s x p)"
223 DbgLv(1) <<
"vhw: init: copy'd simdat (s x p)"
226 for (
int jj = 0; jj < simdat.
scanCount(); jj++ )
228 for (
int kk = 0; kk < simdat.
pointCount(); kk++ )
240 connect(
ck_use_fed, SIGNAL( toggled(
bool ) ),
249 QVector< double > bfracs;
251 double pterm = 100.0 *
positPct + bterm;
252 int npoints =
dseds.size();
254 bfracs.resize( npoints );
256 for (
int jj = 0; jj < npoints; jj++ )
258 bfracs[ jj ] = pterm + bterm * (double)( jj );
262 dialog->move( this->pos() + QPoint( 100, 100 ) );
284 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
301 data_plot2->setAxisAutoScale( QwtPlot::yLeft );
302 data_plot2->setAxisAutoScale( QwtPlot::xBottom );
310 QVector< double > pyvec( totalCount );
311 double* ptx = pxvec.data();
312 double* pty = pyvec.data();
313 divfac = 1.0 / (double)divsCount;
317 kcalls[0]+=1;QDateTime sttime=QDateTime::currentDateTime();
369 int kk = divsCount * ii + jj;
370 double xv = ptx[ ii ];
371 double yv = pty[ kk ];
372 if ( xv > 0.0 && yv > 0.0 ) count++;
391 + tr(
"vHW Extrapolation Plot" ) );
393 data_plot1->setAxisTitle( QwtPlot::xBottom, tr(
"(Time)^-0.5" ) );
395 tr(
"Corrected Sed. Coeff. (1e-13 s)" ) );
398 QVector< double > xvec( nxy );
399 QVector< double > yvec( nxy );
400 double* x = xvec.data();
401 double* y = yvec.data();
405 sym.setStyle( QwtSymbol::Ellipse );
406 sym.setPen ( QPen( Qt::blue ) );
407 sym.setBrush( QBrush( Qt::white ) );
417 double xv = ptx[ ii ];
421 double yv = pty[ kk++ ];
422 if ( xv >= 0.0 && yv >= 0.0 )
426 xmax = ( xmax > xv ) ? xmax : xv;
434 tr(
"Sed Coeff Points, scan %1" ).arg( ii+1 ) );
436 curve->setStyle ( QwtPlotCurve::NoCurve );
437 curve->setSymbol( sym );
438 curve->setData ( x, y, count );
443 double intcept = 0.0;
453 kk = ii * divsCount + jj;
455 if ( ptx[ ii ] > 0.0 && pty[ kk ] > 0.0 )
457 x[ count ] = ptx[ ii ];
458 y[ count ] = pty[ kk ];
467 if(jj<3||jj>(divsCount-9))
468 DbgLv(1) <<
"plot2 jj count" << jj << count <<
" y0 yn" << y[0] << y[count-1];
475 x[ 1 ] = xmax + 0.001;
477 y[ 1 ] = y[ 0 ] + x[ 1 ] * slope;
482 x[ 1 ] = ( slope != 0.0 ? ( -y[ 0 ] / slope ) : xmax );
484 if(jj<3||jj>(divsCount-9))
485 DbgLv(1) <<
"plot2 jj" << jj <<
"x0 y0 x1 y1" << x[0] << y[0] << x[1] << y[1];
488 curve->setPen( QPen( Qt::yellow ) );
489 curve->setData( x, y, 2 );
495 xmax = (double)qRound( ( xmax + 0.0009 ) / 0.001 ) * 0.001;
496 ymax = (double)qRound( ( ymax + 0.3900 ) / 0.400 ) * 0.400;
498 data_plot1->setAxisAutoScale( QwtPlot::xBottom);
499 data_plot1->setAxisAutoScale( QwtPlot::yLeft );
505 x[ count ] =
bdrads.at( count );
506 y[ count ] =
bdcons.at( count );
507 DbgLv(2) <<
" bd x y k " << x[count] << y[count] << count+1;
513 for (
int ii = 0; ii < totalCount; ii++ )
518 dcurve->setPen( QPen( QBrush( Qt::red ), 3.0 ) );
519 dcurve->setData( x, y, count );
520 DbgLv(1) <<
" DP: xr0 yr0 " << x[0] << y[0];
521 DbgLv(1) <<
" DP: xrN yrN " << x[count-1] << y[count-1] << count;
529 QApplication::restoreOverrideCursor();
532 cd <<
"plot" <<
"divseds" <<
"sedc_int" <<
"fitplat" <<
"modplat"
533 <<
"clcstd" <<
"clcenh" <<
"avgplat" <<
"livscns" <<
"inipart"
534 <<
"updmid" <<
"divsed1" <<
"divsed2" <<
"divsed3" <<
"divsed4"
535 <<
"divsed5" <<
"sedcoeff" <<
"findroot" <<
"none" <<
"none";
536 kmsecs[0]+=sttime.msecsTo(QDateTime::currentDateTime());
537 for(
int mm=0;mm<20;mm++)
DbgLv(1) <<
"TIMINGS: mm" << mm
538 <<
"kcalls kmsecs" <<
kcalls[mm] <<
kmsecs[mm] << cd[mm];
547 tr(
"van Holde - Weischet Analysis" ),
edata );
550 ts <<
"\n" +
indent( 4 ) + tr(
"<h3>Selected Groups:</h3>\n" )
551 +
indent( 4 ) +
"<table>\n";
555 ts <<
table_row( tr(
"Groups Selected:" ), tr(
"NONE" ) );
559 ts <<
table_row( tr(
"Group:" ), tr(
"Average S:" ),
560 tr(
"Relative Amount:" ) );
564 for (
int jj = 0; jj < ngrp; jj++ )
567 QString().sprintf(
"%3d:", jj + 1 ),
568 QString().sprintf(
"%6.2f",
groupdat.at( jj ).sed ),
569 QString().sprintf(
"(%5.2f %%)",
groupdat.at( jj ).percent ) );
573 tsed = tsed / ( (double)ngrp * 100.0 );
577 ts <<
indent( 4 ) +
"</table>\n\n";
579 ts <<
indent( 4 ) +
"<br/><table>\n";
581 QString::number(
Swavg * 1.0e13 ) );
582 ts <<
table_row( tr(
"Initial Concentration from plateau fit:" ),
583 QString::number(
C0 ) + tr(
" OD/fringes" ) );
584 ts <<
indent( 4 ) +
"</table>\n";
592 double* x = xvec.data();
593 double* y = yvec.data();
606 C0 = (
C0 == 0.0 ) ? ci :
C0;
608 ts <<
"\n" +
indent( 4 ) +
"<br/><table>\n";
609 ts <<
table_row( tr(
"Initial Concentration:" ),
610 QString::number( ci ) +
" OD" );
611 ts <<
table_row( tr(
"Correlation Coefficient:" ),
612 QString::number( cor ) );
613 ts <<
table_row( tr(
"Standard Deviation:" ),
614 QString::number( sig ) );
615 ts <<
table_row( tr(
"Initial Concentration from exponential fit:" ),
616 QString::number(
C0 ) +
" OD" );
617 ts <<
indent( 4 ) +
"</table>\n";
619 ts <<
" </body>\n</html>\n";
625 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
626 QDateTime time0=QDateTime::currentDateTime();
629 QString tripl = QString(
triples.at(
row ) ).replace(
" / ",
"" );
631 +
"/vHW." + tripl +
".";
633 QStringList repfiles;
638 QString data0File = basernam +
"extrap.csv";
639 QString data1File = basernam +
"s-c-distrib.csv";
640 QString data2File = basernam +
"s-c-envelope.csv";
648 files << basernam +
"fef_model.rpt";
653 +
"/vHW." + tripl +
".";
654 QString htmlFile = basename +
"report.html";
655 QString plot1File = basename +
"velocity.svgz";
656 QString plot2File = basename +
"extrap.svgz";
657 QString plot3File = basename +
"s-c-distrib.svgz";
658 QString plot4File = basename +
"s-c-histo.svgz";
659 QString dsinfFile = QString( basename ).replace(
"/vHW.",
"/dsinfo." )
660 +
"dataset_info.html";
666 QFile rpt_f( htmlFile );
668 if ( !rpt_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
671 QTextStream ts( &rpt_f );
680 QVector< double > bfracs;
683 int npoints =
dseds.size();
684 bfracs.resize( npoints );
686 for (
int jj = 0; jj < npoints; jj++ )
689 bfracs[ jj ] = bfrac;
695 DbgLv(1) <<
"(P)PLOT ENV save: plot3File" << plot3File;
703 DbgLv(1) <<
"(T)PLOT ENV save: plot3File" << plot3File;
725 QString wmsg = tr(
"In directories\n%1,\n%2;\nwrote:\n\n" )
726 .arg( files[ 0 ].left( files[ 0 ].lastIndexOf(
"/" ) ) )
727 .arg( plot4File.left( plot4File.lastIndexOf(
"/" ) ) );
729 for (
int ii = 0; ii < files.size(); ii++ )
731 QString fname = files[ ii ];
732 fname = fname.mid( fname.lastIndexOf(
"/" ) + 1 );
733 wmsg +=
" " + fname +
"\n";
736 QDateTime time1=QDateTime::currentDateTime();
741 wmsg += tr(
"\nFiles were also saved to the database." );
743 QDateTime time2=QDateTime::currentDateTime();
744 int etim1=time0.msecsTo(time1);
745 int etim2=time1.msecsTo(time2);
746 int etimt=etim1+etim2;
747 int et1pc=(etim1*100)/etimt;
748 int et2pc=(etim2*100)/etimt;
749 DbgLv(1) <<
"SAVE-FILES: local ms" << etim1 <<
"=" << et1pc <<
"%";
750 DbgLv(1) <<
"SAVE-FILES: DB ms" << etim2 <<
"=" << et2pc <<
"%";
751 QApplication::restoreOverrideCursor();
753 QMessageBox::information(
this, tr(
"Successfully Written" ), wmsg );
761 QTextStream ts( &rtext );
766 edit->setWindowTitle(
"Results: van Holde - Weischet Analysis" );
767 edit->move( this->pos() + QPoint( 100, 100 ) );
768 edit->resize( 700, 600 );
771 edit->
e->setText( rtext );
781 pb_selegr->setText( tr(
"Select Groups" ) );
783 data_plot1->detachItems( QwtPlotItem::Rtti_PlotMarker );
792 pb_selegr->setText( tr(
"Clear Groups" ) );
795 QMessageBox::information(
this, tr(
"Group Selection" ),
796 tr(
"Please click first ABOVE, then BELOW the intercepts on the\n"
797 "Y-axis of the van Holde - Weischet extrapolation plot to\n"
798 "define groups and to average the S-values within a group.\n\n"
800 "This algorithm provides for multiple and also overlapping\n"
801 "groups, such that the total percentage may exceed 100%" ) );
842 QVector< double >& rvalues,
int valueCount,
int defndx )
848 if ( rvalues[ jj ] >= concenv )
859 QVector< double >& rvalues,
int valueCount )
861 return first_gteq( concenv, rvalues, valueCount, -1 );
868 kcalls[7]+=1;QDateTime sttime=QDateTime::currentDateTime();
875 for (
int jj = j1; jj < j2; jj++ )
878 plato /= (
double)( j2 - j1 );
881 kmsecs[7]+=sttime.msecsTo(QDateTime::currentDateTime());
888 double* radP,
int* ndxP )
891 kcalls[16]+=1;QDateTime sttime=QDateTime::currentDateTime();
897 if ( j2 >= 0 && oterm >= 0.0 )
907 double rra = av2 - av1;
908 rra = ( rra == 0.0 ) ? 0.0 : ( ( rv2 - rv1 ) / rra );
909 rv0 = rv1 + ( cconc - av1 ) * rra;
910 j2 = ( av2 - cconc ) > ( cconc - av1 ) ? j1 : j2;
926 if ( radP != NULL ) *radP = rv0;
927 if ( ndxP != NULL ) *ndxP = j2;
929 kmsecs[16]+=sttime.msecsTo(QDateTime::currentDateTime());
938 kcalls[1]+=1;QDateTime sttime=QDateTime::currentDateTime();
944 double* xx = xxv.data();
945 double* yy = yyv.data();
946 double* xr = xrv.data();
947 double* yr = yrv.data();
960 kcalls[11]+=1;QDateTime sttim1=QDateTime::currentDateTime();
972 DbgLv(1) <<
" ii nscnu" << ii << nscnu <<
" js lscnCount" << js <<
lscnCount;
977 timesqr = sqrt( timecor );
980 xx[ ii ] = 1.0 / timesqr;
1000 radD = bottom - ( 2.0 * xbdleft * bdifcsqr * timesqr );
1001 radD = qMax(
edata->
xvalues[ 0 ], qMin( bottom, radD ) );
1011 DbgLv(1) <<
"BD x,y " << nscnu+1 << radD << yr[nscnu] <<
" mm" << mm;
1012 DbgLv(1) <<
" ii nscnu" << ii << nscnu+1 <<
" bdsed radD yr"
1024 kmsecs[11]+=sttim1.msecsTo(QDateTime::currentDateTime());
1027 kcalls[12]+=1;QDateTime sttim2=QDateTime::currentDateTime();
1030 for (
int jj = 0; jj <
divsCount; jj++ )
1033 kcalls[13]+=1;QDateTime sttim3=QDateTime::currentDateTime();
1045 double rngjFact = rngFact * jj;
1046 double conjFact =
positPct + rngjFact;
1054 for (
int kk = 0; kk < nscnu; kk++ )
1067 mconc =
mconcs[ kk ][ jj ];
1072 pconc = baseline + range * conjFact;
1073 cpij = range * rngFact;
1074 mconc = pconc +
cpij * 0.5;
1081 yy[ kk ] =
sed_coeff( mconc, oterm, &radC, NULL );
1094 kmsecs[13]+=sttim3.msecsTo(QDateTime::currentDateTime());
1097 kcalls[14]+=1;QDateTime sttim4=QDateTime::currentDateTime();
1101 QVector< double > xtvec;
1102 QVector< double > ytvec;
1105 for (
int kk = 0; kk < kscnu; kk++ )
1114 DbgLv(1) <<
"KS +++ SED<=0.0 divjj" << jj <<
"scnkk ii" << kk << ii;
1117 double* xt = xtvec.data();
1118 double* yt = ytvec.data();
1119 DbgLv(1) <<
" KS" << kscnu << kscsv <<
"size xtv ytv" << xtvec.size()
1122 kmsecs[14]+=sttim4.msecsTo(QDateTime::currentDateTime());
1125 kcalls[15]+=1;QDateTime sttim5=QDateTime::currentDateTime();
1133 DbgLv(1) <<
" KS" << kscnu << kscsv <<
"jj" << jj <<
"xx0 xxn yy0 yyn" << xt[0]
1134 << xt[kscnu-1] << yt[0] << yt[kscnu-1] <<
"slo sed" << slope << dsed;
1144 ii=(kscnu<1)?1:kscnu;
1145 DbgLv(1) <<
" kscnu" << kscnu <<
"yy0 yyn " << yy[0] << yy[ii-1];
1154 DbgLv(1) <<
"JJ" << jj <<
"DSED" << dsed <<
"dseds size" <<
dseds.size();
1156 kmsecs[15]+=sttim5.msecsTo(QDateTime::currentDateTime());
1160 int kdivs =
dseds.size();
1161 int k3=qMax(0,kdivs-3);
1162 int k2=qMax(0,kdivs-2);
1163 int k1=qMax(0,kdivs-1);
1164 DbgLv(1) <<
" dsed[0] " <<
dseds[0] <<
"kdivs" << kdivs;
1168 DbgLv(1) <<
" D_S: xr0 yr0 " << xr[0] << yr[0];
1169 DbgLv(1) <<
" D_S: xrN yrN " << xr[nscnu-1] << yr[nscnu-1] << nscnu;
1174 for (
int kk = 0; kk < nscnu; kk++ )
1181 kmsecs[12]+=sttim2.msecsTo(QDateTime::currentDateTime());
1184 kmsecs[1]+=sttime.msecsTo(QDateTime::currentDateTime());
1194 kcalls[17]+=1;QDateTime sttime=QDateTime::currentDateTime();
1197 #define erfc(x) US_Math2::erfc(x)
1200 #define _FR_MXKNT 100 // Max find-root iteration count
1201 double tolerance = 1.0e-7;
1206 double xsqr = xv * xv;
1207 double rsqr_pi = 1.0 / sqrt( M_PI );
1208 double test = exp( -xsqr ) * rsqr_pi - ( xv * erfc( xv ) );
1209 test = ( goal != 0.0 ) ? test : 0.0;
1210 DbgLv(2) <<
" find_root: goal test" << goal << test <<
" xv" << xv;
1217 while ( fabs( test - goal ) > tolerance )
1219 xdiff = ( x2 - x1 ) / 2.0;
1235 test = ( 1.0 + 2.0 * xsqr ) * erfc( xv )
1236 - ( 2.0 * xv * exp( -xsqr ) ) * rsqr_pi;
1242 DbgLv(2) <<
" find_root: goal test" << goal << test
1243 <<
" xv" << xv <<
" count" << count;
1246 kmsecs[17]+=sttime.msecsTo(QDateTime::currentDateTime());
1254 double tempera =
le_temp->text().section(
" ", 0, 0 ).toDouble();
1255 double RT =
R * (
K0 + tempera );
1260 double bdcoef = RT / ( D1 * sqrt( D2 / D3 ) );
1262 DbgLv(1) <<
"BackDiffusion:";
1263 DbgLv(1) <<
" RT " << RT <<
" R K0 tempera " <<
R <<
K0 << tempera;
1264 DbgLv(1) <<
" D1 " << D1 <<
" viscosity AVO " << viscosity <<
AVOGADRO;
1265 DbgLv(1) <<
" D2 " << D2 <<
" sedc vbar " << sedc <<
vbar;
1267 DbgLv(1) <<
" bdiff_coef" << bdcoef <<
" = RT/(D1*sqrt(D2/D3))";
1274 QwtPlotMarker* marker;
1280 <<
"x y" << p.x() << p.y();
1299 marker =
new QwtPlotMarker;
1302 gbanner = tr(
"Group %1: %2 (%3%)" )
1303 .arg( ngroup ).arg( cgrdata.
sed ).arg( cgrdata.
percent );
1306 label.setColor( Qt::darkRed );
1307 label.setBackgroundBrush( QBrush( QColor( 255, 255, 255, 208 ) ) );
1308 label.setText( gbanner );
1310 marker->setValue( 0.0, cgrdata.
sed );
1311 marker->setLabel( label );
1312 marker->setLabelAlignment( Qt::AlignRight | Qt::AlignVCenter );
1327 int ngroup =
groupxy.size() / 4;
1328 int jg = ( ngroup - 1 ) * 4;
1338 grdat.
idivs.clear();
1339 int divsUsed =
dseds.size();
1341 for (
int jj = 0; jj < divsUsed; jj++ )
1343 double sed =
dseds[ jj ];
1344 double slope =
dslos[ jj ];
1345 double yh = sed + slope * grdat.
x1;
1346 double yl = sed + slope * grdat.
x2;
1348 if ( yh <= grdat.y1 && yl >= grdat.
y2 )
1350 grdat.
idivs.append( jj );
1369 QString dirname = dirres +
"/" +
edata->
runID;
1370 QString dirrept = dirrep +
"/" +
edata->
runID;
1372 QDir dirr( dirres );
1373 QDir dirp( dirrep );
1375 if ( ! dirr.exists( dirname ) )
1376 dirr.mkpath( dirname );
1378 if ( ! dirp.exists( dirrept ) )
1379 dirp.mkpath( dirrept );
1381 QString filename = dirname +
"/vHW."
1382 + QString(
triples.at(
row ) ).replace(
" / ",
"" ) +
".extrap.csv";
1384 QFile res_f( filename );
1388 const QString fsep(
"," );
1389 const QString eoln(
"\n" );
1390 const QString blnk(
"\"\"" );
1392 QString control = fsep;
1394 if ( !res_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
1398 DbgLv(1) <<
"WV: filename " << filename;
1400 QTextStream ts( &res_f );
1403 ts <<
"\"1/sqrt(t)\"" << fsep;
1405 for (
int jj = 0; jj <
divsCount; jj++ )
1407 QString line = QString().sprintf(
"\"D%03dSedCoef\"", jj + 1 );
1408 ts << line << ( jj < lastDiv ? fsep : eoln );
1412 for (
int ii = 0; ii <
lscnCount; ii++ )
1417 QString dat = QString().sprintf(
"\"%11.8f\"",
1419 dat.replace(
" ",
"" );
1420 ts << dat << control;
1424 for (
int jj = 0; jj <
divsCount; jj++ )
1426 sedc =
aseds[ kk++ ];
1429 dat = QString().sprintf(
"\"%8.5f\"", sedc );
1430 dat.replace(
" ",
"" );
1435 ts << dat << ( jj < lastDiv ? control : eoln );
1446 +
"/vHW." + QString(
triples.at(
row ) ).replace(
" / ",
"" )
1447 +
".s-c-distrib.csv";
1448 QFile res_f( filename );
1450 double pterm = 100.0 *
positPct + bterm;
1454 if ( !res_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
1458 DbgLv(1) <<
"WD: filename " << filename;
1461 QTextStream ts( &res_f );
1463 ts << tr(
"\"%Boundary\",\"Points\",\"Slope\",\"Intercept\","
1464 "\"Sigma\",\"Correlation\"\n" );
1466 for (
int jj = 0; jj <
dseds.size(); jj++ )
1468 bfrac = pterm + bterm * (double)( jj );
1471 "\"%9.2f\",\"%7d\",\"%12.6f\",\"%12.6f\",\"%12.6f\",\"%12.6f\"\n",
1474 dline.replace(
" ",
"" );
1485 +
"/vHW." + QString(
triples.at(
row ) ).replace(
" / ",
"" )
1487 QFile res_f( filename );
1490 if ( !res_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
1494 DbgLv(1) <<
"WM: filename " << filename;
1496 QTextStream ts( &res_f );
1498 ts <<
"*************************************\n";
1499 ts << tr(
"* Please do not edit this file! *\n" );
1500 ts <<
"*************************************\n\n\n";
1501 ts <<
"3 " << tr(
"\t# Fixed Molecular Weight Distribution\n" );
1502 ts << groups <<
" " << tr(
"\t# Number of Components\n" );
1503 ts <<
edata->
meniscus <<
" " << tr(
"\t# Meniscus in cm\n" );
1504 ts <<
"0.01 " << tr(
"\t# Meniscus range in cm\n" );
1505 ts <<
"0 " << tr(
"\t# Meniscus fitting control\n" );
1506 ts <<
baseline <<
" " << tr(
"\t# Baseline in OD\n" );
1507 ts <<
"0.01 " << tr(
"\t# Baseline range in OD\n" );
1508 ts <<
"1 " << tr(
"\t# Baseline fitting control\n" );
1509 ts <<
"0.0000 " << tr(
"\t# Slope(r) Correction in OD\n" );
1510 ts <<
"0.0000 " << tr(
"\t# Slope(r) Correction range in OD\n" );
1511 ts <<
"0 " << tr(
"\t# Slope(r) Correction fitting control\n" );
1512 ts <<
"0.0000 " << tr(
"\t# Slope(c,r) Correction in OD\n" );
1513 ts <<
"0.0000 " << tr(
"\t# Slope(c,r) Correction range in OD\n" );
1514 ts <<
"0 " << tr(
"\t# Slope(c,r) Correction fitting control\n");
1515 ts <<
"20 " << tr(
"\t# Delta_t in seconds\n" );
1516 ts <<
"0.001 " << tr(
"\t# Delta_t in cm\n" );
1518 QString line04 =
"1 \t" +
1519 tr(
"# Sedimentation Coefficient fitting control\n" );
1520 QString line05 =
"7.00e-07 \t" +
1521 tr(
"# Diffusion Coefficient in D\n" );
1522 QString line06 =
"7.00e-08 \t" +
1523 tr(
"# Diffusion Coefficient range in D\n" );
1524 QString line07 =
"1 \t" +
1525 tr(
"# Diffusion Coefficient fitting control\n" );
1526 QString line10 =
"0 \t" +
1527 tr(
"# Partial Concentration fitting control\n" );
1528 QString line11 =
"0.0000 \t" + tr(
"# Sigma\n" );
1529 QString line12 =
"0.0000 \t" + tr(
"# Sigma range\n" );
1530 QString line13 =
"0 \t" + tr(
"# Sigma fitting control\n" );
1531 QString line14 =
"0.0000 \t" + tr(
"# Delta\n" );
1532 QString line15 =
"0.0000 \t" + tr(
"# Delta range\n" );
1533 QString line16 =
"0 \t" + tr(
"# Delta fitting control\n" );
1534 QString line17 =
"1 \t" +
1535 tr(
"# Molecular Weight fitting control\n" );
1536 QString line18 =
"0 \t" +
1537 tr(
"# Part. Spec. Volume fitting control\n" );
1540 for (
int ii = 0; ii < groups; ii++ )
1542 double gsed =
groupdat.at( ii ).sed * 1.0e-13;
1543 double gcon =
groupdat.at( ii ).percent * cterm;
1545 ts << tr(
"Parameters for Component " ) << ( ii + 1 ) <<
":\n\n";
1547 << tr(
"\t# Sedimentation Coefficient in s\n" );
1548 ts << gsed / 10.0 <<
" "
1549 << tr(
"\t# Sedimentation Coefficient range in s\n" );
1550 ts << line04 << line05 << line06 << line07;
1552 << tr(
"\t# Partial Concentration in OD\n" );
1553 ts << gcon / 10.0 <<
" "
1554 << tr(
"\t# Partial Concentration range in OD\n" );
1555 ts << line10 << line11 << line12 << line13;
1556 ts << line14 << line15 << line16 << line17 << line18;
1565 int mins = (int)( seconds / 60.0 );
1566 int secs = (int)( seconds - (
double)mins * 60.0 );
1570 QString tmin = QString().sprintf(
"%4d", mins );
1571 QString tsec = QString().sprintf(
"%3d", secs );
1572 return tr(
"%1 min %2 sec" ).arg( tmin ).arg( tsec );
1575 else if ( type == 1 )
1577 return tr(
"%1 minutes(s) %2 second(s)" ).arg( mins ).arg( secs );
1582 int hrs = (int)( seconds / 3600.0 );
1583 mins = qRound( ( seconds - (
double)hrs * 3600.0 ) / 60.0 );
1584 return tr(
"%1 hour(s) %2 minute(s)" ).arg( hrs ).arg( mins );
1604 int nfi = files.size();
1617 part = file.split(
"." );
1618 test = part[ 0 ] + part[ 3 ] + part[ 4 ] + part[ 5 ];
1621 for (
int ii = 1; ii < nfi; ii++ )
1626 part = file.split(
"." );
1627 test = part[ 0 ] + part[ 3 ] + part[ 4 ] + part[ 5 ];
1629 if ( QString::compare( test, ptest ) != 0 )
1631 ofiles.append( pfile );
1636 ofiles.append( file );
1654 for(
int mm=0;mm<20;mm++) {
kcalls[mm]=0;
kmsecs[mm]=0; }
1675 QMessageBox::warning(
this, tr(
"Bad Solution Values" ),
1676 tr(
"The Vbar for this data is not a positive value (vbar=%1).\n"
1677 "The current data set needs editing of its Solution before\n"
1678 "van Holde - Weischet analysis can proceed." ).arg(
vbar ) );
1688 QString tripl = QString(
triples.at( row ) ).replace(
" / ",
"" );
1689 QString dmsg =
te_desc->toPlainText() +
"\n";
1693 dmsg += tr(
"A model IS implied for %1" ).arg( tripl );
1700 dmsg += tr(
"NO model is implied for %1" ).arg( tripl );
1716 kcalls[2]+=1;QDateTime sttime=QDateTime::currentDateTime();
1720 double* xr = xrvec.data();
1721 double* yr = yrvec.data();
1725 for (
int ii = 0; ii <
lscnCount; ii++ )
1734 double mconc = basecut + cinc * 0.5;
1737 double oterm = timecor * omega *
omega;
1744 xr[ nscnu ] = 1.0 / sqrt( timecor );
1748 DbgLv(2) <<
" s-i: range baseline basecut platcut mconc" << range << baseline
1749 << basecut << platcut << mconc;
1761 DbgLv(1) <<
"sedco-intcp **SEDC**" << sedc <<
"x0 y0 xn yn n"
1762 << xr[0] << yr[0] << xr[nscnu-1] << yr[nscnu-1] << nscnu;
1763 DbgLv(1) <<
"sedco-intcp slope sigma" << slope << sigma;
1764 while ( (--nscnu) > 0 && sedc <= 0.0 )
1770 DbgLv(1) <<
"sedco-intcp ++SEDC++" << sedc << nscnu;
1774 kmsecs[2]+=sttime.msecsTo(QDateTime::currentDateTime());
1781 QString plot2File, QString data2File )
1784 QString tplot1File = tempbase +
"s-c-distrib.svgz";
1785 QString tplot2File = tempbase +
"s-c-histo.svgz";
1786 QString tdata2File = tempbase +
"s-c-envelope.csv";
1787 QString tplot3File = tempbase +
"s-c-distrib.png";
1788 QString tplot4File = tempbase +
"s-c-histo.png";
1789 QString plot3File = QString( plot1File ).section(
".", 0, -2 ) +
".png";
1790 QString plot4File = QString( plot2File ).section(
".", 0, -2 ) +
".png";
1792 QFile tfp1( tplot1File );
1793 QFile tfp2( tplot2File );
1794 QFile tfd2( tdata2File );
1795 QFile tfp3( tplot3File );
1796 QFile tfp4( tplot4File );
1798 if ( tfp1.exists() )
1800 if ( QFile( plot1File ).remove() )
1801 DbgLv(1) <<
"CDF: removed:" << plot1File;
1802 if ( tfp1.copy( plot1File ) )
1803 DbgLv(1) <<
"CDF: copied:" << tplot1File;
1806 if ( tfp2.exists() )
1808 if ( QFile( plot2File ).remove() )
1809 DbgLv(1) <<
"CDF: removed:" << plot2File;
1810 if ( tfp2.copy( plot2File ) )
1811 DbgLv(1) <<
"CDF: copied:" << tplot2File;
1814 if ( tfd2.exists() )
1816 if ( QFile( data2File ).remove() )
1817 DbgLv(1) <<
"CDF: removed:" << data2File;
1818 if ( tfd2.copy( data2File ) )
1819 DbgLv(1) <<
"CDF: copied:" << tdata2File;
1822 if ( tfp3.exists() )
1824 if ( QFile( plot3File ).remove() )
1825 DbgLv(1) <<
"CDF: removed:" << plot3File;
1826 if ( tfp3.copy( plot3File ) )
1827 DbgLv(1) <<
"CDF: copied:" << tplot3File;
1830 if ( tfp4.exists() )
1832 if ( QFile( plot4File ).remove() )
1833 DbgLv(1) <<
"CDF: removed:" << plot4File;
1834 if ( tfp4.copy( plot4File ) )
1835 DbgLv(1) <<
"CDF: copied:" << tplot4File;
1843 kcalls[3]+=1;QDateTime sttime=QDateTime::currentDateTime();
1846 DbgLv(1) <<
"FITTED_PLATEAUS";
1854 divfac = 1.0 / (double)divsCount;
1867 QVector< double > pyvec( totalCount );
1871 double* ptx = pxvec.data();
1872 double* pty = pyvec.data();
1873 double* csx = sxvec.data();
1874 double* csy = syvec.data();
1875 double* fsy = fyvec.data();
1878 QList< double > plats;
1887 DbgLv(1) <<
" Initial reliable (non-excluded) scan t,log(avg-plat):";
1889 for (
int ii = 0; ii <
lscnCount; ii++ )
1896 pty[ nrelp ] = log( plateau );
1899 DbgLv(1) << ptx[nrelp] << pty[nrelp];
1913 for (
int jj = 6; jj < nrelp; jj++ )
1917 csx[ kf ] = (double)jj;
1918 csy[ kf++ ] = slope;
1919 DbgLv(1) <<
"k,slope point: " << kf << jj << slope;
1927 DbgLv(1) <<
"3rd-ord poly fit coefs:" << coefs[0] << coefs[1] << coefs[2]
1930 for (
int jj = 0; jj < kf; jj++ )
1932 double xx = csx[ jj ];
1933 double yy = coefs[ 0 ] + coefs[ 1 ] * xx + coefs[ 2 ] * xx * xx
1934 + coefs[ 3 ] * xx * xx * xx;
1936 DbgLv(1) <<
" k,fit-slope point: " << jj << xx << yy <<
" raw slope" << csy[jj];
1940 double prevy = fsy[ 1 ];
1941 double dfac = 1.0 / qAbs( fsy[ kf - 1 ] - prevy );
1942 double prevd = ( prevy - fsy[ 0 ] ) * dfac;
1946 DbgLv(1) <<
"Fitted slopes derivative points:";
1947 for (
int jj = 2; jj < kf; jj++ )
1949 double currx = csx[ jj ];
1950 double curry = fsy[ jj ];
1951 double currd = ( curry - prevy ) * dfac;
1953 DbgLv(1) <<
" k" << jj <<
" x fslo" << currx << curry <<
" deriv" << currd;
1955 if ( currd == 0.0 ||
1956 ( currd > 0.0 && prevd < 0.0 ) ||
1957 ( currd < 0.0 && prevd > 0.0 ) )
1960 DbgLv(1) <<
" Z-CROSS jrelp" << jrelp;
1961 if (
dbg_level>=1 ) {
for (
int mm = jj + 1; mm < kf; mm++ ) {
1962 prevy = curry; prevd = currd;
1963 currx = csx[mm]; curry = fsy[mm];
1964 currd = ( curry - prevy ) * dfac;
1965 DbgLv(1) <<
" k cx cy cd pd" << mm << currx << curry << currd << prevd;
1970 if ( prevy < 0.0 && curry < prevy )
1976 DbgLv(1) <<
" KDECR>2 jrelp prevy curry" << jrelp << prevy << curry;
1990 DbgLv(1) <<
" JRELP" << jrelp <<
"KF" << kf;
1991 if ( jrelp < 0 || jrelp > ( kf - 2 ) )
1993 jrelp =
min( 2, ( kf - 1 ) );
1994 DbgLv(1) <<
" NO z-cross/k-decr, so default jrelp" << jrelp;
1999 krelp = (int)csx[ jrelp ];
2000 DbgLv(1) <<
" jrelp krelp" << jrelp << krelp;
2003 DbgLv(1) <<
" KRELP" << krelp <<
" slope intcp sigma"
2004 << slope << intcp << sigma;
2016 for (
int ii = 0; ii <
lscnCount; ii++ )
2023 DbgLv(1) <<
" jj scan plateau " << ii << ii+1 <<
scPlats[ii];
2026 kmsecs[3]+=sttime.msecsTo(QDateTime::currentDateTime());
2036 kcalls[4]+=1;QDateTime sttime=QDateTime::currentDateTime();
2053 for (
int ii = 0; ii <
lscnCount; ii++ )
2063 for (
int jj = 0; jj < ncomp; jj++ )
2067 double sval = sc->
s;
2068 cplat += ( conc * exp( oterm * sval ) );
2083 kmsecs[4]+=sttime.msecsTo(QDateTime::currentDateTime());
2101 kcalls[5]+=1;QDateTime sttime=QDateTime::currentDateTime();
2112 divfac = 1.0 / (double)divsCount;
2120 for (
int ii = 0; ii < totalCount; ii++ )
2129 for (
int ii = 0; ii <
lscnCount; ii++ )
2136 double timex = 1.0 / sqrt( timev );
2137 double bdrad =
bdrads.at( kl );
2138 double bdcon =
bdcons.at( kl++ );
2139 double divrad = 0.0;
2140 DbgLv(1) <<
"scn liv" << ii+1 << kl
2141 <<
" radius concen time" << bdrad << bdcon << timev;
2150 oterm = ( timev > 0.0 ) ? ( timev *
omega *
omega ) : -1.0;
2152 for (
int jj = 0; jj <
divsCount; jj++ )
2155 cconc = pconc + cinc;
2156 mconc = pconc + cinch;
2160 if ( divrad > bdrad )
2163 DbgLv(1) <<
"CPm: *excl* div" << jj+1 <<
" drad dcon " << divrad << mconc;
2165 DbgLv(1) <<
"CPm: ii jj" << ii << jj <<
"kk iSedc" << kk <<
sedc
2166 <<
"mconc divrad bdrad" << mconc << divrad << bdrad;
2173 kmsecs[5]+=sttime.msecsTo(QDateTime::currentDateTime());
2181 kcalls[6]+=1;QDateTime sttime=QDateTime::currentDateTime();
2199 divfac = 1.0 / (double)divsCount;
2208 double avdthr = 2.0e-5;
2210 while( iter <= mxiter )
2212 double avgdif = 0.0;
2214 DbgLv(1) <<
"iter mxiter " << iter << mxiter;
2220 int divsUsed =
dseds.size();
2224 for (
int ii = 0; ii <
lscnCount; ii++ )
2230 eterm = -2.0 * oterm /
correc;
2237 for (
int jj = 0; jj <
divsCount; jj++ )
2251 for (
int jj = 0; jj <
divsCount; jj++ )
2256 avgdif += qAbs(
sdiff );
2258 DbgLv(1) <<
" iter scn " << iter << ii+1 <<
" sumcpij span "
2265 avgdif /= (double)count;
2266 DbgLv(1) <<
" iter" << iter <<
" avg(abs(sdiff))" << avgdif;
2268 if ( avgdif < avdthr )
2270 DbgLv(1) <<
" +++ avgdif < avdthr (" << avgdif << avdthr <<
") +++";
2277 for (
int ii = 0; ii < totalCount; ii++ )
2286 for (
int ii = 0; ii <
lscnCount; ii++ )
2292 double timex = 1.0 / sqrt( timev );
2293 double bdrad =
bdrads.at( kl );
2294 double bdcon =
bdcons.at( kl++ );
2295 double divrad = 0.0;
2296 DbgLv(1) <<
"scn liv" << ii+1 << kl
2297 <<
" radius concen time" << bdrad << bdcon << timev;
2302 oterm = ( timev > 0.0 ) ? ( timev *
omega *
omega ) : -1.0;
2304 for (
int jj = 0; jj <
divsCount; jj++ )
2306 mconc =
mconcs[ ii ][ jj ];
2310 if ( divrad > bdrad )
2313 DbgLv(1) <<
" *excl* div" << jj+1 <<
" drad dcon " << divrad << mconc;
2321 kmsecs[6]+=sttime.msecsTo(QDateTime::currentDateTime());
2338 else if ( n_ri_noi > 0 )
2341 return ( ! modelGUID.isEmpty() && modelGUID.length() == 36 );
2350 int frsc = qRound(
ct_from->value() );
2351 int tosc = qRound(
ct_to ->value() );
2353 if ( tosc <= 0 )
return;
2356 QwtPlotItemList list =
data_plot1->itemList();
2357 for (
int ii = 0; ii < list.size(); ii++ )
2359 QwtPlotItem*
curve = list[ ii ];
2360 if ( curve->title().text().contains(
"Exclude Marker" ) )
2367 for (
int ii = 0; ii <
aseds.size(); ii++ )
2368 ymax = qMax( ymax,
aseds[ ii ] );
2369 frsc = ( frsc < 1 ) ? 1 : frsc;
2371 yy[ 1 ] = ymax - 0.1;
2373 for (
int ii = 0; ii <
lscnCount; ii++ )
2376 if ( ixsc < frsc )
continue;
2377 if ( ixsc > tosc )
break;
2383 tr(
"Scan %1 Exclude Marker" ).arg( ixsc ) );
2384 curve->setPen( QPen( QBrush( Qt::red ), 1.0 ) );
2385 curve->setData( xx, yy, 2 );
2392 double to =
ct_to->value();
2396 ct_to->disconnect();
2397 ct_to->setValue( from );
2399 connect(
ct_to, SIGNAL( valueChanged(
double ) ),
2415 DbgLv(1) <<
"(1)TO=" << to;
2416 double from =
ct_from->value();
2418 if ( from > to || from == 0 )
2420 DbgLv(1) <<
"(2)TO=" << to;
2424 else if ( to > 0.0 )
2427 connect(
ct_from, SIGNAL( valueChanged(
double ) ),
2429 DbgLv(1) <<
"(3)TO=" << to;
2435 DbgLv(1) <<
"(4)TO=" << to;
2442 DbgLv(1) <<
"(5)TO=" << to;
2447 DbgLv(1) <<
"(8)TO=" << to;
2449 DbgLv(1) <<
"(9)TO=" << to;
2457 kcalls[8]+=1;QDateTime sttime=QDateTime::currentDateTime();
2465 for (
int ii = 0; ii <
scanCount; ii++ )
2474 kmsecs[8]+=sttime.msecsTo(QDateTime::currentDateTime());
2482 kcalls[9]+=1;QDateTime sttime=QDateTime::currentDateTime();
2491 for (
int ii = 0; ii <
lscnCount; ii++ )
2493 QVector< double > div_pconcs;
2494 QVector< double > div_mconcs;
2501 for (
int jj = 0; jj <
divsCount; jj++ )
2504 div_mconcs << mconc;
2508 CPijs << div_pconcs;
2512 kmsecs[9]+=sttime.msecsTo(QDateTime::currentDateTime());
2520 kcalls[10]+=1;QDateTime sttime=QDateTime::currentDateTime();
2526 for (
int ii = 0; ii <
lscnCount; ii++ )
2531 for (
int jj = 0; jj <
divsCount; jj++ )
2533 cpij =
CPijs[ ii ][ jj ];
2534 mconc = bconc + cpij * 0.5;
2536 mconcs[ ii ][ jj ] = mconc;
2541 kmsecs[10]+=sttime.msecsTo(QDateTime::currentDateTime());
2556 DbgLv(1) <<
" cr.sim.: row dbP" <<
row << dbP;
2572 bool vari_vbar = ! cnst_vbar;
2583 for (
int ii = 0; ii < amodel.
components.size(); ii++ )
2597 DbgLv(1) <<
" cr.sim.: new astfem";
2599 DbgLv(1) <<
" cr.sim.: astfem calc";
2601 DbgLv(1) <<
" cr.sim.: astfem calc RTN";
2605 DbgLv(1) <<
" cr.sim.: sd 00 0m 0n l0 lm ln"
2606 << simraw.
value( 0, 0)
2607 << simraw.
value( 0,mm)
2608 << simraw.
value( 0,nn)
2609 << simraw.
value(ll, 0)
2610 << simraw.
value(ll,mm)
2611 << simraw.
value(ll,nn);
2635 QString dataType = tr(
"Absorbance" );
2636 if (
simda->
dataType ==
"RI" ) dataType = tr(
"Intensity" );
2637 if (
simda->
dataType ==
"WI" ) dataType = tr(
"Intensity" );
2638 if (
simda->
dataType ==
"IP" ) dataType = tr(
"Interference" );
2639 if (
simda->
dataType ==
"FI" ) dataType = tr(
"Fluorescence" );
2641 QString header = tr(
"Simulation Velocity Data for\n ") +
simda->
runID
2647 data_plot2->setAxisTitle( QwtPlot::yLeft, header );
2649 header = tr(
"Radius (cm) " );
2650 data_plot2->setAxisTitle( QwtPlot::xBottom, header );
2655 int scan_number = 0;
2656 int from = (int)
ct_from->value();
2657 int to = (int)
ct_to ->value();
2666 QVector< double > rvec( points );
2667 QVector< double > vvec( points );
2668 double* rr = rvec.data();
2669 double* vv = vvec.data();
2684 for (
int ii = 0; ii <
scanCount; ii++ )
2689 bool highlight = ( scan_number >= from && scan_number <= to );
2692 double lower_limit = baseline + range * positionPct;
2693 double upper_limit = lower_limit + range * boundaryPct;
2694 QString curvname = tr(
"Curve %1 " ).arg( ii );
2701 while ( jj < points && simsc->rvalues[ jj ] < lower_limit )
2714 title = curvname + tr(
"below range" );
2718 cc->setPen( QPen( Qt::red ) );
2720 cc->setPen( QPen( Qt::cyan ) );
2722 cc->setData( rr, vv, count );
2727 while ( jj < points && simsc->rvalues[ jj ] < upper_limit )
2737 title = curvname + tr(
"in range" );
2741 cc->setPen( QPen( Qt::red ) );
2745 cc->setData( rr, vv, count );
2750 while ( jj < points )
2760 title = curvname + tr(
"above range" );
2764 cc->setPen( QPen( Qt::red ) );
2766 cc->setPen( QPen( Qt::cyan ) );
2768 cc->setData( rr, vv, count );
2790 DbgLv(1) <<
"gMo: modelGUID" << modelGUID;
2791 if ( modelGUID.isEmpty() || modelGUID.length() != 36 ||
2792 ( ! mmodlGUID.isEmpty() && mmodlGUID == modelGUID ) )
2794 DbgLv(1) <<
"gMo: MODEL empty/matches IDln" << modelGUID.length()
2795 <<
"modID" << modelGUID <<
"mmoID" << mmodlGUID;
2807 DbgLv(1) <<
"gMo: loaded model: modelGUID" << modelGUID << mmodlGUID;