3 #include <QApplication>
28 int main(
int argc,
char* argv[] )
30 QApplication application( argc, argv );
38 return application.exec();
44 setWindowTitle( tr(
"Parametrically Constrained Spectrum Analysis" ) );
45 setObjectName(
"US_pcsa" );
53 QLabel* lb_analysis =
us_banner( tr(
"Analysis Controls" ) );
54 QLabel* lb_scan =
us_banner( tr(
"Scan Control" ) );
56 QLabel* lb_status =
us_label ( tr(
"Status\nInfo:" ) );
58 QLabel* lb_from =
us_label ( tr(
"Scan focus from:" ) );
59 QLabel* lb_to =
us_label ( tr(
"to:" ) );
75 connect(
ct_from, SIGNAL( valueChanged(
double ) ),
77 connect(
ct_to, SIGNAL( valueChanged(
double ) ),
92 widg->setVisible(
false );
94 ct_to ->setVisible(
true );
99 QLabel* lb_vari =
us_label ( tr(
"Variance:" ) );
101 QLabel* lb_rmsd =
us_label ( tr(
"RMSD:" ) );
127 te_status->setAlignment( Qt::AlignCenter | Qt::AlignVCenter );
129 "Solution not initiated...\n"
131 "Variance: 0.000000e-05 .\n"
135 connect(
pb_help, SIGNAL( clicked() ), SLOT(
help() ) );
136 connect(
pb_view, SIGNAL( clicked() ), SLOT(
view() ) );
137 connect(
pb_save, SIGNAL( clicked() ), SLOT(
save() ) );
147 ct_to ->setEnabled(
false );
154 rbd_pos = this->pos() + QPoint( 100, 100 );
155 epd_pos = this->pos() + QPoint( 400, 200 );
156 acd_pos = this->pos() + QPoint( 500, 50 );
165 if ( updflag == (-1) )
172 qApp->processEvents();
176 if ( updflag == (-2) )
179 QString avari = mdesc.mid( mdesc.indexOf(
"VARI=" ) + 5 );
180 double vari = avari.section(
" ", 0, 0 ).toDouble();
181 double rmsd = sqrt( vari );
182 le_vari->setText( QString::number( vari ) );
183 le_rmsd->setText( QString::number( rmsd ) );
184 DbgLv(1) <<
"Analysis Done VARI" << vari;
186 qApp->processEvents();
192 bool plotdata = updflag == 1;
193 bool savedata = updflag == 2;
195 DbgLv(1) <<
"Analysis Done";
199 DbgLv(1) <<
" edat0 sdat0 rdat0"
246 query <<
"get_experiment_info_by_runID"
254 idExp = dbP->
value( 1 ).toInt();
258 DbgLv(1) <<
"SS: ss0 w2tfirst w2tlast timefirst timelast"
268 DbgLv(1) <<
"LD: expf path" << expfpath;
269 QFile xfi( expfpath )
271 if ( xfi.open( QIODevice::ReadOnly ) )
273 QXmlStreamReader xmli( &xfi );
275 while ( ! xmli.atEnd() )
279 if ( xmli.isStartElement() && xmli.name() ==
"speedstep" )
284 DbgLv(1) <<
"LD: sp: rotspeed" << sp.rotorspeed <<
"t1" << sp.time_first;
302 DbgLv(1) <<
"Data Plot by Base";
304 DbgLv(1) <<
"Data Plot from Base";
308 ct_to ->setEnabled(
true );
317 int count = ( npoints > nscans ) ? npoints : nscans;
319 QVector< double > rvec( count, 0.0 );
320 QVector< double > vvec( count, 0.0 );
321 double* ra = rvec.data();
322 double* va = vvec.data();
325 QPen pen_red( Qt::red );
326 QPen pen_cyan( Qt::cyan );
327 QPen pen_plot( Qt::green );
337 for (
int ii = 0; ii < nscans; ii++ )
346 for (
int jj = 0; jj < npoints; jj++ )
357 title =
"SimCurve " + QString::number( ii );
359 cc->setPen( pen_red );
360 cc->setData( ra, va, kk );
369 data_plot1->setAxisTitle( QwtPlot::xBottom, tr(
"Radius (cm)" ) );
370 data_plot1->setAxisTitle( QwtPlot::yLeft, tr(
"OD Difference" ) );
374 for (
int jj = 0; jj < npoints; jj++ )
378 for (
int ii = 0; ii < nscans; ii++ )
382 for (
int jj = 0; jj < npoints; jj++ )
392 title =
"resids " + QString::number( ii );
394 cc->setPen( pen_plot );
395 cc->setStyle( QwtPlotCurve::Dots );
396 cc->setData( ra, va, npoints );
399 data_plot1->setAxisAutoScale( QwtPlot::xBottom );
400 data_plot1->setAxisAutoScale( QwtPlot::yLeft );
411 cc->setPen( QPen( QBrush( Qt::red ), 2 ) );
412 cc->setData( ra, va, 2 );
415 data_plot1->setAxisScale( QwtPlot::xBottom, xlo, xhi );
419 vari /= (double)( nscans * npoints );
421 le_vari->setText( QString::number( vari ) );
423 DbgLv(1) <<
"Data Plot VARI" << vari;
431 QTextStream ts( &rtext );
452 DbgLv(1) <<
"SV: IN";
453 QString analysisDate = QDateTime::currentDateTime().toUTC()
454 .toString(
"yyMMddhhmm" );
460 QString dates =
"e" + editID +
"_a" + analysisDate;
462 QString analysisType =
"PCSA";
465 if ( curvType.contains(
"Straight L" ) )
466 analysisType =
"PCSA-SL";
467 else if ( curvType.contains(
"Increasing Sig" ) )
468 analysisType =
"PCSA-IS";
469 else if ( curvType.contains(
"Decreasing Sig" ) )
470 analysisType =
"PCSA-DS";
471 else if ( curvType.contains(
"Horizontal L" ) )
472 analysisType =
"PCSA-HL";
473 else if ( curvType.contains(
"Second-Order" ) )
474 analysisType =
"PCSA-2O";
477 analysisType = analysisType +
"-TR";
480 analysisType = analysisType +
"-MC";
481 DbgLv(1) <<
"SV: analysisType" << analysisType;
483 QString requestID =
"local";
485 QString analysisID = dates +
"_" + analysisType +
"_" + requestID +
"_";
486 QString dext =
"." + tripleID;
487 QString dext2 =
".e" + editID +
"-" + dext.mid( 1 );
488 QString descbase = runID +
"." + tripleID +
"." + analysisID;
499 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
502 if ( !
mkdir( reppath, runID ) )
504 qDebug() <<
"*** Unable to create or find the report directory ***";
510 qDebug() <<
"*** Unable to create or find the model directory ***";
516 qDebug() <<
"*** Unable to create or find the noise directory ***";
522 QMessageBox::critical(
this, tr(
"Zero-Component Model" ),
523 tr(
"*ERROR* The model you are attempting to save\n"
524 "has no components. No data was saved." ) );
532 QDir dirm( mdlpath );
533 QDir dirn( noipath );
536 QStringList mfilt(
"M*.xml" );
537 QStringList nfilt(
"N*.xml" );
538 QStringList mdnams = dirm.entryList( mfilt, QDir::Files, QDir::Name );
539 QStringList ndnams = dirn.entryList( nfilt, QDir::Files, QDir::Name );
543 QString mname =
"M0000000.xml";
544 QString tname = mname;
545 QString nname =
"N0000000.xml";
554 mname =
"M" + QString().sprintf(
"%07i", indx++ ) +
".xml";
555 if ( ! mdnams.contains( mname ) )
558 DbgLv(1) <<
"SV: kmodels mciters" << kmodels << mciters <<
"mname" << mname;
560 if ( ++kmodels >= mciters )
564 DbgLv(1) <<
"SV: mnames size" << mnames.size();
570 nname =
"N" + QString().sprintf(
"%07i", indx++ ) +
".xml";
571 if ( ! ndnams.contains( nname ) )
574 if ( ++knoises >= knois )
582 DbgLv(1) <<
"SV: Pre-sum tno tni" << tino << tini <<
"rno rni" << rino << rini;
586 double variance =
mrecs[ 0 ].variance;
587 QString iterID =
"i01";
588 DbgLv(1) <<
"SV: variance" << variance;
594 mname = mdlpath + mnames[ 0 ];
613 DbgLv(1) <<
"SV: Post-wrdb tno tni"
619 DbgLv(1) <<
"SV: MC models mciters" << mciters;
620 for (
int jmc = 0; jmc < mciters; jmc++ )
622 iterID = QString().sprintf(
"mc%04d", jmc + 1 );
625 tname = tmppath + descbase + iterID +
".mdl.tmp";
631 DbgLv(1) <<
"SV: MC models jmc" << jmc <<
"write" << tname;
640 mname = mdlpath + mnames[ 0 ];
641 DbgLv(1) <<
"SV: MC models write complete mname" << mname;
642 QFile tfile( tname );
647 .replace(
".model.xml",
".model" )
648 .replace(
".mdl.tmp",
".model" );
651 DbgLv(1) <<
"SV: MC models write DB from tname" << tname;
656 tfile.rename( mname );
657 DbgLv(1) <<
"SV: MC models write Local by rename tname" << tname;
670 nname = noipath + nnames[ kk++ ];
672 DbgLv(1) <<
"SV: TI nicount" << nicount;
674 DbgLv(1) <<
"SV: Pre-sum tno tni"
684 qDebug() <<
"*ERROR* writing noise" << nname;
697 for (
int kk = 0; kk < nicount; kk++ )
698 noise_rmv.
values[ kk ] *= -1.0;
710 nname = noipath + nnames[ kk++ ];
712 DbgLv(1) <<
"SV: RI nicount" << nicount;
720 qDebug() <<
"*ERROR* writing noise" << nname;
733 for (
int kk = 0; kk < nicount; kk++ )
734 noise_rmv.
values[ kk ] *= -1.0;
741 DbgLv(1) <<
"SV: Post-write tno rno" << tino << rino;
749 reppath = reppath +
"/" + runID +
"/";
750 respath = respath +
"/" + runID +
"/";
751 QString filebase = reppath + analysisType + dext +
".";
752 QString htmlFile = filebase +
"report.html";
753 QString plot1File = filebase +
"velocity.svgz";
754 QString plot2File = filebase +
"residuals.png";
755 QString plot3File = filebase +
"rbitmap.png";
756 QString plot4File = filebase +
"mlines.png";
757 QString ptmp4File = tmppath +
"PCSA" + dext +
".mlines."
758 + QString::number( getpid() ) +
".png";
759 DbgLv(1) <<
"mlines ptmp4File" << ptmp4File;
762 QFile rep_f( htmlFile );
764 if ( ! rep_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
767 QTextStream ts( &rep_f );
776 QFile::remove( plot4File );
777 if ( QFile::copy ( ptmp4File, plot4File ) )
778 QFile::remove( ptmp4File );
781 QString wmsg = tr(
"Wrote:\n" );
782 wmsg += mname +
"\n";
786 nname = noipath + nnames[ 0 ];
787 wmsg = wmsg + nname +
"\n";
791 nname = noipath + nnames[ 1 ];
792 wmsg = wmsg + nname +
"\n";
797 wmsg = wmsg + htmlFile +
"\n"
802 QStringList repfiles;
813 wmsg += tr(
"\nReport files were also saved to the database." );
816 QApplication::restoreOverrideCursor();
817 QMessageBox::information(
this, tr(
"Successfully Written" ), wmsg );
852 rbd_pos = this->pos() + QPoint( 100, 100 );
857 connect(
resplotd, SIGNAL( destroyed ( QObject *) ),
870 epd_pos = this->pos() + QPoint( 400, 200 );
875 connect(
eplotcd, SIGNAL( destroyed ( QObject *) ),
883 if ( drow < 0 )
return;
889 double buoy = 1.0 - vbar20 *
DENS_20W;
893 QMessageBox::critical(
this, tr(
"Negative Buoyancy Implied" ),
894 tr(
"The current vbar20 value (%1) implies a buoyancy\n"
895 "value (%2) that is non-positive.\n\n"
896 "PCSA cannot proceed with this value. Click on the\n"
897 "<Solution> button and change the vbar20 value.\n"
898 "Note that the Solution may be accepted without being saved.\n"
899 "Include negative values in the sedimentation coefficient\n"
900 "range to represent floating data." ).arg( vbar20 ).arg( buoy ) );
925 dset.solute_type = ( atrx << 6 ) | ( atry << 3 ) | atrz;
929 dset.temperature = avTemp;
930 dset.vbar20 = vbar20;
931 dset.vbartb = vbartb;
934 DbgLv(1) <<
"Bottom" <<
dset.simparams.bottom <<
"rotorcoeffs"
935 <<
dset.simparams.rotorcoeffs[0] <<
dset.simparams.rotorcoeffs[1];
949 acd_pos = this->pos() + QPoint( 500, 50 );
954 connect(
analcd, SIGNAL( destroyed ( QObject *) ),
956 qApp->processEvents();
963 DbgLv(1) <<
"distrinfo: ncomp" << ncomp;
970 if ( maDesc.startsWith( runID ) )
972 maDesc = maDesc.section(
".", -2, -2 ).section(
"_", 1, -1 );
976 maDesc =
"a" + QDateTime::currentDateTime().toUTC()
977 .toString(
"yyMMddhhmm" ) +
"_PCSA_local_01";
980 QString mstr =
"\n" +
indent( 4 )
981 + tr(
"<h3>Data Analysis Settings:</h3>\n" )
982 +
indent( 4 ) +
"<table>\n";
984 mstr +=
table_row( tr(
"Model Analysis:" ),
986 mstr +=
table_row( tr(
"Number of Components:" ),
987 QString::number( ncomp ) );
988 mstr +=
table_row( tr(
"Residual RMS Deviation:" ),
989 QString::number(
rmsd ) );
996 double maxk = -1e+99;
998 double maxv = -1e+99;
1000 for (
int ii = 0; ii < ncomp; ii++ )
1013 bool cnstvb = ( ( maxk - mink ) / qAbs( maxk )
1014 > ( maxv - minv ) / qAbs( maxv ) );
1016 mstr +=
table_row( tr(
"Weight Average s20,W:" ),
1017 QString().sprintf(
"%6.4e", ( sum_s / sum_c ) ) );
1018 mstr +=
table_row( tr(
"Weight Average D20,W:" ),
1019 QString().sprintf(
"%6.4e", ( sum_D / sum_c ) ) );
1020 mstr +=
table_row( tr(
"W.A. Molecular Weight:" ),
1021 QString().sprintf(
"%6.4e", ( sum_mw / sum_c ) ) );
1022 mstr +=
table_row( tr(
"Total Concentration:" ),
1023 QString().sprintf(
"%6.4e", sum_c ) );
1026 mstr +=
table_row( tr(
"Constant Vbar at 20" ) +
DEGC +
":",
1027 QString().number( maxv ) );
1029 mstr +=
table_row( tr(
"Constant f/f0:" ),
1030 QString().number( maxk ) );
1032 mstr +=
indent( 4 ) +
"</table>\n\n";
1034 mstr +=
indent( 4 ) + tr(
"<h3>Distribution Information:</h3>\n" )
1035 +
indent( 4 ) +
"<table>\n";
1038 mstr +=
table_row( tr(
"Molecular Wt." ), tr(
"S Apparent" ),
1039 tr(
"S 20,W" ), tr(
"D Apparent" ),
1040 tr(
"D 20,W" ), tr(
"f / f0" ),
1041 tr(
"Concentration" ) );
1043 mstr +=
table_row( tr(
"Molecular Wt." ), tr(
"S Apparent" ),
1044 tr(
"S 20,W" ), tr(
"D Apparent" ),
1045 tr(
"D 20,W" ), tr(
"Vbar20" ),
1046 tr(
"Concentration" ) );
1061 for (
int ii = 0; ii < ncomp; ii++ )
1064 double perc = 100.0 * conc / sum_c;
1083 QString().sprintf(
"%10.4e", s_ap ),
1085 QString().sprintf(
"%10.4e", D_ap ),
1087 QString().sprintf(
"%10.4e", f_f0 ),
1088 QString().sprintf(
"%10.4e (%5.2f %%)", conc, perc ) );
1091 mstr +=
indent( 4 ) +
"</table>\n";
1101 QString mstr =
"\n" +
indent( 4 )
1102 + tr(
"<h3>Model Statistics:</h3>\n" )
1103 +
indent( 4 ) +
"<table>\n";
1105 for (
int ii = 0; ii <
model_stats.size(); ii += 2 )
1110 mstr +=
indent( 4 ) +
"</table>\n";
1119 QString hdr = tr(
"Parametrically Constrained Spectrum Analysis" )
1120 +
"<br/>( " + curvtype +
" )";
1123 hdr +=
"<br/>- Tihhonov Regularization";
1128 ts <<
indent( 2 ) +
"</body>\n</html>\n";
1139 QVector< double > resscn( npoints );
1140 QVector< QVector< double > > resids( nscans );
1142 for (
int ii = 0; ii < nscans; ii++ )
1146 for (
int jj = 0; jj < npoints; jj++ )
1153 resids[ ii ] = resscn;
1158 QPixmap pixmap = QPixmap::grabWidget( resbmap, 0, 0,
1159 resbmap->width(), resbmap->height() );
1162 if ( ! pixmap.save( plotFile ) )
1163 qDebug() <<
"*ERROR* Unable to write file" << plotFile;
1202 DbgLv(1) <<
"NTr: ti noise in minr,maxr"
1211 QString tripleID = (
edata != 0 )
1215 +
".mlines." + QString::number( getpid() ) +
".png";
1217 QFile tfile( ptmp4File );
1218 if ( tfile.exists() )
1221 DbgLv(1) <<
"pcsa: removed: " << ptmp4File;
1236 QString oname = o->objectName();
1239 if ( oname.contains(
"AnalysisControl" ) )
1241 else if ( oname.contains(
"ResidPlot" ) )
1243 else if ( oname.contains(
"PlotControl" ) )
1246 <<
"oname" << oname;