UltraScan III
us_predict1.cpp
Go to the documentation of this file.
1 
3 #include "us_predict1.h"
4 #include "us_constants.h"
5 #include "us_gui_settings.h"
6 #include "us_buffer_gui.h"
7 #include "us_choice.h"
8 #include "us_solution_gui.h"
9 #include "us_math2.h"
10 
11 #include "qwt_legend.h"
12 
14  const US_Analyte a_data,
15  int disk_access,
16  bool signal_wanted )
17  : US_WidgetsDialog( 0, 0 ),
18  allparams ( parm ),
19  base_analyte( a_data ),
20  access ( disk_access ),
21  signal ( signal_wanted )
22 {
25  mw = parm.mw;
26  ratio = parm.axial_ratio;
27  solution.density = parm.density;
29  solution.vbar20 = parm.vbar;
30  solution.vbar = parm.vbar + ( 4.25e-4 * ( temperature - 20.0 ) );
31 
32  double x = 1.1;
33 
34  // From: K.E. van Holde, Biophysical Chemistry, 2nd edition, chapter 4.1
35  // Calculate frictional ratio as a function of axial ratio
36  for ( int i = 0; i < ARRAYSIZE; i++, x += 0.1 )
37  {
38  prolate[ i ] = pow( x, -1.0 / 3.0 ) * sqrt( sq( x ) - 1.0 ) /
39  log( x + sqrt( sq( x ) - 1.0 ) );
40 
41  oblate[ i ] = sqrt( sq( x ) - 1.0 ) /
42  ( pow( x, 2.0 / 3.0 ) * atan( sqrt( sq( x ) - 1.0 ) ) );
43 
44  rod[ i ] = pow( 2.0 / 3.0, 1.0 / 3.0 ) * pow( x, 2.0 / 3.0 ) /
45  ( log( 2.0 * x ) - 0.3 );
46 
47  ratio_x[ i ] = x;
48  }
49 
50  setWindowTitle( tr( "Modeling s, D, and f from MW for 4 basic shapes" ) );
51  setPalette( US_GuiSettings::frameColor() );
52 
53  // Very light gray
54  QPalette gray = US_GuiSettings::editColor();
55  gray.setColor( QPalette::Base, QColor( 0xe0, 0xe0, 0xe0 ) );
56 
57  QBoxLayout* main = new QVBoxLayout( this );
58  main->setSpacing ( 2 );
59  main->setContentsMargins ( 2, 2, 2, 2 );
60 
61  QBoxLayout* top = new QHBoxLayout;
62 
63  QGridLayout* controls = new QGridLayout;
64  int c_row = 0;
65 
66  QPushButton* pb_solution = us_pushbutton( tr( "Select Solution" ) );
67  connect( pb_solution, SIGNAL( clicked() ), SLOT( get_solution() ) );
68  controls->addWidget( pb_solution, c_row++, 0, 1, 2 );
69 
70  // Basic values
71  if ( signal )
72  {
73  QLabel* lb_density = us_label( tr( "Density" ) );
74  controls->addWidget( lb_density, c_row, 0 );
75 
77  le_density = us_lineedit( QString::number( solution.density, 'f', 4 ) );
78  le_density->setPalette( gray );
79  le_density->setReadOnly( true );
80  controls->addWidget( le_density, c_row++, 1 );
81 
82  QLabel* lb_viscosity = us_label( tr( "Viscosity" ) );
83  controls->addWidget( lb_viscosity, c_row, 0 );
84 
86  le_viscosity = us_lineedit( QString::number( solution.viscosity, 'f', 4 ) );
87  le_viscosity->setPalette( gray );
88  le_viscosity->setReadOnly( true );
89  controls->addWidget( le_viscosity, c_row++, 1 );
90  }
91  else
92  {
93  QPushButton* pb_density = us_pushbutton( tr( "Density" ) );
94  connect( pb_density, SIGNAL( clicked() ), SLOT( get_buffer() ) );
95  controls->addWidget( pb_density, c_row, 0 );
96 
98  le_density->setText( QString::number( DENS_20W, 'f', 4 ) );
99  connect( le_density, SIGNAL( textChanged( const QString& ) ),
100  SLOT ( density ( const QString& ) ) );
101  controls->addWidget( le_density, c_row++, 1 );
102 
103  QPushButton* pb_viscosity = us_pushbutton( tr( "Viscosity" ) );
104  connect( pb_viscosity, SIGNAL( clicked() ), SLOT( get_buffer() ) );
105  controls->addWidget( pb_viscosity, c_row, 0 );
106 
108  le_viscosity->setText( QString::number( VISC_20W, 'f', 4 ) );
109  connect( le_viscosity, SIGNAL( textChanged( const QString& ) ),
110  SLOT ( viscosity ( const QString& ) ) );
111  controls->addWidget( le_viscosity, c_row++, 1 );
112  }
113 
114  QPushButton* pb_vbar = us_pushbutton( tr( "vbar (20" ) + DEGC + ")" );
115  connect( pb_vbar, SIGNAL( clicked() ), SLOT( get_peptide() ) );
116  controls->addWidget( pb_vbar, c_row, 0 );
117 
118  le_vbar = us_lineedit();
119  le_vbar->setText( QString::number( solution.vbar20, 'e', 4 ) );
120  connect( le_vbar, SIGNAL( textChanged( const QString& ) ),
121  SLOT ( vbar ( const QString& ) ) );
122  controls->addWidget( le_vbar, c_row++, 1 );
123 
124  QLabel* lb_mw = us_label( tr( "Molecular Weight:" ) );
125  controls->addWidget( lb_mw, c_row, 0 );
126 
127  le_mw = us_lineedit();
128  le_mw->setText( QString::number( mw, 'e', 3 ) );
129  connect( le_mw, SIGNAL( textChanged( const QString& ) ),
130  SLOT ( update_mw ( const QString& ) ) );
131  controls->addWidget( le_mw, c_row++, 1 );
132 
133  QLabel* lb_temperature = us_label(
134  tr( "Temperature (" ) + DEGC + tr( "):" ) );
135  controls->addWidget( lb_temperature, c_row, 0 );
136 
137  QLineEdit* le_temperature = us_lineedit();
138  le_temperature->setText( QString::number( temperature, 'f', 1 ) );
139 
140  if ( signal )
141  {
142  le_temperature->setReadOnly( true );
143  le_temperature->setPalette( gray );
144  }
145  else
146  {
147  connect( le_temperature, SIGNAL( textChanged( const QString& ) ),
148  SLOT ( degC ( const QString& ) ) );
149  }
150  controls->addWidget( le_temperature, c_row++, 1 );
151 
152  // Axial Ratio
153  QLabel* lb_axial = us_label( tr( "Axial Ratio:" ) );
154  controls->addWidget( lb_axial, c_row, 0 );
155 
156  le_axial = us_lineedit();
157  le_axial->setText( QString::number( ratio, 'f', 3 ) );
158  connect( le_axial, SIGNAL( editingFinished( void ) ),
159  SLOT ( update_ratio ( void ) ) );
160  controls->addWidget( le_axial, c_row++, 1 );
161 
162  // Information
163  QPalette p = US_GuiSettings::editColor();
164 
165  lb_info = us_banner(
166  tr( "Please select an axial ratio by\n"
167  "dragging the white bar with the\n"
168  "mouse to change the axial ratio" ) );
169  lb_info->setPalette( p );
170  controls->addWidget( lb_info, c_row, 0, 3, 2 );
171  c_row += 3;
172 
173  // Control buttons
174  QBoxLayout* buttons = new QHBoxLayout;
175 
176  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
177  connect( pb_help, SIGNAL( clicked() ), SLOT( help() ) );
178  buttons->addWidget( pb_help );
179 
180  QPushButton* pb_close = us_pushbutton( tr( "Close" ) );
181  connect( pb_close, SIGNAL( clicked() ), SLOT( close() ) );
182  buttons->addWidget( pb_close );
183 
184  QPushButton* pb_accept = us_pushbutton( tr( "Accept" ) );
185  connect( pb_accept, SIGNAL( clicked() ), SLOT( complete() ) );
186  buttons->addWidget( pb_accept );
187 
188  controls->addLayout( buttons, c_row++, 0, 1, 2 );
189 
190  top->addLayout ( controls );
191 
192  // Graph
193  plotLayout = new US_Plot( plot,
194  tr( "f/f0 Dependence on Axial Ratios" ),
195  tr( "Axial Ratio" ),
196  tr( "f / f0" ) );
197 
198  plot->setAxisScale(QwtPlot::xBottom, 0.0, 100.0 );
199  plot->setAxisScale(QwtPlot::yLeft , 1.0, 4.5 );
200  plot->setMinimumSize( 650, 350 );
201 
202 
203  pick = new US_PlotPicker( plot );
204  pick->setRubberBand( QwtPicker::VLineRubberBand );
205  connect( pick, SIGNAL( moved ( const QwtDoublePoint& ) ),
206  SLOT ( new_value( const QwtDoublePoint& ) ) );
207  connect( pick, SIGNAL( mouseDown( const QwtDoublePoint& ) ),
208  SLOT ( new_value( const QwtDoublePoint& ) ) );
209  connect( pick, SIGNAL( mouseUp ( const QwtDoublePoint& ) ),
210  SLOT ( mouseU ( const QwtDoublePoint& ) ) );
211 
212  QwtPlotGrid* grid = us_grid( plot );
213  grid->attach( plot );
214 
215  prolate_curve = us_curve( plot, tr( "Prolate Ellipsoid" ) );
216  prolate_curve->setPen ( QPen( QBrush( Qt::magenta ), 2.0 ) );
217  prolate_curve->setData( ratio_x, prolate, ARRAYSIZE );
218 
219  oblate_curve = us_curve( plot, tr( "Oblate Ellipsoid" ) );
220  oblate_curve ->setPen ( QPen( QBrush( Qt::yellow ), 2.0 ) );
221  oblate_curve ->setData( ratio_x, oblate, ARRAYSIZE );
222 
223  rod_curve = us_curve( plot, tr( "Long Rod" ) );
224  rod_curve->setPen( QPen( QBrush( Qt::cyan ), 2.0 ) );
225  rod_curve->setData( ratio_x, rod, ARRAYSIZE );
226 
227  vline_x[ 0 ] = ratio;
228  vline_x[ 1 ] = ratio;
229  vline_y[ 0 ] = 1.1;
230  vline_y[ 1 ] = 4.3;
231 
232  vline_curve = us_curve( plot, tr( "Axial Ratio" ) );
233  vline_curve->setPen ( QPen( QBrush( Qt::white ), 1.5 ) );
234  vline_curve->setData( vline_x, vline_y, 2 );
235 
236  QwtLegend* legend = new QwtLegend();
237  plot->insertLegend( legend, QwtPlot::BottomLegend, 0.1 );
238 
239  top->addLayout( plotLayout );
240  main->addLayout( top );
241 
242  QGridLayout* values = new QGridLayout;
243 
244  QLabel* titles[ 8 ];
245 
246  titles[ 0 ] = us_label( tr( "Model:" ) );
247  titles[ 1 ] = us_label( "s (sec)" );
248  titles[ 2 ] = us_label( "D (cm<sup>2</sup>/sec)" );
249  titles[ 3 ] = us_label( "f" );
250  titles[ 4 ] = us_label( "f / f0" );
251  titles[ 5 ] = us_label( "a (<span>&Aring;</span>)" );
252  titles[ 6 ] = us_label( "b (<span>&Aring;</span>)" );
253  titles[ 7 ] = us_label( tr( "Volume " ) + "(&Aring;<sup>3</sup>)" );
254 
255  int row = 0;
256 
257  for ( int i = 0; i < 8; i++ )
258  {
259  titles[ i ]->setAlignment( Qt::AlignCenter );
260  values->addWidget( titles[ i ], row, i );
261  }
262 
263  row++;
264 
265  lb_sphere [ 0 ] = us_label( tr( "Sphere:" ) );
266  lb_prolate[ 0 ] = us_label( tr( "Prolate:" ) );
267  lb_oblate [ 0 ] = us_label( tr( "Oblate:" ) );
268  lb_rod [ 0 ] = us_label( tr( "Long Rod:" ) );
269 
270  for ( int i = 0; i < 8; i++ )
271  {
272  if ( i > 0 )
273  {
274  lb_sphere [ i ] = us_label( "" );
275  lb_prolate[ i ] = us_label( "" );
276  lb_oblate [ i ] = us_label( "" );
277  lb_rod [ i ] = us_label( "" );
278 
279  lb_sphere [ i ]->setPalette( p );
280  lb_prolate[ i ]->setPalette( p );
281  lb_oblate [ i ]->setPalette( p );
282  lb_rod [ i ]->setPalette( p );
283  }
284 
285  lb_sphere [ i ]->setAlignment( Qt::AlignCenter );
286  lb_prolate[ i ]->setAlignment( Qt::AlignCenter );
287  lb_oblate [ i ]->setAlignment( Qt::AlignCenter );
288  lb_rod [ i ]->setAlignment( Qt::AlignCenter );
289 
290  values->addWidget( lb_sphere [ i ], row , i );
291  values->addWidget( lb_prolate[ i ], row + 1, i );
292  values->addWidget( lb_oblate [ i ], row + 2, i );
293  values->addWidget( lb_rod [ i ], row + 3, i );
294  }
295 
296  main->addLayout( values );
297  update();
298 }
299 
301 {
302  if ( signal )
303  {
304  emit done();
305  emit changed( analyte );
306  }
307  close();
308 }
309 
311 {
312  QwtDoublePoint p( le_axial->text().toDouble(), 0.0 );
313  mouseU( p );
314 }
315 
316 void US_Predict1::update_mw( const QString& s )
317 {
318  mw = s.toDouble();
319  update();
320 }
321 
322 void US_Predict1::degC( const QString& s )
323 {
324  temperature = s.toDouble();
325  solution.vbar = solution.vbar20 + 4.25e-4 * ( temperature - 20.0 );
326 
328  update();
329 }
330 
332 {
333  US_AnalyteGui* dialog =
334  new US_AnalyteGui( true, analyte.analyteGUID );
335 
336  connect( dialog, SIGNAL( valueChanged( US_Analyte ) ),
337  SLOT ( update_vbar ( US_Analyte ) ) );
338 
339  connect( dialog, SIGNAL( use_db ( bool ) ),
340  SLOT ( source_changed( bool ) ) );
341  dialog->exec();
342 }
343 
345 {
346  analyte = ad;
347  mw = ad.mw;
348  solution.vbar20 = ad.vbar20;
349 
350  le_mw ->setText( QString::number( (int) mw, 'e', 3 ) );
351  le_vbar->setText( QString::number( solution.vbar, 'f', 4 ) );
352 
354  update();
355 }
356 
358 {
360 
361  US_BufferGui* dialog = new US_BufferGui( true, buffer, access );
362 
363  connect( dialog, SIGNAL( valueChanged ( US_Buffer ) ),
364  SLOT ( update_buffer( US_Buffer ) ) );
365 
366  connect( dialog, SIGNAL( use_db ( bool ) ),
367  SLOT ( source_changed( bool ) ) );
368 
369  dialog->exec();
370 }
371 
373 {
374  buffer = b;
377 
378  le_density ->setText( QString::number( solution.density, 'f', 4 ) );
379  le_viscosity->setText( QString::number( solution.viscosity , 'f', 4 ) );
380 
382  update();
383 }
384 
385 void US_Predict1::density( const QString& s )
386 {
387  solution.density = s.toDouble();
389  update();
390 }
391 
392 void US_Predict1::viscosity( const QString& s )
393 {
394  solution.viscosity = s.toDouble();
396  update();
397 }
398 
399 void US_Predict1::vbar( const QString& s )
400 {
401  solution.vbar = s.toDouble();
403  update();
404 }
405 
406 void US_Predict1::new_value( const QwtDoublePoint& p )
407 {
408  ratio = p.x();
409 
410  le_axial ->disconnect();
411  le_axial->setText( QString::number( ratio, 'f', 3 ) );
412 
413  connect( le_axial, SIGNAL( editingFinished( void ) ),
414  SLOT ( update_ratio ( void ) ) );
415  update();
416 }
417 
418 void US_Predict1::mouseU( const QwtDoublePoint& p )
419 {
420  ratio = p.x();
421 
422  QString msg;
423 
424  if ( ratio < 1.1 )
425  {
426  msg = tr( "Attention:\n\n"
427  "The lower axial ratio limit is 1.1!" );
428  ratio = 1.1;
429  }
430 
431  else if ( ratio < 6.0 && ratio >= 1.1 )
432  msg = tr( "Attention:\n\n"
433  "The rod model is unreliable\n"
434  "for axial ratios less than 6.0" );
435 
436  else if ( ratio >= 6.0 && ratio <= 100.0 )
437  msg = tr( "Please select an axial ratio by\n"
438  "dragging the white bar with the\n"
439  "mouse to change the axial ratio" );
440 
441  else if ( ratio > 100 )
442  {
443  msg = tr( "Attention:\n\n"
444  "The upper axial ratio limit is 100!" );
445  ratio = 100.0;
446  }
447 
448  lb_info->setText( msg );
449 
450  vline_x[ 0 ] = ratio;
451  vline_x[ 1 ] = ratio;
452  vline_curve->setData( vline_x, vline_y, 2 );
453  plot->replot();
454 
455  le_axial ->disconnect();
456 
457  le_axial->setText( QString::number( ratio, 'f', 3 ) );
458 
459  connect( le_axial, SIGNAL( editingFinished( void ) ),
460  SLOT ( update_ratio ( void ) ) );
461  update();
462  //debug();
463 }
464 
466 {
467  allparams.mw = mw;
473 
475 
476  lb_sphere[ 1 ] ->setText( QString::number( allparams.sphere.s , 'e', 4 ) );
477  lb_sphere[ 2 ] ->setText( QString::number( allparams.sphere.D , 'e', 4 ) );
478  lb_sphere[ 3 ] ->setText( QString::number( allparams.sphere.f , 'e', 4 ) );
479  lb_sphere[ 4 ] ->setText( QString::number( allparams.sphere.f_f0 , 'f', 4 ) );
480  lb_sphere[ 5 ] ->setText( QString::number( allparams.sphere.a , 'e', 4 ) );
481  lb_sphere[ 6 ] ->setText( QString::number( allparams.sphere.b , 'e', 4 ) );
482  lb_sphere[ 7 ] ->setText( QString::number( allparams.sphere.volume , 'e', 4 ) );
483 
484  lb_prolate[ 1 ]->setText( QString::number( allparams.prolate.s , 'e', 4 ) );
485  lb_prolate[ 2 ]->setText( QString::number( allparams.prolate.D , 'e', 4 ) );
486  lb_prolate[ 3 ]->setText( QString::number( allparams.prolate.f , 'e', 4 ) );
487  lb_prolate[ 4 ]->setText( QString::number( allparams.prolate.f_f0 , 'f', 4 ) );
488  lb_prolate[ 5 ]->setText( QString::number( allparams.prolate.a , 'e', 4 ) );
489  lb_prolate[ 6 ]->setText( QString::number( allparams.prolate.b , 'e', 4 ) );
490  lb_prolate[ 7 ]->setText( QString::number( allparams.prolate.volume, 'e', 4 ) );
491 
492  lb_oblate[ 1 ] ->setText( QString::number( allparams.oblate.s , 'e', 4 ) );
493  lb_oblate[ 2 ] ->setText( QString::number( allparams.oblate.D , 'e', 4 ) );
494  lb_oblate[ 3 ] ->setText( QString::number( allparams.oblate.f , 'e', 4 ) );
495  lb_oblate[ 4 ] ->setText( QString::number( allparams.oblate.f_f0 , 'f', 4 ) );
496  lb_oblate[ 5 ] ->setText( QString::number( allparams.oblate.a , 'e', 4 ) );
497  lb_oblate[ 6 ] ->setText( QString::number( allparams.oblate.b , 'e', 4 ) );
498  lb_oblate[ 7 ] ->setText( QString::number( allparams.oblate.volume , 'e', 4 ) );
499 
500  lb_rod[ 1 ] ->setText( QString::number( allparams.rod.s , 'e', 4 ) );
501  lb_rod[ 2 ] ->setText( QString::number( allparams.rod.D , 'e', 4 ) );
502  lb_rod[ 3 ] ->setText( QString::number( allparams.rod.f , 'e', 4 ) );
503  lb_rod[ 4 ] ->setText( QString::number( allparams.rod.f_f0 , 'f', 4 ) );
504  lb_rod[ 5 ] ->setText( QString::number( allparams.rod.a , 'e', 4 ) );
505  lb_rod[ 6 ] ->setText( QString::number( allparams.rod.b , 'e', 4 ) );
506  lb_rod[ 7 ] ->setText( QString::number( allparams.rod.volume , 'e', 4 ) );
507  if ( signal ) emit changed();
508 }
509 
511 {
512  emit use_db( db );
513  qApp->processEvents();
514 }
515 
516 void US_Predict1::debug( void )
517 {
518  /*
519  US_Hydrosim sim;
520  sim.mw = allparams.mw;
521  sim.density = allparams.density;
522  sim.viscosity = allparams.viscosity;
523  sim.vbar = allparams.vbar;
524  sim.axial_ratio = allparams.axial_ratio;
525 
526  sim.calculate( temperature );
527 
528  qDebug() << "sphere" << sim.sphere.s
529  << sim.sphere.D
530  << sim.sphere.f
531  << sim.sphere.f_f0
532  << sim.sphere.a
533  << sim.sphere.b
534  << sim.sphere.volume;
535 
536  qDebug() << "prolate" << sim.prolate.s
537  << sim.prolate.D
538  << sim.prolate.f
539  << sim.prolate.f_f0
540  << sim.prolate.a
541  << sim.prolate.b
542  << sim.prolate.volume;
543 
544  qDebug() << "oblate" << sim.oblate.s
545  << sim.oblate.D
546  << sim.oblate.f
547  << sim.oblate.f_f0
548  << sim.oblate.a
549  << sim.oblate.b
550  << sim.oblate.volume;
551 
552  qDebug() << "rod" << sim.rod.s
553  << sim.rod.D
554  << sim.rod.f
555  << sim.rod.f_f0
556  << sim.rod.a
557  << sim.rod.b
558  << sim.rod.volume;
559 */
560 }
561 
563 {
564  US_SolutionGui* dialog = new US_SolutionGui( 1, 1, true );
565  connect( dialog, SIGNAL( updateSolutionGuiSelection( US_Solution ) ),
566  SLOT ( update_solution ( US_Solution ) ) );
567  dialog->setWindowTitle( tr( "Solutions" ) );
568  dialog->exec();
569 }
570 
572 {
575 
576  le_density ->setText( QString::number( solution.density, 'f', 4 ) );
577  le_viscosity->setText( QString::number( solution.viscosity, 'f', 4 ) );
578 
580 
581  if ( soln.analyteInfo.size() == 0 )
582  {
583  QMessageBox::warning( this,
584  tr( "No Analyte" ),
585  tr( "There is no analyte in the solution" ) );
586  return;
587  }
588  else if ( soln.analyteInfo.size() == 1 )
589  {
590  analyte = soln.analyteInfo[ 0 ].analyte;
591  solution.vbar20 = analyte.vbar20;;
593  le_vbar->setText( QString::number( solution.vbar, 'f', 4 ) );
594 
595  mw = analyte.mw;
596  le_mw->setText( QString::number( mw, 'e', 4 ) );
597  }
598  else
599  {
600  US_Choice* dialog = new US_Choice( soln );
601  connect( dialog, SIGNAL( choice( int ) ),
602  SLOT ( choose( int ) ) );
603  dialog->exec();
604  qApp->processEvents();
605 
606  analyte = soln.analyteInfo[ analyte_number ].analyte;
607  solution.vbar20 = analyte.vbar20;;
609  le_vbar->setText( QString::number( solution.vbar, 'f', 4 ) );
610 
611  mw = analyte.mw;
612  le_mw->setText( QString::number( mw, 'e', 4 ) );
613  }
614 
615  update();
616 }
617 
618 void US_Predict1::choose( int value )
619 {
620  analyte_number = value;
621 }
622 
623