3 #include <QApplication>
28 int main(
int argc,
char* argv[] )
30 QApplication application( argc, argv );
38 return application.exec();
44 setWindowTitle( tr(
"2-Dimensional Spectrum Analysis" ) );
45 setObjectName(
"US_2dsa" );
54 QLabel* lb_analysis =
us_banner( tr(
"Analysis Controls" ) );
55 QLabel* lb_scan =
us_banner( tr(
"Scan Control" ) );
57 QLabel* lb_status =
us_label ( tr(
"Status\nInfo:" ) );
59 QLabel* lb_from =
us_label ( tr(
"Scan focus from:" ) );
60 QLabel* lb_to =
us_label ( tr(
"to:" ) );
66 connect(
ct_from, SIGNAL( valueChanged(
double ) ),
68 connect(
ct_to, SIGNAL( valueChanged(
double ) ),
84 widg ->setVisible(
false );
87 ct_to ->setVisible(
true);
102 QLabel* lb_vari =
us_label ( tr(
"Variance:" ) );
104 QLabel* lb_rmsd =
us_label ( tr(
"RMSD:" ) );
130 te_status->setAlignment( Qt::AlignCenter | Qt::AlignVCenter );
132 "Solution not initiated...\n"
134 "Variance: 0.000000e-05 .\n"
138 connect(
pb_help, SIGNAL( clicked() ), SLOT(
help() ) );
139 connect(
pb_view, SIGNAL( clicked() ), SLOT(
view() ) );
140 connect(
pb_save, SIGNAL( clicked() ), SLOT(
save() ) );
149 ct_to ->setEnabled(
false );
156 rbd_pos = this->pos() + QPoint( 100, 100 );
157 epd_pos = this->pos() + QPoint( 400, 200 );
158 acd_pos = this->pos() + QPoint( 500, 50 );
167 if ( updflag == (-1) )
177 qApp->processEvents();
181 if ( updflag == (-2) )
192 QString avari = mdesc.mid( mdesc.indexOf(
"VARI=" ) + 5 );
193 double vari = avari.section(
" ", 0, 0 ).toDouble();
194 double rmsd = sqrt( vari );
195 le_vari->setText( QString::number( vari ) );
196 le_rmsd->setText( QString::number( rmsd ) );
197 DbgLv(1) <<
"Analysis Done VARI" << vari <<
"model,noise counts"
200 qApp->processEvents();
206 bool plotdata = updflag == 1;
207 bool savedata = updflag == 2;
209 DbgLv(1) <<
"Analysis Done" << updflag;
211 DbgLv(1) <<
" edat0 sdat0 rdat0 tnoi0"
259 query <<
"get_experiment_info_by_runID"
267 idExp = dbP->
value( 1 ).toInt();
271 DbgLv(1) <<
"SS: ss0 w2tfirst w2tlast timefirst timelast"
281 DbgLv(1) <<
"LD: expf path" << expfpath;
282 QFile xfi( expfpath )
284 if ( xfi.open( QIODevice::ReadOnly ) )
286 QXmlStreamReader xmli( &xfi );
288 while ( ! xmli.atEnd() )
292 if ( xmli.isStartElement() && xmli.name() ==
"speedstep" )
297 DbgLv(1) <<
"LD: sp: rotspeed" << sp.rotorspeed <<
"t1" << sp.time_first;
313 DbgLv(1) <<
"LD:sp: nesc nssp nssc" << nesc << nssp << nssc;
314 DbgLv(1) <<
"LD:sp: etm1 etm2 eom1 eom2" << etm1 << etm2 << eom1 << eom2;
320 DbgLv(1) <<
"LD:sp: stm1 stm2 som1 som2" << stm1 << stm2 << som1 << som2; }
331 DbgLv(1) <<
"Data Plot by Base";
333 DbgLv(1) <<
"Data Plot from Base";
337 ct_to ->setEnabled(
true );
346 int count = ( npoints > nscans ) ? npoints : nscans;
348 QVector< double > rvec( count, 0.0 );
349 QVector< double > vvec( count, 0.0 );
350 double* ra = rvec.data();
351 double* va = vvec.data();
354 QPen pen_red( Qt::red );
355 QPen pen_cyan( Qt::cyan );
356 QPen pen_plot( Qt::green );
366 for (
int ii = 0; ii < nscans; ii++ )
375 for (
int jj = 0; jj < npoints; jj++ )
386 title =
"SimCurve " + QString::number( ii );
388 cc->setPen( pen_red );
389 cc->setData( ra, va, kk );
398 data_plot1->setAxisTitle( QwtPlot::xBottom, tr(
"Radius (cm)" ) );
399 data_plot1->setAxisTitle( QwtPlot::yLeft, tr(
"OD Difference" ) );
404 for (
int jj = 0; jj < npoints; jj++ )
408 for (
int ii = 0; ii < nscans; ii++ )
412 for (
int jj = 0; jj < npoints; jj++ )
417 vari +=
sq( va[ jj ] );
422 title =
"resids " + QString::number( ii );
424 cc->setPen( pen_plot );
425 cc->setStyle( QwtPlotCurve::Dots );
426 cc->setData( ra, va, npoints );
429 data_plot1->setAxisAutoScale( QwtPlot::xBottom );
430 data_plot1->setAxisAutoScale( QwtPlot::yLeft );
441 cc->setPen( QPen( QBrush( Qt::red ), 2 ) );
442 cc->setData( ra, va, 2 );
445 data_plot1->setAxisScale( QwtPlot::xBottom, xlo, xhi );
449 vari /= (double)( kntva );
451 le_vari->setText( QString::number( vari ) );
453 DbgLv(1) <<
"Data Plot VARI" << vari;
461 QTextStream ts( &rtext );
482 QString analysisDate = QDateTime::currentDateTime().toUTC()
483 .toString(
"yyMMddhhmm" );
489 QString dates =
"e" + editID +
"_a" + analysisDate;
494 QString analysisType = QString( cusGrid ?
"2DSA-CG" :
"2DSA" )
495 + QString( fitMeni ?
"-FM" :
"" )
496 + QString( montCar ?
"-MC" :
"" );
497 QString requestID =
"local";
499 QString analysisID = dates +
"_" + analysisType +
"_" + requestID +
"_";
500 QString dext =
"." + tripleID;
501 QString dext2 =
".e" + editID +
"-" + dext.mid( 1 );
502 QString descbase = runID +
"." + tripleID +
"." + analysisID;
508 int nmodels =
models.size();
511 int nnoises = nmodels * knois;
514 QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
517 if ( !
mkdir( reppath, runID ) )
519 qDebug() <<
"*** Unable to create or find the report directory ***";
525 qDebug() <<
"*** Unable to create or find the model directory ***";
531 qDebug() <<
"*** Unable to create or find the noise directory ***";
539 QDir dirm( mdlpath );
540 QDir dirn( noipath );
543 QStringList mfilt(
"M*.xml" );
544 QStringList nfilt(
"N*.xml" );
545 QStringList mdnams = dirm.entryList( mfilt, QDir::Files, QDir::Name );
546 QStringList ndnams = dirn.entryList( nfilt, QDir::Files, QDir::Name );
550 QString mname =
"M0000000.xml";
551 QString nname =
"N0000000.xml";
561 mname =
"M" + QString().sprintf(
"%07i", indx++ ) +
".xml";
562 if ( ! mdnams.contains( mname ) )
565 if ( ++kmodels >= nmodels )
574 nname =
"N" + QString().sprintf(
"%07i", indx++ ) +
".xml";
575 if ( ! ndnams.contains( nname ) )
578 if ( ++knoises >= nnoises )
588 for (
int jj = 0; jj < nmodels; jj++ )
592 double variance = mdesc.mid( mdesc.indexOf(
"VARI=" ) + 5 )
593 .section(
' ', 0, 0 ).toDouble();
596 QString iterID =
"i01";
597 int iterNum = jj + 1;
600 iterID.sprintf(
"mc%04d", iterNum );
604 meniscus = mdesc.mid( mdesc.indexOf(
"MENISCUS=" ) + 9 )
605 .section(
' ', 0, 0 ).toDouble();
606 iterID.sprintf(
"i%02d-m%05d", iterNum, qRound( meniscus * 10000 ) );
613 tmppath + mname.replace(
".model",
".mdl.tmp" ) :
614 mdlpath + mnames[ jj ];
628 if ( dbP == NULL || montCar )
645 nname = noipath + nnames[ kk++ ];
660 for (
int kk = 0; kk < nicount; kk++ )
661 noise_rmv.
values[ kk ] *= -1.0;
674 nname = noipath + nnames[ kk++ ];
689 for (
int kk = 0; kk < nicount; kk++ )
690 noise_rmv.
values[ kk ] *= -1.0;
699 mname = mdlpath + mnames[ 0 ];
705 QFile( tname ).rename( mname );
726 reppath = reppath +
"/" + runID +
"/";
727 respath = respath +
"/" + runID +
"/";
728 QString analybase = fitMeni ?
"2DSA-FM" : ( montCar ?
"2DSA-MC" :
"2DSA" );
729 QString analynode =
"/" + analybase +
".";
730 QString filebase = reppath + analybase + dext +
".";
731 QString htmlFile = filebase +
"report.html";
732 QString plot1File = filebase +
"velocity.svgz";
733 QString plot2File = filebase +
"residuals.png";
734 QString plot3File = filebase +
"rbitmap.png";
735 QString fitFile = filebase +
"fitmen.dat";
736 QString fresFile = respath +
"2dsa-fm" + dext2 +
".fitmen.dat";
737 QString dsinfFile = QString( filebase ).replace( analynode,
"/dsinfo." )
738 +
"dataset_info.html";
744 QFile rep_f( htmlFile );
746 if ( ! rep_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
749 QTextStream ts( &rep_f );
759 QString wmsg = tr(
"Wrote:\n" );
761 mname =
loadDB ? tnames[ 0 ] : mdlpath + mnames[ 0 ];
762 wmsg = wmsg + mname +
"\n";
766 nname = noipath + nnames[ 0 ];
767 wmsg = wmsg + nname +
"\n";
771 nname = noipath + nnames[ 1 ];
772 wmsg = wmsg + nname +
"\n";
776 if ( nmodels > 1 && ! montCar )
778 int kk = ( nmodels - 2 ) * ( knois + 1 );
779 wmsg = wmsg +
" ... ( "
780 + QString::number( kk ) + tr(
" files unshown )\n" );
782 mname = mdlpath + mnames[ kk ];
783 wmsg = wmsg + mname +
"\n";
788 nname = noipath + nnames[ kk++ ];
789 wmsg = wmsg + nname +
"\n";
793 nname = noipath + nnames[ kk ];
794 wmsg = wmsg + nname +
"\n";
800 wmsg = wmsg + htmlFile +
"\n"
804 QStringList repfiles;
815 QFile rep_f( fitFile );
816 QFile res_f( fresFile );
818 if ( rep_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
820 QTextStream ts( &rep_f );
823 wmsg = wmsg + fitFile +
"\n";
827 if ( res_f.open( QIODevice::WriteOnly | QIODevice::Text ) )
829 QTextStream ts( &res_f );
832 wmsg = wmsg + fresFile +
"\n";
836 wmsg = wmsg + dsinfFile +
"\n";
843 wmsg += tr(
"\nReport files were also saved to the database." );
846 QApplication::restoreOverrideCursor();
847 QMessageBox::information(
this, tr(
"Successfully Written" ), wmsg );
880 rbd_pos = this->pos() + QPoint( 100, 100 );
896 epd_pos = this->pos() + QPoint( 400, 200 );
907 if ( drow < 0 )
return;
913 double buoy = 1.0 - vbar20 *
DENS_20W;
917 QMessageBox::critical(
this, tr(
"Negative Buoyancy Implied" ),
918 tr(
"The current vbar20 value (%1) implies a buoyancy\n"
919 "value (%2) that is non-positive.\n\n"
920 "2DSA cannot proceed with this value. Click on the\n"
921 "<Solution> button and change the vbar20 value.\n"
922 "Note that the Solution may be accepted without being saved.\n"
923 "Include negative values in the sedimentation coefficient\n"
924 "range to represent floating data." ).arg( vbar20 ).arg( buoy ) );
936 <<
"manual" << sd.
manual <<
"vbar20" << vbar20;
957 dset.temperature = avTemp;
958 dset.vbar20 = vbar20;
959 dset.vbartb = vbartb;
963 DbgLv(1) <<
"Bottom" <<
dset.simparams.bottom <<
"rotorcoeffs"
964 <<
dset.simparams.rotorcoeffs[0] <<
dset.simparams.rotorcoeffs[1];
966 DbgLv(1) <<
"SimulationParameter --";
980 acd_pos = this->pos() + QPoint( 500, 50 );
985 qApp->processEvents();
999 if ( maDesc.startsWith( runID ) )
1001 maDesc = maDesc.section(
".", -2, -2 ).section(
"_", 1, -1 );
1006 QString adate =
"a" + QDateTime::currentDateTime().toUTC()
1007 .toString(
"yyMMddhhmm" );
1011 QString anType = QString( cusGrid ?
"2DSA-CG" :
"2DSA" )
1012 + QString( fitMeni ?
"-FM" :
"" )
1013 + QString( montCar ?
"-MC" :
"" );
1014 maDesc = adate +
"_" + anType +
"_local_i01";
1017 QString mstr =
"\n" +
indent( 4 )
1018 + tr(
"<h3>Data Analysis Settings:</h3>\n" )
1019 +
indent( 4 ) +
"<table>\n";
1021 mstr +=
table_row( tr(
"Model Analysis:" ),
1023 mstr +=
table_row( tr(
"Number of Components:" ),
1024 QString::number( ncomp ) );
1025 mstr +=
table_row( tr(
"Residual RMS Deviation:" ),
1026 QString::number(
rmsd ) );
1028 double sum_mw = 0.0;
1032 double mink = 1e+99;
1033 double maxk = -1e+99;
1034 double minv = 1e+99;
1035 double maxv = -1e+99;
1037 for (
int ii = 0; ii < ncomp; ii++ )
1050 bool cnstvb = ( ( maxk - mink ) / qAbs( maxk )
1051 > ( maxv - minv ) / qAbs( maxv ) );
1053 mstr +=
table_row( tr(
"Weight Average s20,W:" ),
1054 QString().sprintf(
"%6.4e", ( sum_s / sum_c ) ) );
1055 mstr +=
table_row( tr(
"Weight Average D20,W:" ),
1056 QString().sprintf(
"%6.4e", ( sum_D / sum_c ) ) );
1057 mstr +=
table_row( tr(
"W.A. Molecular Weight:" ),
1058 QString().sprintf(
"%6.4e", ( sum_mw / sum_c ) ) );
1059 mstr +=
table_row( tr(
"Total Concentration:" ),
1060 QString().sprintf(
"%6.4e", sum_c ) );
1063 mstr +=
table_row( tr(
"Constant Vbar at 20" ) +
DEGC +
":",
1064 QString().number( maxv ) );
1066 mstr +=
table_row( tr(
"Constant f/f0:" ),
1067 QString().number( maxk ) );
1069 mstr +=
indent( 4 ) +
"</table>\n\n";
1071 mstr +=
indent( 4 ) + tr(
"<h3>Distribution Information:</h3>\n" )
1072 +
indent( 4 ) +
"<table>\n";
1075 mstr +=
table_row( tr(
"Molecular Wt." ), tr(
"S Apparent" ),
1076 tr(
"S 20,W" ), tr(
"D Apparent" ),
1077 tr(
"D 20,W" ), tr(
"f / f0" ),
1078 tr(
"Concentration" ) );
1080 mstr +=
table_row( tr(
"Molecular Wt." ), tr(
"S Apparent" ),
1081 tr(
"S 20,W" ), tr(
"D Apparent" ),
1082 tr(
"D 20,W" ), tr(
"Vbar20" ),
1083 tr(
"Concentration" ) );
1099 for (
int ii = 0; ii < ncomp; ii++ )
1102 double perc = 100.0 * conc / sum_c;
1121 QString().sprintf(
"%10.4e", s_ap ),
1123 QString().sprintf(
"%10.4e", D_ap ),
1125 QString().sprintf(
"%10.4e", f_f0 ),
1126 QString().sprintf(
"%10.4e (%5.2f %%)", conc, perc ) );
1129 mstr +=
indent( 4 ) +
"</table>\n";
1137 int nmodels =
models.size();
1145 QString anType = montCar ?
"Monte Carlo" :
"Fit Meniscus";
1147 QString mstr =
"\n" +
indent( 4 )
1148 + tr(
"<h3>Multiple Model Settings:</h3>\n" )
1149 +
indent( 4 ) +
"<table>\n";
1151 mstr +=
table_row( tr(
"Number of Model Iterations:" ),
1152 QString::number( nmodels ) );
1153 mstr +=
table_row( tr(
"Iteration Analysis Type:" ), anType );
1157 QString mdesc =
models[ 0 ].description;
1158 QString mend1 = mdesc.mid( mdesc.indexOf(
"MENISCUS=" ) + 9 );
1160 QString mend2 = mdesc.mid( mdesc.indexOf(
"MENISCUS=" ) + 9 );
1162 double smenis = mend1.toDouble();
1163 double emenis = mend2.toDouble();
1164 double rmenis = emenis - smenis;
1165 mstr +=
table_row( tr(
"Meniscus Range:" ),
1166 QString::number( rmenis ) );
1167 mstr +=
table_row( tr(
"Base Experiment Meniscus:" ),
1168 QString::number( bmenis ) );
1169 mstr +=
table_row( tr(
"Start Fit Meniscus:" ),
1170 QString::number( smenis ) );
1171 mstr +=
table_row( tr(
"End Fit Meniscus:" ),
1172 QString::number( emenis ) );
1175 mstr +=
indent( 4 ) +
"</table>\n\n";
1177 mstr +=
indent( 4 ) + tr(
"<h3>Fit / Iteration Information:</h3>\n" )
1178 +
indent( 4 ) +
"<table>\n";
1182 tr(
"Iteration ID" ),
1190 for (
int ii = 0; ii < nmodels; ii++ )
1192 QString itnum = QString::number( ii + 1 ).rightJustified( 4,
'_' );
1193 QString mdesc =
models[ ii ].description;
1194 QString avari = mdesc.mid( mdesc.indexOf(
"VARI=" ) + 5 );
1195 double rmsd = sqrt( avari.section(
" ", 0, 0 ).toDouble() );
1196 QString armsd = QString().sprintf(
"%10.8f", rmsd );
1200 QString itID = QString().sprintf(
"i%04i", ii + 1 );
1201 mstr +=
table_row( itnum, itID, armsd );
1206 QString ameni = mdesc.mid( mdesc.indexOf(
"MENISCUS=" ) + 9 )
1207 .section(
" ", 0, 0 );
1208 mstr +=
table_row( itnum, ameni, armsd );
1212 mstr +=
indent( 4 ) +
"</table>\n";
1221 tr(
"2-Dimensional Spectrum Analysis" ),
1225 ts <<
indent( 2 ) +
"</body>\n</html>\n";
1236 QVector< double > resscn( npoints );
1237 QVector< QVector< double > > resids( nscans );
1239 for (
int ii = 0; ii < nscans; ii++ )
1243 for (
int jj = 0; jj < npoints; jj++ )
1250 resids[ ii ] = resscn;
1255 QPixmap pixmap = QPixmap::grabWidget( resbmap, 0, 0,
1256 resbmap->width(), resbmap->height() );
1259 if ( ! pixmap.save( plotFile ) )
1260 qDebug() <<
"*ERROR* Unable to write file" << plotFile;
1305 int nmodels =
models.size();
1310 for (
int ii = 0; ii < nmodels; ii++ )
1312 QString mdesc =
models[ ii ].description;
1313 QString avari = mdesc.mid( mdesc.indexOf(
"VARI=" ) + 5 );
1314 double rmsd = sqrt( avari.section(
" ", 0, 0 ).toDouble() );
1315 QString armsd = QString().sprintf(
"%10.8f", rmsd );
1316 QString ameni = mdesc.mid( mdesc.indexOf(
"MENISCUS=" ) + 9 )
1317 .section(
" ", 0, 0 );
1318 mstr += ( ameni +
" " + armsd +
"\n" );