UltraScan III
us_constraints_edit.cpp
Go to the documentation of this file.
1 
3 #include "us_constraints_edit.h"
4 #include "us_gui_settings.h"
5 #include "us_settings.h"
6 #include "us_constants.h"
7 #include "us_properties.h"
8 #include "us_investigator.h"
9 #include "us_util.h"
10 #include "us_passwd.h"
11 #include "us_associations_gui.h"
12 
13 #ifndef DbgLv
14 #define DbgLv(a) if(dbg_level>=a)qDebug()
15 #endif
16 
17 const QString notapl = QObject::tr( "" );
18 
19 // Constructor of dialog for editing discreteGA constraints
21  : US_WidgetsDialog( 0, 0 ), cmodel( current_model )
22 {
23  setWindowTitle ( "Discrete Model GA Constraints Editor" );
24  setPalette ( US_GuiSettings::frameColor() );
25  setWindowModality( Qt::WindowModal );
26 
28  oldRow = -2;
29  inUpdate = false;
30  chgStoi = false;
31  crow = -1;
32  arow = -1;
34 
35  // Initialize the check icon
36  check = QIcon( US_Settings::appBaseDir() + "/etc/check.png" );
37 
38  // Grid
39  QGridLayout* main = new QGridLayout( this );
40  main->setSpacing( 2 );
41  main->setContentsMargins( 2, 2, 2, 2 );
42 
43  // Components
44  QLabel* lb_comps = us_banner( tr( "Components" ) );
45  lw_comps = new US_ListWidget;
46 
47  // Components column headers
48  QLabel* lb_attr = us_label( tr( "Attribute" ) );
49  QLabel* lb_avalue = us_label( tr( "Value" ) );
50  QLabel* lb_alow = us_label( tr( "Low" ) );
51  QLabel* lb_ahigh = us_label( tr( "High" ) );
52  QLabel* lb_float = us_label( tr( "Float?" ) );
53  QLabel* lb_locsc = us_label( tr( "LogSc?" ) );
54 // QLabel* lb_desc = us_label( tr( "Analyte Description:" ) );
55 
56  // Attribute Fix? checkboxes and labels
57  QGridLayout* lo_vbar = us_checkbox(
58  tr( "Vbar at 20 " ) + DEGC + " (ml/g):", ck_sel_vbar, true );
59  QGridLayout* lo_mw = us_checkbox(
60  tr( "Molecular Wt. (mw)" ), ck_sel_mw, true );
61  QGridLayout* lo_ff0 = us_checkbox(
62  tr( "Frictional Ratio (f/f0)" ), ck_sel_ff0, true );
63  QGridLayout* lo_s = us_checkbox(
64  tr( "Sedimentation Coeff. (s)" ), ck_sel_s );
65  QGridLayout* lo_D = us_checkbox(
66  tr( "Diffusion Coeff. (D)" ), ck_sel_D );
67  QGridLayout* lo_f = us_checkbox(
68  tr( "Frictional Coeff. (f)" ), ck_sel_f );
69  QGridLayout* lo_conc = us_checkbox(
70  tr( "Partial Concentration" ), ck_sel_conc, true );
71  ck_sel_vbar->setEnabled( false );
72  ck_sel_mw ->setEnabled( true );
73  ck_sel_ff0 ->setEnabled( true );
74  ck_sel_s ->setEnabled( true );
75  ck_sel_D ->setEnabled( true );
76  ck_sel_f ->setEnabled( true );
77  ck_sel_conc->setEnabled( false );
78 DbgLv(1) << "cnG:main: hds,lbs defined";
79 
80  // Attribute value/low/high text boxes
81  le_val_vbar = us_lineedit( "0.7200" );
82  le_min_vbar = us_lineedit( notapl, true );
83  le_max_vbar = us_lineedit( notapl, true );
84  le_val_mw = us_lineedit( "10000" );
85  le_min_mw = us_lineedit( notapl, true );
86  le_max_mw = us_lineedit( notapl, true );
87  le_val_ff0 = us_lineedit( "2.0" );
88  le_min_ff0 = us_lineedit( notapl, true );
89  le_max_ff0 = us_lineedit( notapl, true );
90  le_val_s = us_lineedit( "3e-13" );
91  le_min_s = us_lineedit( notapl, true );
92  le_max_s = us_lineedit( notapl, true );
93  le_val_D = us_lineedit( "3e-7" );
94  le_min_D = us_lineedit( notapl, true );
95  le_max_D = us_lineedit( notapl, true );
96  le_val_f = us_lineedit( "3e-6" );
97  le_min_f = us_lineedit( notapl, true );
98  le_max_f = us_lineedit( notapl, true );
99  le_val_conc = us_lineedit( "0.5" );
100  le_min_conc = us_lineedit( notapl, true );
101  le_max_conc = us_lineedit( notapl, true );
102 DbgLv(1) << "cnG:main: le_vals defined";
103 
104  // Attribute Float? checkboxes
105  ck_flt_vbar = new QCheckBox( "", this );
106  ck_flt_mw = new QCheckBox( "", this );
107  ck_log_mw = new QCheckBox( "", this );
108  ck_flt_ff0 = new QCheckBox( "", this );
109  ck_flt_s = new QCheckBox( "", this );
110  ck_flt_D = new QCheckBox( "", this );
111  ck_flt_f = new QCheckBox( "", this );
112  ck_flt_conc = new QCheckBox( "", this );
113  ck_flt_vbar->setChecked( false );
114  ck_flt_mw ->setChecked( false );
115  ck_log_mw ->setChecked( false );
116  ck_flt_ff0 ->setChecked( false );
117  ck_flt_s ->setChecked( false );
118  ck_flt_D ->setChecked( false );
119  ck_flt_f ->setChecked( false );
120  ck_flt_conc->setChecked( false );
121  ck_flt_vbar->setEnabled( true );
122  ck_flt_mw ->setEnabled( true );
123  ck_log_mw ->setEnabled( true );
124  ck_flt_ff0 ->setEnabled( true );
125  ck_flt_s ->setEnabled( true );
126  ck_flt_D ->setEnabled( true );
127  ck_flt_f ->setEnabled( true );
128  ck_flt_conc->setEnabled( true );
129 DbgLv(1) << "cnG:main: flt/log defined";
130 
131  QLabel* lb_extinction = us_label(
132  tr( "Extinction (OD/(cm*mol)):" ) );
133  QLabel* lb_wavelength = us_label(
134  tr( "Wavelength (nm):" ) );
135  le_extinction = us_lineedit( "" );
136  le_wavelength = us_lineedit( QString::number( cmodel.wavelength, 'f', 1 ) );
137  le_wavelength->setMinimumWidth( 80 );
138  le_wavelength->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
139  us_setReadOnly( le_wavelength, true );
140 
141  QLabel* lb_oligomer = us_label( tr( "Oligomer" ) );
142  le_oligomer = us_lineedit( "" );
143  QGridLayout* isreac_layout = us_checkbox( tr( "Is Reactant" ), ck_isreact );
144  QGridLayout* isprod_layout = us_checkbox( tr( "Is Product" ), ck_isprod );
145  us_setReadOnly( le_oligomer, true );
146  ck_isreact->setEnabled( false );
147  ck_isprod ->setEnabled( false );
148 
149  // Advanced parameters
150  QLabel* lb_sigma = us_label(
151  tr( "Concentration Dependency of s (<span>&sigma;</span>):" ) );
152  le_sigma = us_lineedit( "" );
153  QLabel* lb_delta = us_label(
154  tr( "Concentration Dependency of D (<span>&delta;</span>):" ) );
155  le_delta = us_lineedit( "" );
156  pb_load_c0 = us_pushbutton( tr( "Load C0 from File" ) );
157  QGridLayout* co_sed_layout = us_checkbox(
158  tr( "Co-sedimenting Solute" ), ck_co_sed );
159 pb_load_c0->setEnabled(false);
160  QPushButton* pb_recompute = us_pushbutton(
161  tr( "Re-compute unselected component attribute values" ) );
162 
163  // Associations
164  QLabel* lb_assocs = us_banner( tr( "Associations (reactions)" ) );
165  lw_assocs = new US_ListWidget;
166 
167  // Associations column headers
168  QLabel* lb_attra = us_label( tr( "Attribute" ) );
169  QLabel* lb_avala = us_label( tr( "Value" ) );
170  QLabel* lb_alowa = us_label( tr( "Low" ) );
171  QLabel* lb_ahigha = us_label( tr( "High" ) );
172  QLabel* lb_floata = us_label( tr( "Float?" ) );
173  QLabel* lb_logsca = us_label( tr( "LogSc?" ) );
174  le_lbl_kd = us_lineedit( tr( "K_dissociation" ), true );
175  le_val_kd = us_lineedit( "0.0001" );
176  le_min_kd = us_lineedit( notapl, true );
177  le_max_kd = us_lineedit( notapl, true );
178  ck_flt_kd = new QCheckBox( "", this );
179  ck_log_kd = new QCheckBox( "", this );
180  le_lbl_koff = us_lineedit( tr( "k_off rate" ), true );
181  le_val_koff = us_lineedit( "0.0001" );
182  le_min_koff = us_lineedit( notapl, true );
183  le_max_koff = us_lineedit( notapl, true );
184  ck_flt_koff = new QCheckBox( "", this );
185  ck_log_koff = new QCheckBox( "", this );
186  us_setReadOnly( le_lbl_kd, true );
187  us_setReadOnly( le_lbl_koff, true );
188  le_lbl_kd ->setEnabled( false );
189  le_lbl_koff->setEnabled( false );
190  ck_flt_kd ->setEnabled( true );
191  ck_log_kd ->setEnabled( true );
192  ck_flt_koff->setEnabled( true );
193  ck_log_koff->setEnabled( true );
194 DbgLv(1) << "cnG:main: assocs defined";
195 
196  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
197  QPushButton* pb_close = us_pushbutton( tr( "Cancel" ) );
198  pb_accept = us_pushbutton( tr( "Accept" ) );
199 DbgLv(1) << "cnG:main: elements defined";
200 
201  int row = 0;
202  main->addWidget( lb_comps, row++, 0, 1, 12 );
203  main->addWidget( lw_comps, row, 0, 3, 12 ); row += 3;
204  main->addWidget( lb_attr, row, 0, 1, 4 );
205  main->addWidget( lb_avalue, row, 4, 1, 2 );
206  main->addWidget( lb_alow, row, 6, 1, 2 );
207  main->addWidget( lb_ahigh, row, 8, 1, 2 );
208  main->addWidget( lb_float, row, 10, 1, 1 );
209  main->addWidget( lb_locsc, row++, 11, 1, 1 );
210  main->addLayout( lo_vbar, row, 0, 1, 4 );
211  main->addWidget( le_val_vbar, row, 4, 1, 2 );
212  main->addWidget( le_min_vbar, row, 6, 1, 2 );
213  main->addWidget( le_max_vbar, row, 8, 1, 2 );
214  main->addWidget( ck_flt_vbar, row++, 10, 1, 1 );
215  main->addLayout( lo_mw, row, 0, 1, 4 );
216  main->addWidget( le_val_mw, row, 4, 1, 2 );
217  main->addWidget( le_min_mw, row, 6, 1, 2 );
218  main->addWidget( le_max_mw, row, 8, 1, 2 );
219  main->addWidget( ck_flt_mw, row, 10, 1, 1 );
220  main->addWidget( ck_log_mw, row++, 11, 1, 1 );
221  main->addLayout( lo_ff0, row, 0, 1, 4 );
222  main->addWidget( le_val_ff0, row, 4, 1, 2 );
223  main->addWidget( le_min_ff0, row, 6, 1, 2 );
224  main->addWidget( le_max_ff0, row, 8, 1, 2 );
225  main->addWidget( ck_flt_ff0, row++, 10, 1, 1 );
226  main->addLayout( lo_s, row, 0, 1, 4 );
227  main->addWidget( le_val_s, row, 4, 1, 2 );
228  main->addWidget( le_min_s, row, 6, 1, 2 );
229  main->addWidget( le_max_s, row, 8, 1, 2 );
230  main->addWidget( ck_flt_s, row++, 10, 1, 1 );
231  main->addLayout( lo_D, row, 0, 1, 4 );
232  main->addWidget( le_val_D, row, 4, 1, 2 );
233  main->addWidget( le_min_D, row, 6, 1, 2 );
234  main->addWidget( le_max_D, row, 8, 1, 2 );
235  main->addWidget( ck_flt_D, row++, 10, 1, 1 );
236  main->addLayout( lo_f, row, 0, 1, 4 );
237  main->addWidget( le_val_f, row, 4, 1, 2 );
238  main->addWidget( le_min_f, row, 6, 1, 2 );
239  main->addWidget( le_max_f, row, 8, 1, 2 );
240  main->addWidget( ck_flt_f, row++, 10, 1, 1 );
241  main->addLayout( lo_conc, row, 0, 1, 4 );
242  main->addWidget( le_val_conc, row, 4, 1, 2 );
243  main->addWidget( le_min_conc, row, 6, 1, 2 );
244  main->addWidget( le_max_conc, row, 8, 1, 2 );
245  main->addWidget( ck_flt_conc, row++, 10, 1, 1 );
246  main->addWidget( lb_extinction, row, 0, 1, 4 );
247  main->addWidget( le_extinction, row, 4, 1, 2 );
248  main->addWidget( lb_wavelength, row, 6, 1, 4 );
249  main->addWidget( le_wavelength, row++, 10, 1, 2 );
250  main->addWidget( lb_oligomer, row, 0, 1, 4 );
251  main->addWidget( le_oligomer, row, 4, 1, 2 );
252  main->addLayout( isreac_layout, row, 6, 1, 3 );
253  main->addLayout( isprod_layout, row++, 9, 1, 3 );
254  main->addWidget( lb_sigma, row, 0, 1, 6 );
255  main->addWidget( le_sigma, row, 6, 1, 2 );
256  main->addLayout( co_sed_layout, row++, 8, 1, 4 );
257  main->addWidget( lb_delta, row, 0, 1, 6 );
258  main->addWidget( le_delta, row, 6, 1, 2 );
259  main->addWidget( pb_load_c0, row++, 8, 1, 4 );
260  main->addWidget( pb_recompute, row++, 0, 1, 12 );
261  main->addWidget( lb_assocs, row++, 0, 1, 12 );
262  main->addWidget( lw_assocs, row, 0, 2, 12 ); row += 2;
263  main->addWidget( lb_attra, row, 0, 1, 4 );
264  main->addWidget( lb_avala, row, 4, 1, 2 );
265  main->addWidget( lb_alowa, row, 6, 1, 2 );
266  main->addWidget( lb_ahigha, row, 8, 1, 2 );
267  main->addWidget( lb_floata, row, 10, 1, 1 );
268  main->addWidget( lb_logsca, row++, 11, 1, 1 );
269  main->addWidget( le_lbl_kd, row, 0, 1, 4 );
270  main->addWidget( le_val_kd, row, 4, 1, 2 );
271  main->addWidget( le_min_kd, row, 6, 1, 2 );
272  main->addWidget( le_max_kd, row, 8, 1, 2 );
273  main->addWidget( ck_flt_kd, row, 10, 1, 1 );
274  main->addWidget( ck_log_kd, row++, 11, 1, 1 );
275  main->addWidget( le_lbl_koff, row, 0, 1, 4 );
276  main->addWidget( le_val_koff, row, 4, 1, 2 );
277  main->addWidget( le_min_koff, row, 6, 1, 2 );
278  main->addWidget( le_max_koff, row, 8, 1, 2 );
279  main->addWidget( ck_flt_koff, row, 10, 1, 1 );
280  main->addWidget( ck_log_koff, row++, 11, 1, 1 );
281  main->addWidget( pb_help, row, 0, 1, 4 );
282  main->addWidget( pb_close, row, 4, 1, 4 );
283  main->addWidget( pb_accept, row++, 8, 1, 4 );
284 
285  connect( le_extinction, SIGNAL( editingFinished() ),
286  SLOT ( set_molar () ) );
287  connect( pb_load_c0, SIGNAL( clicked() ),
288  SLOT ( load_c0() ) );
289  connect( ck_co_sed, SIGNAL( stateChanged( int ) ),
290  SLOT ( co_sed ( int ) ) );
291  connect( pb_recompute, SIGNAL( clicked () ),
292  SLOT ( check_selects() ) );
293  connect( pb_help, SIGNAL( clicked () ),
294  SLOT ( help () ) );
295  connect( pb_close, SIGNAL( clicked () ),
296  SLOT ( close () ) );
297  connect( pb_accept, SIGNAL( clicked () ),
298  SLOT ( acceptProp() ) );
299  pb_accept->setEnabled( false );
300 DbgLv(1) << "cnG:main: connections made";
301  const QString clets( "ABCDEFGHIJ" );
302  lcompx.clear();
303 
304  // Populate the lists from the model
306  { // Constraints model
307  constraints.load_constraints( &cmodel );
308  int kk = 0;
309 DbgLv(1) << "cnG:main: cmodel load rtn";
310  for ( int ii = 0; ii < cmodel.components.size(); ii++, kk++ )
311  {
312  QString prenm = QString( clets ).mid( kk, 1 ) + " ";
313  QString flgnm = QString( cmodel.components[ ii ].name ).left( 4 );
314  QString name = QString( cmodel.components[ ii ].name ).mid( 4 );
315  lw_comps->addItem( prenm + name );
316  lcompx << ii;
317 
318  if ( ! flgnm.contains( "V" ) ) ii++;
319  }
320 
321  for ( int ii = 0; ii < cmodel.associations.size(); ii += 2 )
322  {
323  QVector< int > rcomps = cmodel.associations[ ii ].rcomps;
324  QVector< int > stoichs = cmodel.associations[ ii ].stoichs;
325  int nrc = rcomps.size();
326  int rc1 = ( nrc > 0 ) ? rcomps [ 0 ] : 0;
327  int rc2 = ( nrc > 1 ) ? rcomps [ 1 ] : 0;
328  int rc3 = ( nrc > 2 ) ? rcomps [ 2 ] : 0;
329  int st1 = ( nrc > 0 ) ? stoichs[ 0 ] : 1;
330  int st2 = ( nrc > 1 ) ? stoichs[ 1 ] : 1;
331  int st3 = ( nrc > 2 ) ? stoichs[ 2 ] : 1;
332  int ol1 = cmodel.components[ lcompx[ rc1 ] ].oligomer;
333  int ol2 = cmodel.components[ lcompx[ rc2 ] ].oligomer;
334  int ol3 = cmodel.components[ lcompx[ rc3 ] ].oligomer;
335 
336  QString name;
337  if ( rcomps.size() == 2 )
338  {
339  name = QString::number( st1 )
340  + QString( clets ).mid( rc1, 1 )
341  + QString::number( ol1 )
342  + " => "
343  + QString::number( qAbs( st2 ) )
344  + QString( clets ).mid( rc2, 1 )
345  + QString::number( ol2 );
346  }
347  else if ( rcomps.size() == 3 )
348  {
349  name = QString::number( st1 )
350  + QString( clets ).mid( rc1, 1 )
351  + QString::number( ol1 )
352  + " + "
353  + QString::number( st2 )
354  + QString( clets ).mid( rc2, 1 )
355  + QString::number( ol2 )
356  + " => "
357  + QString::number( qAbs( st3 ) )
358  + QString( clets ).mid( rc3, 1 )
359  + QString::number( ol3 );
360  }
361  else
362  {
363  name = "(reaction " + QString::number( ii + 1 ) + ")";
364  }
365 
366  lw_assocs->addItem( name );
367  }
368 
369  if ( lw_assocs->count() == 0 )
370  lw_assocs->addItem( "(none)" );
371 
372  pb_accept->setEnabled( constraints.float_constraints( NULL ) > 0 );
373  }
374 
375  else
376  { // Base model
377  constraints.load_base_model( &cmodel );
378 DbgLv(1) << "cnG:main: bmodel load rtn";
379  for ( int ii = 0; ii < cmodel.components.size(); ii++ )
380  {
381  QString prenm = QString( clets ).mid( ii, 1 ) + " ";
382  QString name = cmodel.components[ ii ].name;
383  lw_comps->addItem( prenm + name );
384  lcompx << ii;
385  }
386 
387  for ( int ii = 0; ii < cmodel.associations.size(); ii++ )
388  {
389  QVector< int > rcomps = cmodel.associations[ ii ].rcomps;
390  QVector< int > stoichs = cmodel.associations[ ii ].stoichs;
391  int nrc = rcomps.size();
392  int rc1 = ( nrc > 0 ) ? rcomps [ 0 ] : 0;
393  int rc2 = ( nrc > 1 ) ? rcomps [ 1 ] : 0;
394  int rc3 = ( nrc > 2 ) ? rcomps [ 2 ] : 0;
395  int st1 = ( nrc > 0 ) ? stoichs[ 0 ] : 1;
396  int st2 = ( nrc > 1 ) ? stoichs[ 1 ] : 1;
397  int st3 = ( nrc > 2 ) ? stoichs[ 2 ] : 1;
398  int ol1 = cmodel.components[ rc1 ].oligomer;
399  int ol2 = cmodel.components[ rc2 ].oligomer;
400  int ol3 = cmodel.components[ rc3 ].oligomer;
401  QString name;
402 
403  if ( rcomps.size() == 2 )
404  {
405  name = QString::number( st1 )
406  + QString( clets ).mid( rc1, 1 )
407  + QString::number( ol1 )
408  + " => "
409  + QString::number( qAbs( st2 ) )
410  + QString( clets ).mid( rc2, 1 )
411  + QString::number( ol2 );
412  }
413  else if ( rcomps.size() == 3 )
414  {
415  name = QString::number( st1 )
416  + QString( clets ).mid( rc1, 1 )
417  + QString::number( ol1 )
418  + " + "
419  + QString::number( st2 )
420  + QString( clets ).mid( rc2, 1 )
421  + QString::number( ol2 )
422  + " => "
423  + QString::number( qAbs( st3 ) )
424  + QString( clets ).mid( rc3, 1 )
425  + QString::number( ol3 );
426  }
427  else
428  {
429  name = "(reaction " + QString::number( ii + 1 ) + ")";
430  }
431 
432  lw_assocs->addItem( name );
433  }
434 
435  if ( lw_assocs->count() == 0 )
436  lw_assocs->addItem( "(none)" );
437  }
438 
439  connect( lw_comps, SIGNAL( currentRowChanged ( int ) ),
440  SLOT ( component_select ( int ) ) );
441  connect( lw_assocs, SIGNAL( currentRowChanged ( int ) ),
442  SLOT ( association_select( int ) ) );
443 
445  QFontMetrics fm( font );
446  int fhigh = fm.lineSpacing();
447  int fwide = fm.width( QChar( '6' ) );
448  int chigh = fhigh * 3 + 12;
449  int ahigh = fhigh * 2 + 12;
450  int lwide = width() - 10;
451  const int bmwide = 700;
452  const int bmhigh = 540;
453  const int bfwide = 8;
454  const int bfhigh = 16;
455 
456  lw_comps ->setMinimumHeight( chigh );
457  lw_comps ->resize( lwide, chigh );
458  lw_assocs->setMinimumHeight( ahigh );
459  lw_assocs->resize( lwide, ahigh );
460 
461  comps_connect ( true );
462  assocs_connect( true );
463 
464 DbgLv(1) << "cnG:main: set comp row";
465  lw_comps ->setCurrentRow( 0 );
466  lw_assocs->setCurrentRow( cmodel.associations.size() > 0 ? 0 : -1 );
467 
468 DbgLv(1) << "cnG:main: m size" << size() << "fwide fhigh" << fwide << fhigh;
469  int mwide = ( bmwide * fwide ) / bfwide;
470  int mhigh = ( bmhigh * fhigh ) / bfhigh;
471  resize( mwide, mhigh );
472 DbgLv(1) << "cnG:main: m size" << size();
473 }
474 
476 {
477 // int row = lw_comps->currentRow();
478 
479 // if ( row < 0 ) return;
480 int row=0;
481 
482  // See if the initialization vector is already loaded.
483  if ( ! pb_load_c0->icon().isNull() )
484  {
485  int response = QMessageBox::question( this,
486  tr( "Remove C0 Data?" ),
487  tr( "The C0 information is loaded.\n"
488  "Remove it?" ),
489  QMessageBox::Yes, QMessageBox::No );
490 
491  if ( response == QMessageBox::Yes )
492  {
494 
495  sc->c0.radius .clear();
496  sc->c0.concentration.clear();
497  pb_load_c0->setIcon( QIcon() );
498  }
499 
500  return;
501  }
502 
503  QMessageBox::information( this,
504  tr( "UltraScan Information" ),
505  tr( "Please note:\n\n"
506  "The initial concentration file should have\n"
507  "the following format:\n\n"
508  "radius_value1 concentration_value1\n"
509  "radius_value2 concentration_value2\n"
510  "radius_value3 concentration_value3\n"
511  "etc...\n\n"
512  "radius values smaller than the meniscus or\n"
513  "larger than the bottom of the cell will be\n"
514  "excluded from the concentration vector." ) );
515 
516  QString fn = QFileDialog::getOpenFileName(
517  this, tr( "Load initial concentration" ), US_Settings::resultDir(), "*" );
518 
519  if ( ! fn.isEmpty() )
520  {
521  QFile f( fn );;
522 
523  if ( f.open( QIODevice::ReadOnly | QIODevice::Text ) )
524  {
525  QTextStream ts( &f );
526 
527 // int row = lw_comps->currentRow();
528 int row=0;
529 
531 
532  sc->c0.radius .clear();
533  sc->c0.concentration.clear();
534 
535  // Sets concentration for this component to -1 to signal that we are
536  // using a concentration vector
537  double val1;
538  double val2;
539 
540  while ( ! ts.atEnd() )
541  {
542  ts >> val1;
543  ts >> val2;
544 
545  if ( val1 > 0.0 ) // Ignore radius pairs that aren't positive
546  {
547  sc->c0.radius .push_back( val1 );
548  sc->c0.concentration .push_back( val2 );
549  }
550  }
551 
552  f.close();
553  pb_load_c0->setIcon( check );
554  }
555  else
556  {
557  QMessageBox::warning( this,
558  tr( "UltraScan Warning" ),
559  tr( "UltraScan could not open the file specified\n" ) + fn );
560  }
561  }
562 }
563 
565 {
566  int row = lw_comps->currentRow();
567  if ( row < 0 ) return;
568  int mcx = lcompx[ row ];
569 
571 
572  double extinction = le_extinction->text().toDouble();
573  double signalConc = le_val_conc ->text().toDouble();
574 
575  if ( extinction > 0.0 )
576  sc->molar_concentration = signalConc / extinction;
577  else
578  sc->molar_concentration = 0.0;
579 }
580 
582 {
583 DbgLv(1) << "cnG:aP:accept";
584  QVector< C_CONSTRAINT > cnsv;
585  save_comp_settings ( crow, cnsv ); // Save current page
586 DbgLv(1) << "cnG:aP: svcs crow" << crow << "cnsv sz" << cnsv.count();
587  constraints.update_constraints( cnsv ); // Update comp constraints
588 DbgLv(1) << "cnG:aP: upd_(c)cnst rtn";
589 
590  if ( arow >= 0 )
591  {
592  cnsv.clear();
593  save_assoc_settings( arow, cnsv );
594 DbgLv(1) << "cnG:aP: svas arow" << arow << "cnsv sz" << cnsv.count();
595  constraints.update_constraints( cnsv ); // Update assoc constraints
596 DbgLv(1) << "cnG:aP: upd_(a)cnst rtn";
597  }
598 
599  constraints.get_constr_model( &cmodel ); // Get equivalent model
600 DbgLv(1) << "cnG:aP: get_cmo RTN";
601 
602  accept();
603  close();
604 }
605 
606 void US_ConstraintsEdit::co_sed( int new_state )
607 {
608  if ( inUpdate ) return;
609 
610  if ( new_state == Qt::Checked )
611  {
612  int row = lw_comps->currentRow();
613 
614  if ( cmodel.coSedSolute != -1 )
615  {
616  int response = QMessageBox::question( this,
617  tr( "Change co-sedimenting solute?" ),
618  tr( "Another component is marked as the co-sedimenting solute.\n"
619  "Change it to the current analyte?" ),
620  QMessageBox::Yes, QMessageBox::No );
621 
622  if ( response == QMessageBox::No )
623  {
624  ck_co_sed->disconnect();
625  ck_co_sed->setChecked( false );
626  connect( ck_co_sed, SIGNAL( stateChanged( int ) ),
627  SLOT ( co_sed ( int ) ) );
628  return;
629  }
630  }
631  cmodel.coSedSolute = row;
632  }
633  else
634  cmodel.coSedSolute = -1;
635 }
636 
638 {
639  emit use_db( db ); // Just pass on the signal
640  qApp->processEvents();
641 }
642 
643 void US_ConstraintsEdit::check_mw ( bool checked )
644 {
645 DbgLv(1) << "cnG:check_mw checked" << checked;
646  ck_flt_mw ->setEnabled( checked );
647  ck_log_mw ->setEnabled( checked );
648 
649  check_selects();
650 }
651 
652 void US_ConstraintsEdit::check_ff0 ( bool checked )
653 {
654 DbgLv(1) << "cnG:check_ff0 checked" << checked;
655  ck_flt_ff0 ->setEnabled( checked );
656 
657  check_selects();
658 }
659 
660 void US_ConstraintsEdit::check_s ( bool checked )
661 {
662 DbgLv(1) << "cnG:check_s checked" << checked;
663  ck_flt_s ->setEnabled( checked );
664  check_selects();
665 }
666 
667 void US_ConstraintsEdit::check_D ( bool checked )
668 {
669 DbgLv(1) << "cnG:check_D checked" << checked;
670  ck_flt_D ->setEnabled( checked );
671  check_selects();
672 }
673 
674 void US_ConstraintsEdit::check_f ( bool checked )
675 {
676 DbgLv(1) << "cnG:check_f checked" << checked;
677  ck_flt_f ->setEnabled( checked );
678  check_selects();
679 }
680 
682 {
683 DbgLv(1) << "cnG:float_vbar floats" << floats;
685 }
686 
687 void US_ConstraintsEdit::float_mw ( bool floats )
688 {
689 DbgLv(1) << "cnG:float_mw floats" << floats;
690  float_par( floats, le_val_mw, le_min_mw, le_max_mw );
691 }
692 
693 void US_ConstraintsEdit::float_ff0 ( bool floats )
694 {
695 DbgLv(1) << "cnG:float_ff0 floats" << floats;
697 }
698 
699 void US_ConstraintsEdit::float_s ( bool floats )
700 {
701 DbgLv(1) << "cnG:float_s floats" << floats;
702  float_par( floats, le_val_s, le_min_s, le_max_s );
703 }
704 
705 void US_ConstraintsEdit::float_D ( bool floats )
706 {
707 DbgLv(1) << "cnG:float_D floats" << floats;
708  float_par( floats, le_val_D, le_min_D, le_max_D );
709 }
710 
711 void US_ConstraintsEdit::float_f ( bool floats )
712 {
713 DbgLv(1) << "cnG:float_f floats" << floats;
714  float_par( floats, le_val_f, le_min_f, le_max_f );
715 }
716 
718 {
719 DbgLv(1) << "cnG:float_conc floats" << floats;
721 }
722 
723 void US_ConstraintsEdit::float_kd ( bool floats )
724 {
725 DbgLv(1) << "cnG:float_kd floats" << floats;
726  float_par( floats, le_val_kd, le_min_kd, le_max_kd );
727 }
728 
730 {
731 DbgLv(1) << "cnG:float_koff floats" << floats;
733 }
734 
735 void US_ConstraintsEdit::logsc_mw ( bool logscl )
736 {
737 DbgLv(1) << "cnG:logsc_mw logscl" << logscl;
738 }
739 
740 void US_ConstraintsEdit::logsc_kd ( bool logscl )
741 {
742 DbgLv(1) << "cnG:logsc_kd logscl" << logscl;
743 }
745 {
746 DbgLv(1) << "cnG:logsc_koff logscl" << logscl;
747 }
748 
749 // Utility to connect/disconnect component slots
751 {
752  if ( c_on )
753  { // Turn connections on
754  connect( ck_flt_vbar, SIGNAL( toggled ( bool ) ),
755  SLOT ( float_vbar( bool ) ) );
756  connect( ck_sel_mw, SIGNAL( toggled ( bool ) ),
757  SLOT ( check_mw ( bool ) ) );
758  connect( ck_flt_mw, SIGNAL( toggled ( bool ) ),
759  SLOT ( float_mw ( bool ) ) );
760  connect( ck_log_mw, SIGNAL( toggled ( bool ) ),
761  SLOT ( logsc_mw ( bool ) ) );
762  connect( ck_sel_ff0, SIGNAL( toggled ( bool ) ),
763  SLOT ( check_ff0 ( bool ) ) );
764  connect( ck_flt_ff0, SIGNAL( toggled ( bool ) ),
765  SLOT ( float_ff0 ( bool ) ) );
766  connect( ck_sel_s, SIGNAL( toggled ( bool ) ),
767  SLOT ( check_s ( bool ) ) );
768  connect( ck_flt_s, SIGNAL( toggled ( bool ) ),
769  SLOT ( float_s ( bool ) ) );
770  connect( ck_sel_D, SIGNAL( toggled ( bool ) ),
771  SLOT ( check_D ( bool ) ) );
772  connect( ck_flt_D, SIGNAL( toggled ( bool ) ),
773  SLOT ( float_D ( bool ) ) );
774  connect( ck_sel_f, SIGNAL( toggled ( bool ) ),
775  SLOT ( check_f ( bool ) ) );
776  connect( ck_flt_f, SIGNAL( toggled ( bool ) ),
777  SLOT ( float_f ( bool ) ) );
778  connect( ck_flt_conc, SIGNAL( toggled ( bool ) ),
779  SLOT ( float_conc( bool ) ) );
780  }
781  else
782  { // Turn connections off
783  ck_flt_vbar->disconnect();
784  ck_sel_mw ->disconnect();
785  ck_flt_mw ->disconnect();
786  ck_log_mw ->disconnect();
787  ck_sel_ff0 ->disconnect();
788  ck_flt_ff0 ->disconnect();
789  ck_sel_s ->disconnect();
790  ck_flt_s ->disconnect();
791  ck_sel_D ->disconnect();
792  ck_flt_D ->disconnect();
793  ck_sel_f ->disconnect();
794  ck_flt_f ->disconnect();
795  ck_flt_conc->disconnect();
796  }
797 }
798 
799 // Utility to connect/disconnect component slots
801 {
802  if ( c_on )
803  { // Turn connections on
804  connect( ck_flt_kd, SIGNAL( toggled ( bool ) ),
805  SLOT ( float_kd ( bool ) ) );
806  connect( ck_log_kd, SIGNAL( toggled ( bool ) ),
807  SLOT ( logsc_kd ( bool ) ) );
808  connect( ck_flt_koff, SIGNAL( toggled ( bool ) ),
809  SLOT ( float_koff( bool ) ) );
810  connect( ck_log_koff, SIGNAL( toggled ( bool ) ),
811  SLOT ( logsc_koff( bool ) ) );
812  }
813  else
814  { // Turn connections off
815  ck_flt_kd ->disconnect();
816  ck_log_kd ->disconnect();
817  ck_flt_koff->disconnect();
818  ck_log_koff->disconnect();
819  }
820 }
821 
822 // Utility to count the selected main component attributes
824 {
825  int nchecks = ( ck_sel_mw ->isChecked() ? 1 : 0 )
826  + ( ck_sel_ff0->isChecked() ? 1 : 0 )
827  + ( ck_sel_s ->isChecked() ? 1 : 0 )
828  + ( ck_sel_D ->isChecked() ? 1 : 0 )
829  + ( ck_sel_f ->isChecked() ? 1 : 0 );
830  return nchecks;
831 }
832 
833 // Slot to populate component attribute values after component change
835 {
836 DbgLv(1) << "cnG: component_select row" << srow << crow;
837  QVector< C_CONSTRAINT > cnsv;
838 
839  if ( srow < 0 ) return;
840 
841  if ( crow >= 0 )
842  { // Save settings from previous component screen
843  save_comp_settings( crow, cnsv );
844 
845 DbgLv(1) << "cnG: update_constraints call";
846  constraints.update_constraints( cnsv );
847 DbgLv(1) << "cnG: update_constraints rtn";
848  }
849 
850  if ( srow == crow ) return;
851 
852  // Get constraints for new component
853  crow = srow;
854 DbgLv(1) << "cnG: comp_constraints call row" << crow;
855  constraints.comp_constraints( crow, &cnsv, NULL );
856 DbgLv(1) << "cnG: comp_constraints rtn cnsv size" << cnsv.size();
857  bool is_prod = cmodel.is_product( crow );
858  bool not_prod = ! is_prod;
859 
860  if ( is_prod )
861  { // Impose various restrictions for product component
862  QVector< C_CONSTRAINT > old_cnsv = cnsv;
863  cnsv.clear();
864 DbgLv(1) << "cnG: IS_PROD";
865 
866  // First scan associations to determine the reactant values
867  double vsum = 0.0; // vbar sum
868  double cval = 0.0; // concentration value
869  double wsum = 0.0; // weight sum
870  double esum = 0.0; // extinction sum
871  int nreact = 0;
872 
873  for ( int ii = 0; ii < cmodel.associations.size(); ii++ )
874  {
876  QVector< int >* rcomps = &as1->rcomps;
877 DbgLv(1) << "cnG: ii" << ii << "rc0" << rcomps->at(0) << "crow" << crow;
878  if ( rcomps->at( 0 ) < 0 ) continue;
879 
880  if ( rcomps->contains( crow ) )
881  {
882  QVector< int >* stoichs = &as1->stoichs;
883 DbgLv(1) << "cnG: ii" << ii << "rc-cont-crow: rcsize stsize"
884  << rcomps->size() << stoichs->size();
885 
886  for ( int jj = 0; jj < rcomps->size(); jj++ )
887  {
888  int rc1 = rcomps ->at( jj );
889  int st1 = stoichs->at( jj );
890 DbgLv(1) << "cnG: jj" << jj << "rc1" << rc1 << "st1" << st1;
891  if ( rc1 >= 0 && st1 > 0 )
892  {
893  // Get reactant's constraints
894  QVector< C_CONSTRAINT > rcnsv;
895  constraints.comp_constraints( rc1, &rcnsv, NULL );
896 
897  nreact++;
898  int mcx = lcompx[ rc1 ];
899  double rst1 = (double)st1;
900  double mw = constr_value( C_ATYPE_MW, rcnsv ) * rst1;
901  double vbar = constr_value( C_ATYPE_VBAR, rcnsv ) * mw;
902  double conc = constr_value( C_ATYPE_CONC, rcnsv );
903  double extinc = constr_value( C_ATYPE_EXT, rcnsv ) * rst1;
904  cval = ( cval == 0.0 ) ? conc : cval;
905  vsum += vbar;
906  wsum += mw;
907  esum += extinc;
908 DbgLv(1) << "cnG: mcx" << mcx << "cval,vsum,wsum,esum"
909  << cval << vsum << wsum << esum;
910  }
911  }
912 
913  break;
914  }
915  }
916 
917  vsum /= wsum;
918  bool miss_vb = true;
919  bool miss_co = true;
920  bool miss_mw = true;
921  bool miss_ff = true;
922  C_CONSTRAINT cnse;
923 
924  // Replace product constraints with appropriate ones
925 
926  for ( int ii = 0; ii < old_cnsv.size(); ii++ )
927  {
928  cnse = old_cnsv[ ii ];
929  C_ATYPE atype = cnse.atype;
930 
931  if ( atype == C_ATYPE_VBAR )
932  { // Replace vbar
933  cnse.low = vsum;
934  cnse.high = cnse.low;
935  cnse.floats = false;
936  cnsv << cnse;
937  miss_vb = false;
938  }
939 
940  else if ( atype == C_ATYPE_MW )
941  { // Replace mw
942  cnse.low = wsum;
943  cnse.high = cnse.low;
944  cnse.floats = false;
945  cnsv << cnse;
946  miss_mw = false;
947  }
948 
949  else if ( atype == C_ATYPE_FF0 )
950  { // Just copy f/f0 as is
951  cnsv << cnse;
952  miss_ff = false;
953  }
954 
955  else if ( atype == C_ATYPE_CONC )
956  { // Replace concentration
957  cnse.low = cval;
958  cnse.high = cnse.low;
959  cnse.floats = false;
960  cnsv << cnse;
961  miss_co = false;
962  }
963 
964  else if ( atype == C_ATYPE_EXT )
965  { // Replace extinction
966  cnse.low = esum;
967  cnse.high = cnse.low;
968  cnse.floats = false;
969  cnsv << cnse;
970  }
971 
972  }
973 DbgLv(1) << "cnG: miss_vb,mw,ff,co" << miss_vb << miss_mw << miss_ff << miss_co;
974 
975  // Insure product constraints includes needed values
976  if ( miss_vb )
977  { // Supply missing vbar constraint
978  cnse.atype = C_ATYPE_VBAR;
979  cnse.low = vsum;
980  cnse.high = cnse.low;
981  cnse.floats = false;
982  cnse.logscl = false;
983  cnsv << cnse;
984  }
985 
986  if ( miss_mw )
987  { // Supply missing mw constraint
988  cnse.atype = C_ATYPE_MW;
989  cnse.low = wsum;
990  cnse.high = cnse.low;
991  cnse.floats = false;
992  cnse.logscl = false;
993  cnsv << cnse;
994  }
995 
996  if ( miss_ff )
997  { // Supply missing f/f0 constraint
998  cnse.atype = C_ATYPE_FF0;
999  cnse.low = 1.8;
1000  cnse.high = cnse.low;
1001  cnse.floats = false;
1002  cnse.logscl = false;
1003  cnsv << cnse;
1004  }
1005 
1006  if ( miss_co )
1007  { // Supply missing concentration constraint
1008  cnse.atype = C_ATYPE_CONC;
1009  cnse.low = cval;
1010  cnse.high = cval;
1011  cnse.floats = false;
1012  cnse.logscl = false;
1013  cnsv << cnse;
1014  }
1015  }
1016 
1017  comps_connect ( false );
1018 DbgLv(1) << "cnG: comp_constraints rtn";
1019  //QListWidgetItem* item = lw_comps->item( crow );
1020 
1021  // Initialize component attribute GUI elements
1022  ck_sel_vbar->setChecked( true );
1023  ck_sel_mw ->setChecked( false );
1024  ck_sel_ff0 ->setChecked( false );
1025  ck_sel_s ->setChecked( false );
1026  ck_sel_D ->setChecked( false );
1027  ck_sel_f ->setChecked( false );
1028  ck_sel_conc->setChecked( true );
1029  ck_sel_mw ->setEnabled( false );
1030  ck_sel_ff0 ->setEnabled( false );
1031  ck_sel_s ->setEnabled( false );
1032  ck_sel_D ->setEnabled( false );
1033  ck_sel_f ->setEnabled( false );
1034  us_setReadOnly( le_val_vbar, true );
1035  us_setReadOnly( le_min_vbar, true );
1036  us_setReadOnly( le_max_vbar, true );
1037  us_setReadOnly( le_val_mw, true );
1038  us_setReadOnly( le_min_mw, true );
1039  us_setReadOnly( le_max_mw, true );
1040  us_setReadOnly( le_val_ff0, true );
1041  us_setReadOnly( le_min_ff0, true );
1042  us_setReadOnly( le_max_ff0, true );
1043  us_setReadOnly( le_val_s, true );
1044  us_setReadOnly( le_min_s, true );
1045  us_setReadOnly( le_max_s, true );
1046  us_setReadOnly( le_val_D, true );
1047  us_setReadOnly( le_min_D, true );
1048  us_setReadOnly( le_max_D, true );
1049  us_setReadOnly( le_val_f, true );
1050  us_setReadOnly( le_min_f, true );
1051  us_setReadOnly( le_max_f, true );
1052  us_setReadOnly( le_val_conc, true );
1053  us_setReadOnly( le_min_conc, true );
1054  us_setReadOnly( le_max_conc, true );
1055  ck_flt_vbar->setEnabled( not_prod );
1056  ck_flt_mw ->setEnabled( false );
1057  ck_flt_ff0 ->setEnabled( false );
1058  ck_flt_s ->setEnabled( false );
1059  ck_flt_D ->setEnabled( false );
1060  ck_flt_f ->setEnabled( false );
1061  ck_flt_conc->setEnabled( not_prod );
1062 
1063  // Populate component attribute values
1064  for ( int ii = 0; ii < cnsv.size(); ii++ )
1065  {
1066  bool floats = cnsv[ ii ].floats;
1067 
1068 DbgLv(1) << "cnG:cmp_sel: ii" << ii << "atype" << cnsv[ii].atype << "fl" << floats;
1069  if ( cnsv[ ii ].atype == C_ATYPE_VBAR )
1070  {
1071  ck_sel_vbar->setChecked( true );
1072  ck_sel_vbar->setEnabled( false );
1074  ck_flt_vbar->setChecked( floats );
1075  ck_flt_vbar->setEnabled( not_prod );
1076  }
1077  if ( cnsv[ ii ].atype == C_ATYPE_MW )
1078  {
1079  ck_sel_mw ->setChecked( true );
1080  ck_sel_mw ->setEnabled( not_prod );
1081  check_value( cnsv[ ii ], le_val_mw, le_min_mw, le_max_mw );
1082  ck_flt_mw ->setChecked( floats );
1083  ck_log_mw ->setChecked( cnsv[ ii ].logscl );
1084  ck_flt_mw ->setEnabled( not_prod );
1085  ck_log_mw ->setEnabled( not_prod );
1086  }
1087  if ( cnsv[ ii ].atype == C_ATYPE_FF0 )
1088  {
1089  ck_sel_ff0 ->setChecked( true );
1090  ck_sel_ff0 ->setEnabled( true );
1091  check_value( cnsv[ ii ], le_val_ff0, le_min_ff0, le_max_ff0 );
1092  ck_flt_ff0 ->setChecked( floats );
1093  ck_flt_ff0 ->setEnabled( true );
1094  }
1095  if ( cnsv[ ii ].atype == C_ATYPE_S )
1096  {
1097  ck_sel_s ->setChecked( true );
1098  ck_sel_s ->setEnabled( not_prod );
1099  check_value( cnsv[ ii ], le_val_s, le_min_s, le_max_s );
1100  ck_flt_s ->setChecked( floats );
1101  ck_flt_s ->setEnabled( not_prod );
1102  }
1103  if ( cnsv[ ii ].atype == C_ATYPE_D )
1104  {
1105  ck_sel_D ->setChecked( true );
1106  ck_sel_D ->setEnabled( not_prod );
1107  check_value( cnsv[ ii ], le_val_D, le_min_D, le_max_D );
1108  ck_flt_D ->setChecked( floats );
1109  ck_flt_D ->setEnabled( not_prod );
1110  }
1111  if ( cnsv[ ii ].atype == C_ATYPE_F )
1112  {
1113  ck_sel_f ->setChecked( true );
1114  ck_sel_f ->setEnabled( not_prod );
1115  check_value( cnsv[ ii ], le_val_f, le_min_f, le_max_f );
1116  ck_flt_f ->setChecked( floats );
1117  ck_flt_f ->setEnabled( true );
1118  }
1119  if ( cnsv[ ii ].atype == C_ATYPE_CONC )
1120  {
1122  ck_flt_conc->setChecked( floats );
1123  ck_flt_conc->setEnabled( not_prod );
1124  }
1125  if ( cnsv[ ii ].atype == C_ATYPE_EXT )
1126  {
1127  le_extinction->setText( QString::number( cnsv[ ii ].low ) );
1128  }
1129  if ( is_prod )
1130  {
1131  us_setReadOnly( le_val_vbar, true );
1132  us_setReadOnly( le_min_vbar, true );
1133  us_setReadOnly( le_max_vbar, true );
1134  us_setReadOnly( le_val_mw, true );
1135  us_setReadOnly( le_min_mw, true );
1136  us_setReadOnly( le_max_mw, true );
1137  us_setReadOnly( le_val_conc, true );
1138  us_setReadOnly( le_min_conc, true );
1139  us_setReadOnly( le_max_conc, true );
1140  }
1141  }
1142 
1143  // Set oligomer and reactant,product flags
1144  le_oligomer->setText( QString::number(
1145  cmodel.components[ lcompx[ crow ] ].oligomer ) );
1146  ck_isreact ->setChecked( cmodel.is_reactant( crow ) );
1147  ck_isprod ->setChecked( cmodel.is_product ( crow ) );
1148 
1149  check_selects();
1150  comps_connect( true );
1151 }
1152 
1153 // Slot to populate association attribute values after association change
1155 {
1156 DbgLv(1) << "cnG: association_select row" << srow << arow;
1157  QVector< C_CONSTRAINT > cnsv;
1158 
1159  if ( srow < 0 ) return;
1160 
1161  if ( srow != arow && arow >= 0 )
1162  { // Save settings from previous component screen
1163  save_assoc_settings( arow, cnsv );
1164 
1165  constraints.update_constraints( cnsv );
1166  }
1167 
1168  // Get constraints for new association
1169  arow = srow;
1170  constraints.assoc_constraints( arow, &cnsv, NULL );
1171  assocs_connect( false );
1172 
1173  // Populate association attribute values
1174  ck_flt_kd ->setChecked( false );
1175  ck_flt_koff->setChecked( false );
1176  ck_log_kd ->setChecked( false );
1177  ck_log_koff->setChecked( false );
1178 
1179  for ( int ii = 0; ii < cnsv.size(); ii++ )
1180  {
1181  bool floats = cnsv[ ii ].floats;
1182  bool logscl = cnsv[ ii ].logscl;
1183 
1184  if ( cnsv[ ii ].atype == C_ATYPE_KD )
1185  {
1186  check_value( cnsv[ ii ], le_val_kd, le_min_kd, le_max_kd );
1187  ck_flt_kd ->setChecked( floats );
1188  ck_log_kd ->setChecked( logscl );
1189  }
1190 
1191  if ( cnsv[ ii ].atype == C_ATYPE_KOFF )
1192  {
1194  ck_flt_koff->setChecked( floats );
1195  ck_log_koff->setChecked( logscl );
1196  }
1197  }
1198 
1199  assocs_connect( true );
1200 }
1201 
1202 // Internal function to save current page's component settings
1204  QVector< C_CONSTRAINT >& cnsv )
1205 {
1206 DbgLv(1) << "cnG: svcs: save_comp_settings crow" << crow;
1207  C_CONSTRAINT cnse;
1208  cnse.mcompx = crow;
1209  bool floats = false;
1210  int kselect = 0;
1211 
1212  // Save any s selection
1213  if ( ck_sel_s ->isChecked() )
1214  {
1215  floats = ck_flt_s ->isChecked();
1216  cnse.atype = C_ATYPE_S;
1217  cnse.low = le_val_s ->text().toDouble();
1218  cnse.low = floats ? le_min_s ->text().toDouble() : cnse.low;
1219  cnse.high = floats ? le_max_s ->text().toDouble() : cnse.low;
1220  cnse.floats = floats;
1221  cnse.logscl = false;
1222  cnsv << cnse;
1223  kselect++;
1224 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "S";
1225  }
1226  // Save any f/f0 selection
1227  if ( ck_sel_ff0 ->isChecked() )
1228  {
1229  floats = ck_flt_ff0 ->isChecked();
1230  cnse.atype = C_ATYPE_FF0;
1231  cnse.low = le_val_ff0 ->text().toDouble();
1232  cnse.low = floats ? le_min_ff0 ->text().toDouble() : cnse.low;
1233  cnse.high = floats ? le_max_ff0 ->text().toDouble() : cnse.low;
1234  cnse.floats = floats;
1235  cnse.logscl = false;
1236  cnsv << cnse;
1237  kselect++;
1238 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "FF0";
1239  }
1240  // Save any mw selection
1241  if ( ck_sel_mw ->isChecked() )
1242  {
1243  floats = ck_flt_mw ->isChecked();
1244  cnse.atype = C_ATYPE_MW;
1245  cnse.low = le_val_mw ->text().toDouble();
1246  cnse.low = floats ? le_min_mw ->text().toDouble() : cnse.low;
1247  cnse.high = floats ? le_max_mw ->text().toDouble() : cnse.low;
1248  cnse.floats = floats;
1249  cnse.logscl = ck_log_mw ->isChecked();
1250  cnsv << cnse;
1251  kselect++;
1252 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "MW";
1253  }
1254  // Save any D selection
1255  if ( ck_sel_D ->isChecked() )
1256  {
1257  floats = ck_flt_D ->isChecked();
1258  cnse.atype = C_ATYPE_D;
1259  cnse.low = le_val_D ->text().toDouble();
1260  cnse.low = floats ? le_min_D ->text().toDouble() : cnse.low;
1261  cnse.high = floats ? le_max_D ->text().toDouble() : cnse.low;
1262  cnse.floats = floats;
1263  cnse.logscl = false;
1264  cnsv << cnse;
1265  kselect++;
1266 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "D";
1267  }
1268  // Save any f selection
1269  if ( ck_sel_f ->isChecked() )
1270  {
1271  floats = ck_flt_f ->isChecked();
1272  cnse.atype = C_ATYPE_F;
1273  cnse.low = le_val_f ->text().toDouble();
1274  cnse.low = floats ? le_min_f ->text().toDouble() : cnse.low;
1275  cnse.high = floats ? le_max_f ->text().toDouble() : cnse.low;
1276  cnse.floats = floats;
1277  cnse.logscl = false;
1278  cnsv << cnse;
1279  kselect++;
1280 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "F";
1281  }
1282 
1283  // Save the vbar constraints
1284  floats = ck_flt_vbar->isChecked();
1285  cnse.atype = C_ATYPE_VBAR;
1286  cnse.low = le_val_vbar->text().toDouble();
1287  cnse.low = floats ? le_min_vbar->text().toDouble() : cnse.low;
1288  cnse.high = floats ? le_max_vbar->text().toDouble() : cnse.low;
1289  cnse.floats = floats;
1290  cnse.logscl = false;
1291  cnsv << cnse;
1292  kselect++;
1293 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "VBAR";
1294 
1295  // Save the concentration constraints
1296  floats = ck_flt_conc->isChecked();
1297  cnse.atype = C_ATYPE_CONC;
1298  cnse.low = le_val_conc->text().toDouble();
1299  cnse.low = floats ? le_min_conc->text().toDouble() : cnse.low;
1300  cnse.high = floats ? le_max_conc->text().toDouble() : cnse.low;
1301  cnse.floats = floats;
1302  cnse.logscl = false;
1303  cnsv << cnse;
1304  kselect++;
1305 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << floats << "CONC";
1306 
1307  // There should be a total of 4 checked
1308  if ( kselect != 4 )
1309  {
1310  qDebug() << "*ERROR* dmGA_Init: component" << cnse.mcompx + 1
1311  << "has" << kselect << "attributes selected (SB 4)";
1312  }
1313 
1314  // Add one more entry for extinction
1315  cnse.atype = C_ATYPE_EXT;
1316  cnse.low = le_extinction->text().toDouble();
1317  cnse.high = cnse.low;
1318  cnse.floats = false;
1319  cnse.logscl = false;
1320  cnsv << cnse;
1321  kselect++;
1322 DbgLv(1) << "cnG: svcs: ks" << kselect << "flt" << cnse.floats << "EXT"
1323  << "cnsv size" << cnsv.size();
1324 }
1325 
1326 // Internal function to save current page's association settings
1328  QVector< C_CONSTRAINT >& cnsv )
1329 {
1330  C_CONSTRAINT cnse;
1331  bool floats = ck_flt_kd ->isChecked();
1332  cnse.mcompx = arow;
1333  cnse.atype = C_ATYPE_KD;
1334  cnse.low = le_val_kd ->text().toDouble();
1335  cnse.low = floats ? le_min_kd ->text().toDouble() : cnse.low;
1336  cnse.high = floats ? le_max_kd ->text().toDouble() : cnse.low;
1337  cnse.floats = floats;
1338  cnse.logscl = ck_log_kd ->isChecked();
1339  cnsv << cnse;
1340 DbgLv(1) << "cnG: svas: ks 1 flt" << floats << "KD";
1341 
1342  floats = ck_flt_koff->isChecked();
1343  cnse.atype = C_ATYPE_KOFF;
1344  cnse.low = le_val_koff->text().toDouble();
1345  cnse.low = floats ? le_min_koff->text().toDouble() : cnse.low;
1346  cnse.high = floats ? le_max_koff->text().toDouble() : cnse.low;
1347  cnse.floats = floats;
1348  cnse.logscl = ck_log_koff->isChecked();
1349  cnsv << cnse;
1350 DbgLv(1) << "cnG: svas: ks 2 flt" << floats << "KOFF";
1351 }
1352 
1353 // Switch between value and low,high based on float check
1355  QLineEdit* le_val, QLineEdit* le_min, QLineEdit* le_max )
1356 {
1357  bool fixed = !floats;
1358 
1359 DbgLv(1) << "cnG:float_par floats" << floats;
1360  if ( floats )
1361  { // Changed to float: at least 1 float, so capable of saving constraints
1362  pb_accept->setEnabled( true);
1363  }
1364 
1365  else
1366  { // Changed to fixed: value only
1367  // Disable Accept if no floats remaining
1368  bool have_fl = false;
1369  have_fl = ( have_fl || ck_flt_vbar->isChecked() );
1370  have_fl = ( have_fl || ck_flt_mw ->isChecked() );
1371  have_fl = ( have_fl || ck_flt_ff0 ->isChecked() );
1372  have_fl = ( have_fl || ck_flt_s ->isChecked() );
1373  have_fl = ( have_fl || ck_flt_D ->isChecked() );
1374  have_fl = ( have_fl || ck_flt_f ->isChecked() );
1375  have_fl = ( have_fl || ck_flt_conc->isChecked() );
1376  have_fl = ( have_fl || ck_flt_kd ->isChecked() );
1377  have_fl = ( have_fl || ck_flt_koff->isChecked() );
1378  pb_accept->setEnabled( have_fl );
1379  }
1380 
1381  le_val->setEnabled( fixed );
1382  le_min->setEnabled( floats );
1383  le_max->setEnabled( floats );
1384  us_setReadOnly( le_val, floats );
1385  us_setReadOnly( le_min, fixed );
1386  us_setReadOnly( le_max, fixed );
1387 }
1388 
1389 // Set value and low,high states based on constraints entry
1391  QLineEdit* le_val, QLineEdit* le_min, QLineEdit* le_max )
1392 {
1393  bool floats = cnse.floats;
1394  bool fixed = !floats;
1395 DbgLv(1) << "cnG:check_value: floats" << floats << "atype" << cnse.atype
1396  << "low high" << cnse.low << cnse.high;
1397 
1398  if ( fixed )
1399  {
1400  le_val->setText( QString::number( cnse.low ) );
1401  double vmin = cnse.low * 0.9;
1402  double vmax = cnse.low * 1.1;
1403  le_min->setText( QString::number( vmin ) );
1404  le_max->setText( QString::number( vmax ) );
1405  }
1406 
1407  else
1408  {
1409  le_min->setText( QString::number( cnse.low ) );
1410  le_max->setText( QString::number( cnse.high ) );
1411  double vval = ( cnse.low + cnse.high ) * 0.5;
1412  le_val->setText( QString::number( vval ) );
1413  }
1414 
1415  us_setReadOnly( le_val, floats );
1416  us_setReadOnly( le_min, fixed );
1417  us_setReadOnly( le_max, fixed );
1418 }
1419 
1420 // Set state of selectable component attributes based on overall picture
1422 {
1423  int kcheck = count_checks();
1424  bool ckd_mw = ck_sel_mw ->isChecked();
1425  bool ckd_ff0 = ck_sel_ff0 ->isChecked();
1426  bool ckd_s = ck_sel_s ->isChecked();
1427  bool ckd_D = ck_sel_D ->isChecked();
1428  bool ckd_f = ck_sel_f ->isChecked();
1429  bool flt_vbar = ck_flt_vbar->isChecked();
1430  bool flt_mw = ck_flt_mw ->isChecked();
1431  bool flt_ff0 = ck_flt_ff0 ->isChecked();
1432  bool flt_s = ck_flt_s ->isChecked();
1433  bool flt_D = ck_flt_D ->isChecked();
1434  bool flt_f = ck_flt_f ->isChecked();
1435  bool flt_any = flt_vbar || flt_mw || flt_ff0 || flt_s || flt_D || flt_f;
1436 DbgLv(1) << "cnG:check_selects kcheck" << kcheck << "flt_any" << flt_any;
1437 
1438  // Read-only based on selected state
1439  us_setReadOnly( le_val_mw , ( !ckd_mw || flt_mw ) );
1440  us_setReadOnly( le_min_mw , ( !ckd_mw || !flt_mw ) );
1441  us_setReadOnly( le_max_mw , ( !ckd_mw || !flt_mw ) );
1442  us_setReadOnly( le_val_ff0, ( !ckd_ff0 || flt_ff0 ) );
1443  us_setReadOnly( le_min_ff0, ( !ckd_ff0 || !flt_ff0 ) );
1444  us_setReadOnly( le_max_ff0, ( !ckd_ff0 || !flt_ff0 ) );
1445  us_setReadOnly( le_val_s , ( !ckd_s || flt_s ) );
1446  us_setReadOnly( le_min_s , ( !ckd_s || !flt_s ) );
1447  us_setReadOnly( le_max_s , ( !ckd_s || !flt_s ) );
1448  us_setReadOnly( le_val_D , ( !ckd_D || flt_D ) );
1449  us_setReadOnly( le_min_D , ( !ckd_D || !flt_D ) );
1450  us_setReadOnly( le_max_D , ( !ckd_D || !flt_D ) );
1451  us_setReadOnly( le_val_f , ( !ckd_f || flt_f ) );
1452  us_setReadOnly( le_min_f , ( !ckd_f || !flt_f ) );
1453  us_setReadOnly( le_max_f , ( !ckd_f || !flt_f ) );
1454 
1455  if ( kcheck == 2 )
1456  { // Right number of attributes are selected
1457  int ksel = 0;
1459  scva.vbar20 = 0.0;
1460  scva.mw = 0.0;
1461  scva.s = 0.0;
1462  scva.D = 0.0;
1463  scva.f = 0.0;
1464  scva.f_f0 = 0.0;
1465  US_Model::SimulationComponent scll = scva;
1466  US_Model::SimulationComponent schh = scva;
1467  US_Model::SimulationComponent sclh = scva;
1468  US_Model::SimulationComponent schl = scva;
1469 DbgLv(1) << "cnG:ck_sels: ff0 B0" << scva.f_f0;
1470 
1471  // Set the selected component values
1472  scva.vbar20 = le_val_vbar->text().toDouble();
1473  scll.vbar20 = le_min_vbar->text().toDouble();
1474  schh.vbar20 = le_max_vbar->text().toDouble();
1475 
1476  sclh.vbar20 = scll.vbar20;
1477  schl.vbar20 = schh.vbar20;
1478 DbgLv(1) << "cnG:ck_sels: ff0 B1" << scva.f_f0;
1479 
1480  if ( ckd_mw )
1481  {
1482  scva.mw = le_val_mw ->text().toDouble();
1483  scll.mw = le_min_mw ->text().toDouble();
1484  schh.mw = le_max_mw ->text().toDouble();
1485  sclh.mw = scll.mw;
1486  schl.mw = schh.mw;
1487  ksel++;
1488  }
1489 
1490  if ( ckd_ff0 )
1491  {
1492  scva.f_f0 = le_val_ff0->text().toDouble();
1493  scll.f_f0 = le_min_ff0->text().toDouble();
1494  schh.f_f0 = le_max_ff0->text().toDouble();
1495  sclh.f_f0 = ( ksel == 0 ) ? scll.f_f0 : schh.f_f0;
1496  schl.f_f0 = ( ksel == 0 ) ? schh.f_f0 : scll.f_f0;
1497  ksel++;
1498  }
1499 DbgLv(1) << "cnG:ck_sels: ff0 B3" << scva.f_f0;
1500 
1501  if ( ckd_s )
1502  {
1503  scva.s = le_val_s ->text().toDouble();
1504  scll.s = le_min_s ->text().toDouble();
1505  schh.s = le_max_s ->text().toDouble();
1506  sclh.s = ( ksel == 0 ) ? scll.s : schh.s ;
1507  schl.s = ( ksel == 0 ) ? schh.s : scll.s ;
1508  ksel++;
1509  }
1510 
1511  if ( ckd_D )
1512  {
1513  scva.D = le_val_D ->text().toDouble();
1514  scll.D = le_min_D ->text().toDouble();
1515  schh.D = le_max_D ->text().toDouble();
1516  sclh.D = ( ksel == 0 ) ? scll.D : schh.D ;
1517  schl.D = ( ksel == 0 ) ? schh.D : scll.D ;
1518  ksel++;
1519  }
1520 DbgLv(1) << "cnG:ck_sels: ff0 B6" << scva.f_f0;
1521 
1522  if ( ckd_f )
1523  {
1524  scva.f = le_val_f ->text().toDouble();
1525  scll.f = le_min_f ->text().toDouble();
1526  schh.f = le_max_f ->text().toDouble();
1527  sclh.f = ( ksel == 0 ) ? scll.f : schh.f ;
1528  schl.f = ( ksel == 0 ) ? schh.f : scll.f ;
1529  ksel++;
1530  }
1531 
1532  // Compute unselected values
1533 DbgLv(1) << "cnG:ck_sels: ff0 BEF" << scva.f_f0 << scll.f_f0 << schh.f_f0
1534  << sclh.f_f0 << schl.f_f0 << "ksel" << ksel;
1540 DbgLv(1) << "cnG:ck_sels: ff0 AFT" << scva.f_f0 << scll.f_f0 << schh.f_f0
1541  << sclh.f_f0 << schl.f_f0;
1542 
1543  // Fill unselected attribute value fields
1544  if ( !ckd_mw )
1545  {
1546  double vmin = qMin( scll.mw, sclh.mw );
1547  double vmax = qMax( scll.mw, sclh.mw );
1548  vmin = qMin( vmin, qMin( schh.mw, schl.mw ) );
1549  vmax = qMax( vmax, qMax( schh.mw, schl.mw ) );
1550  le_val_mw ->setText( QString::number( scva.mw ) );
1551  le_min_mw ->setText( QString::number( vmin ) );
1552  le_max_mw ->setText( QString::number( vmax ) );
1553  }
1554 
1555  if ( !ckd_ff0 )
1556  {
1557  double vmin = qMin( scll.f_f0, sclh.f_f0 );
1558  double vmax = qMax( scll.f_f0, sclh.f_f0 );
1559  vmin = qMin( vmin, qMin( schh.f_f0, schl.f_f0 ) );
1560  vmax = qMax( vmax, qMax( schh.f_f0, schl.f_f0 ) );
1561  le_val_ff0->setText( QString::number( scva.f_f0 ) );
1562  le_min_ff0->setText( QString::number( vmin ) );
1563  le_max_ff0->setText( QString::number( vmax ) );
1564  }
1565 
1566  if ( !ckd_s )
1567  {
1568  double vmin = qMin( scll.s, sclh.s );
1569  double vmax = qMax( scll.s, sclh.s );
1570  vmin = qMin( vmin, qMin( schh.s, schl.s ) );
1571  vmax = qMax( vmax, qMax( schh.s, schl.s ) );
1572  le_val_s ->setText( QString::number( scva.s ) );
1573  le_min_s ->setText( QString::number( vmin ) );
1574  le_max_s ->setText( QString::number( vmax ) );
1575 DbgLv(1) << "cnG:check_selects !CKD_S flt_any" << flt_any;
1576  }
1577 
1578  if ( !ckd_D )
1579  {
1580  double vmin = qMin( scll.D, sclh.D );
1581  double vmax = qMax( scll.D, sclh.D );
1582  vmin = qMin( vmin, qMin( schh.D, schl.D ) );
1583  vmax = qMax( vmax, qMax( schh.D, schl.D ) );
1584  le_val_D ->setText( QString::number( scva.D ) );
1585  le_min_D ->setText( QString::number( vmin ) );
1586  le_max_D ->setText( QString::number( vmax ) );
1587  }
1588 
1589  if ( !ckd_f )
1590  {
1591  double vmin = qMin( scll.f, sclh.f );
1592  double vmax = qMax( scll.f, sclh.f );
1593  vmin = qMin( vmin, qMin( schh.f, schl.f ) );
1594  vmax = qMax( vmax, qMax( schh.f, schl.f ) );
1595  le_val_f ->setText( QString::number( scva.f ) );
1596  le_min_f ->setText( QString::number( vmin ) );
1597  le_max_f ->setText( QString::number( vmax ) );
1598  }
1599 
1600  // Only enable checks to be unchecked
1601  ck_sel_mw ->setEnabled( ckd_mw );
1602  ck_sel_ff0->setEnabled( ckd_ff0 );
1603  ck_sel_s ->setEnabled( ckd_s );
1604  ck_sel_D ->setEnabled( ckd_D );
1605  ck_sel_f ->setEnabled( ckd_f );
1606  }
1607 
1608  else
1609  { // Attribute newly unselected, enable ability to check a different one
1610  ck_sel_mw ->setEnabled( true );
1611  ck_sel_ff0->setEnabled( true );
1612  ck_sel_s ->setEnabled( true );
1613  ck_sel_D ->setEnabled( true );
1614  ck_sel_f ->setEnabled( true );
1615  }
1616 DbgLv(1) << "cnG:check_selects END";
1617 }
1618 
1619 // Get the value of a specified type in a constraints record
1621  QVector< C_CONSTRAINT >& cnsv )
1622 {
1623  double cval = 0.0;
1624 
1625  for ( int ii = 0; ii < cnsv.size(); ii++ )
1626  {
1627  if ( cnsv[ ii ].atype == atype )
1628  { // Found the type: return its value or range average
1629  double cmin = cnsv[ ii ].low;
1630  double cmax = cnsv[ ii ].high;
1631 
1632  if ( cnsv[ ii ].floats )
1633  {
1634  cval = cnsv[ ii ].logscl
1635  ? exp( ( log( cmin ) + log( cmax ) ) * 0.5 )
1636  : ( ( cmin + cmax ) * 0.5 );
1637  }
1638 
1639  else
1640  {
1641  cval = cmin;
1642  }
1643  break;
1644  }
1645  }
1646 
1647  return cval;
1648 
1649 }
1650