11 #include <qwt_legend.h>
14 #define round(x) floor( (x) + 0.5 )
18 const QString& dataDir,
19 const QStringList& cell_ch_wl )
22 setWindowTitle( tr(
"Details for Raw Data" ) );
25 QGridLayout*
main =
new QGridLayout(
this );
26 main->setSpacing ( 2 );
27 main->setContentsMargins( 2, 2, 2, 2 );
35 tr(
"Parameter Variation Throughout Run" ),
37 tr(
"RPM * 1000 / Temperature " ) +
DEGC );
43 QwtText axisTitle =
data_plot->axisTitle( QwtPlot::yLeft );
44 axisTitle.setText( tr(
"Time between Scans (min)" ) );
45 data_plot->setAxisTitle( QwtPlot::yRight, axisTitle );
48 grid->enableXMin(
false );
50 main->addLayout( plot, row, 0, 5, 6 );
54 QLabel* lb_dir =
us_label( tr(
"Data Directory:" ) );
55 main->addWidget( lb_dir, row, 0 );
58 le_dir->setReadOnly(
true );
59 le_dir->setText( dataDir );
60 main->addWidget( le_dir, row++, 1, 1, 5 );
63 QLabel* lb_desc =
us_label( tr(
"Description:" ) );
64 main->addWidget( lb_desc, row, 0 );
69 main->addWidget(
le_desc, row++, 1, 1, 5 );
72 QLabel* lb_runID =
us_label( tr(
"Run Identification:" ) );
73 main->addWidget( lb_runID, row, 0 );
76 lw_rpm->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
77 lw_rpm->setMinimumSize( 100, 50 );
78 main->addWidget(
lw_rpm, row, 2, 5, 2 );
81 lw_triples->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
88 main->addWidget(
le_runID, row++, 1 );
91 QLabel* lb_runLen =
us_label( tr(
"Length of Run:" ) );
92 main->addWidget( lb_runLen, row, 0 );
99 QLabel* lb_timeCorr =
us_label( tr(
"Time Correction:" ) );
100 main->addWidget( lb_timeCorr, row, 0 );
107 QLabel* lb_rotorSpeed =
us_label( tr(
"Avg. Rotor Speed:" ) );
108 main->addWidget( lb_rotorSpeed, row, 0 );
115 QLabel* lb_avgTemp =
us_label( tr(
"Avg. Temperature:" ) );
116 main->addWidget( lb_avgTemp, row, 0 );
123 QLabel* lb_tempCheck =
us_label( tr(
"Temperature Check:" ) );
124 main->addWidget( lb_tempCheck, row, 0 );
126 QHBoxLayout* box1 =
new QHBoxLayout;
127 box1->setAlignment( Qt::AlignCenter );
129 QHBoxLayout* box2 =
new QHBoxLayout;
130 box2->setAlignment( Qt::AlignCenter );
131 box2->setSpacing( 10 );
135 lb_green->setPalette( QPalette( QColor( 0, 0x44, 0 ) ) );
136 lb_green->setAutoFillBackground(
true );
137 lb_green->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
140 lb_red->setFixedSize(20, 16);
141 lb_red->setPalette( QPalette( QColor( 0x55, 0, 0 ) ) );
142 lb_red->setAutoFillBackground(
true );
143 lb_red->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
146 box2->addWidget(
lb_red );
147 box1->addLayout( box2 );
149 main->addLayout( box1, row, 1 );
151 QHBoxLayout* buttons =
new QHBoxLayout();
154 connect( pb_temp, SIGNAL( clicked() ), SLOT(
plot_temp() ) );
155 buttons->addWidget( pb_temp );
158 connect( pb_rpm, SIGNAL( clicked() ), SLOT(
plot_rpm() ) );
159 buttons->addWidget( pb_rpm );
161 QPushButton* pb_interval =
us_pushbutton( tr(
"Interval" ) );
162 connect( pb_interval, SIGNAL( clicked() ), SLOT(
plot_interval() ) );
163 buttons->addWidget( pb_interval );
166 connect( pb_all, SIGNAL( clicked() ), SLOT(
plot_combined() ) );
167 buttons->addWidget( pb_all );
170 connect( pb_close, SIGNAL( clicked() ), SLOT( close() ) );
171 buttons->addWidget( pb_close );
173 main->addLayout( buttons, row++, 2, 1, 4 );
175 timer =
new QTimer();
179 connect(
lw_triples, SIGNAL( currentRowChanged(
int ) ),
180 SLOT (
update (
int ) ) );
182 connect(
lw_rpm, SIGNAL( itemClicked ( QListWidgetItem* ) ),
191 if ( ! QDir( dir ).exists() )
195 for (
int i = 0; i <
triples.size(); i++ )
198 QString filename = dir +
"/rundetail." + triple +
".rundetail.svgz";
205 qDebug() << filename <<
"plot not saved";
220 last =
round( last );
221 int hours = (int)floor( last / 3600.0 );
222 int mins = (int)
round( ( last - hours * 3600.0 ) / 60.0 );
225 QString
h = ( hours == 1 ) ? tr(
"hour" ) : tr(
"hours" );
228 s.sprintf(
"%d %s %02d min", hours, h.toAscii().data(), mins ) );
231 double correction = 0.0;
240 double omega = ( M_PI / 30.0 ) * scan.
rpm;
246 correction /= scanCount;
247 int minutes = (int) correction / 60;
248 int seconds = (int) correction % 60;
250 le_timeCorr->setText( s.sprintf(
"%d min %02d sec", minutes, seconds ) );
261 int rpm = (int)
round( scan.
rpm / 100.0 ) * 100;
262 map.insert( rpm,
triples[ i ] +
" / " + QString::number( scanNumber ) );
269 QList< int > rpms =
map.uniqueKeys();
274 foreach( rpm, rpms ) s_rpms << QString::number( rpm ) +
" RPM";
275 lw_rpm->addItems( s_rpms );
278 for (
int i = 0; i <
triples.size(); i++ )
280 int scans =
dataList[ i ].scanData.size();
284 lw_triples->addItem( s.sprintf(
"All scans -- %d scans", scanCount ) );
314 le_avgTemp->setText( QString::number( temp / scanCount,
'f', 1 )
319 rpm =
round( rpm / 100.0 );
320 le_rotorSpeed->setText( QString::number( (
int)rpm * 100 ) +
" RPM" );
328 dt = ( temp_spread > dt ) ? temp_spread : dt;
335 QList< graphValue > values;
347 QVector< double > x( scanCount );
348 QVector< double > t( scanCount );
349 QVector< double > r( scanCount );
350 QVector< double > m( scanCount );
351 double prior_seconds = 0.0;
353 for (
int i = 0; i < scanCount; i++ )
356 t[ i ] = values[ i ].temperature;
357 r[ i ] = values[ i ].rpm / 1000.0;
361 m[ i ] = ( values[ i ].seconds - prior_seconds ) / 60.0;
363 prior_seconds = values[ i ].seconds;
366 draw_plot( x.constData(), t.constData(), r.constData(), m.constData(), scanCount );
373 lb_red ->setPalette( QPalette( QColor( 0x55, 0, 0 ) ) );
374 lb_green->setPalette( QPalette( Qt::green ) );
378 lb_red ->setPalette( QPalette( Qt::red ) );
379 lb_green->setPalette( QPalette( QColor( 0, 0x44, 0 ) ) );
381 if ( !
timer->isActive() )
timer->start( 1000 );
387 static bool bright =
true;
388 static const QPalette red( Qt::red );
389 static const QPalette darkRed( QColor( 0x55, 0, 0 ) );
392 lb_red->setPalette( darkRed );
394 lb_red->setPalette( red );
400 const double* r,
const double* m,
int count )
403 QwtText axisTitle =
data_plot->axisTitle( QwtPlot::yLeft );
405 data_plot->setAxisTitle ( QwtPlot::yRight, axisTitle );
406 data_plot->enableAxis ( QwtPlot::yRight,
false );
407 data_plot->setAxisAutoScale( QwtPlot::yLeft );
408 data_plot->setAxisScale ( QwtPlot::xBottom, 1.0, count );
409 data_plot->setAxisMaxMinor ( QwtPlot::xBottom, 0 );
414 axisTitle.setText( tr(
"Temperature " ) +
DEGC );
415 data_plot->setAxisTitle( QwtPlot::yLeft, axisTitle );
419 axisTitle.setText( tr(
"RPM * 1000" ) );
420 data_plot->setAxisTitle( QwtPlot::yLeft, axisTitle );
424 axisTitle.setText( tr(
"Time between Scans (min)" ) );
425 data_plot->setAxisTitle( QwtPlot::yLeft, axisTitle );
430 tr(
"RPM * 1000 / Temperature " ) +
DEGC );
431 data_plot->setAxisTitle( QwtPlot::yLeft, axisTitle );
433 axisTitle.setText( tr(
"Time between Scans (min)" ) );
434 data_plot->setAxisTitle( QwtPlot::yRight, axisTitle );
436 data_plot->enableAxis ( QwtPlot::yRight,
true );
437 data_plot->setAxisScale( QwtPlot::yLeft, 0.0, 60.0 );
442 data_plot->detachItems( QwtPlotItem::Rtti_PlotCurve );
446 sym.setStyle( QwtSymbol::Ellipse );
447 sym.setPen ( QPen( Qt::yellow ) );
448 sym.setBrush( Qt::white );
454 c1->setPen ( QPen( QBrush( Qt::yellow ), 2 ) );
455 c1->setSymbol( sym );
456 c1->setData ( x, t, count );
459 sym.setPen( QColor( Qt::green ) );
464 c2->setPen ( QPen( QBrush( Qt::green ), 2 ) );
465 c2->setSymbol ( sym );
466 c2->setData ( x, r, count );
469 sym.setPen( QColor( Qt::red ) );
475 c3->setPen ( QPen( QBrush( Qt::red ), 2 ) );
476 c3->setSymbol ( sym );
477 c3->setData ( &x[ 1 ], &m[ 1 ], count - 1 );
482 QwtLegend* legend =
new QwtLegend;
483 data_plot->insertLegend( legend, QwtPlot::BottomLegend );
484 legend->setFrameStyle( QFrame::Box | QFrame::Sunken );
486 QList< QWidget* > items = legend->legendItems();
488 QFont font = items[ 0 ]->font();
492 foreach( item, items ) item->setFont( font );
494 data_plot->insertLegend( legend, QwtPlot::BottomLegend );
504 if (
lw_triples->currentItem()->text().contains( tr(
"All" ) ) )
511 int scanCount = data->
scanData.size();
518 for (
int i = 0; i < scanCount; i++ )
520 temp += data->
scanData[ i ].temperature;
525 le_avgTemp->setText( QString::number( temp / scanCount,
'f', 1 )
530 rpm =
round( rpm / 100.0 );
531 le_rotorSpeed->setText( QString::number( (
int)rpm * 100 ) +
" RPM" );
533 double maxTemp = -1.0e99;
534 double minTemp = 1.0e99;
536 QVector< double > x( scanCount );
537 QVector< double > t( scanCount );
538 QVector< double > r( scanCount );
539 QVector< double > m( scanCount );
540 double prior_seconds = 0.0;
542 for (
int i = 0; i < scanCount; i++ )
551 r[ i ] = s->
rpm / 1000.0;
553 if ( i > 0 ) m[ i ] = ( s->
seconds - prior_seconds ) / 60.0;
563 draw_plot( x.constData(), t.constData(), r.constData(), m.constData(), scanCount );
568 qDebug() <<
"show_rpm_details";
569 QString sspeed = item->text();
570 QString msg = tr(
"The following scans have been measured at " )
573 qDebug() <<
" srd: msg" << msg;
574 QStringList sl = sspeed.split(
" " );
576 int rpm = sspeed.toInt();
577 qDebug() <<
" srd: sl" << sl <<
"rpm" << rpm <<
"np" << sl.count();
579 sl =
map.values( rpm );
584 bool isMwl = triple.split(
" / " ).size() < 3;
585 QString pcellCh =
"0/Z";
595 if ( value.startsWith( triple ) )
597 QStringList components = value.split(
" / " );
598 int lvx = components.size() - 1;
599 scans << components[ lvx ].toInt();
603 if ( scans.size() == 0 )
continue;
605 QStringList cellChWl = triple.split(
" / " );
606 QString cellCh = cellChWl[ 0 ] +
"/" + cellChWl[ 1 ];
607 qDebug() <<
" srd: ccw" << cellChWl <<
"ccwsz" << cellChWl.count();
608 qDebug() <<
" srd: pcellCh cellCh isMwl" << pcellCh << cellCh << isMwl;
610 if ( cellChWl.size() > 2 )
612 msg += tr(
"Cell: " ) + cellChWl[ 0 ]
613 + tr(
", Channel: " ) + cellChWl[ 1 ]
614 + tr(
", Wavelength: " ) + cellChWl[ 2 ]
615 + tr(
", Scan Count: " );
616 isMwl = ( isMwl || cellCh == pcellCh );
617 qDebug() <<
" srd: isMwl" << isMwl;
622 msg += tr(
"Cell: " ) + cellChWl[ 0 ]
623 + tr(
", Channel: " ) + cellChWl[ 1 ]
624 + tr(
", Scan Count: " );
627 msg += QString::number( scans.size() ) +
"\n";
631 bool have_avg =
false;
635 QFile filei( fname );
636 if ( filei.open( QIODevice::ReadOnly | QIODevice::Text ) )
638 QTextStream texti( &filei );
639 QString xtext = texti.readAll();
640 have_avg = xtext.contains(
"avg_speed" );
650 QMessageBox::information(
this,
651 tr(
"Speed Information" ), msg );
654 msg += tr(
"\nYou may \"Close\" this dialog or click \"Details\""
655 " to open a text dialog showing speed details"
658 msgbox.setIcon( QMessageBox::Information );
659 msgbox.setText( tr(
"Speed Information" ) );
660 msgbox.setInformativeText( msg );
661 msgbox.addButton( tr(
"Details" ), QMessageBox::AcceptRole );
662 msgbox.addButton( tr(
"Close" ), QMessageBox::RejectRole );
664 int sbutton = msgbox.exec();
665 qDebug() <<
"select button" << sbutton <<
"Rej(C) Acc(D)"
666 << QMessageBox::RejectRole << QMessageBox::AcceptRole;
668 if ( sbutton == QMessageBox::AcceptRole )
670 QMessageBox::information(
this,
"DEBUG",
"you clicked DETAILS" );
673 QMessageBox::information(
this,
"DEBUG",
"you clicked CLOSE" );
709 QFile filei( fname );
710 qDebug() <<
" srd:mSI: rpm fname" << rpm << fname;
715 if ( filei.open( QIODevice::ReadOnly | QIODevice::Text ) )
717 QXmlStreamReader xmli( &filei );
719 while ( ! xmli.atEnd() )
722 qDebug() <<
" srd:mSI: xml name" << xmli.name();
724 if ( xmli.isStartElement() && xmli.name() ==
"speedstep" )
726 QXmlStreamAttributes attr = xmli.attributes();
727 double rpm_x = attr.value(
"rotorspeed" ).toString().toDouble();
729 qDebug() <<
" srd:mSI: rpm_x" << rpm_x;
731 if ( qAbs( rpm_x - rpm ) < 200.0 )
733 rpm_s = attr.value(
"set_speed" ).toString().toDouble();
734 rpm_a = attr.value(
"avg_speed" ).toString().toDouble();
735 rpm_d = attr.value(
"speed_stddev" ).toString().toDouble();
736 qDebug() <<
" srd:mSI:M: rpm_s rpm_a rpm_d" << rpm_s << rpm_a << rpm_d;
744 qDebug() <<
" srd:mSI: rpm_s rpm_a rpm_d" << rpm_s << rpm_a << rpm_d;
748 int rpm_fe = qRound( rpm_a );
749 msg = tr(
"\nSpeed step additional information:"
750 "\n Set Speed = %1 ;"
751 "\n Average Speed = %2 ;"
752 "\n Speed Standard Deviation = %3 ;"
753 "\n Finite Element Rotor Speed = %4 ." )
754 .arg( rpm_s ).arg( rpm_a ).arg( rpm_d ).arg( rpm_fe );
757 msg=
"\n*** MWL but no extended speedstep values ***";