UltraScan III
us_analysis_control_pc.cpp
Go to the documentation of this file.
1 
3 #include "us_pcsa.h"
5 #include "us_adv_analysis_pc.h"
6 #include "us_simparms.h"
7 #include "us_rpscan.h"
8 #include "us_settings.h"
9 #include "us_passwd.h"
10 #include "us_db2.h"
11 #include "us_gui_settings.h"
12 #include "us_memory.h"
13 
14 // constructor: pcsa analysis controls widget
16  QList< US_SolveSim::DataSet* >& dsets, QWidget* p )
17  : US_WidgetsDialog( p, 0 ), dsets( dsets )
18 {
19  parentw = p;
20  processor = 0;
22  varimin = 9e+99;
23  bmndx = -1;
24  mlnplotd = 0;
25  fitpars = QString();
27  << CTYPE_ALL;
28  attr_x = 0;
29  attr_y = 1;
30  attr_z = 3;
31  sol_type = ( attr_x << 6 ) + ( attr_y << 3 ) + attr_z;
32 
33  if ( parentw )
34  { // Get pointers to needed objects from the main
35  US_pcsa* mainw = (US_pcsa*)parentw;
36  edata = mainw->mw_editdata();
37  sdata = mainw->mw_simdata();
38  rdata = mainw->mw_resdata();
39  model = mainw->mw_model();
40  ti_noise = mainw->mw_ti_noise();
41  ri_noise = mainw->mw_ri_noise();
42  mw_stattext = mainw->mw_status_text();
43  mw_modstats = mainw->mw_model_stats();
44  mw_mrecs = mainw->mw_mrecs();
45  mw_mrecs_mc = mainw->mw_mrecs_mc();
46  mw_baserss = mainw->mw_base_rss();
47 DbgLv(1) << "AnaC: edata scans" << edata->scanData.size();
48  }
49  else
50  { // Aarrggg! No pointer back to parent!!!
51  DbgLv(0) << "*ERROR* AnalysisControl has no pointer back to Main PCSA";
52  QMessageBox::critical( this, tr( "Parent Pointer NULL!" ),
53  tr( "*ERROR* AnalysisControl has no pointer back to Main PCSA" ) );
54  close();
55  return;
56  }
57 
58  setObjectName( "US_AnalysisControlPc" );
59  setAttribute( Qt::WA_DeleteOnClose, true );
60  setPalette( US_GuiSettings::frameColor() );
61  setFont( QFont( US_GuiSettings::fontFamily(),
63  QFontMetrics fmet( font() );
64 
65  // lay out the GUI
66  setWindowTitle(
67  tr( "Parametrically Constrained Spectrum Analysis Controls" ) );
68 
69  mainLayout = new QHBoxLayout( this );
70  controlsLayout = new QGridLayout( );
71  optimizeLayout = new QGridLayout( );
72 
73  mainLayout->setSpacing ( 2 );
74  mainLayout->setContentsMargins( 2, 2, 2, 2 );
75 
76  mainLayout->addLayout( controlsLayout );
77  mainLayout->addLayout( optimizeLayout );
78 
79  QLabel* lb_fitting = us_banner( tr( "Fitting Controls:" ) );
80  QLabel* lb_curvtype = us_label( tr( "Curve Type:" ) );
81  QLabel* lb_x_type = us_label( tr( "X Axis Type:" ) );
82  QLabel* lb_y_type = us_label( tr( "Y Axis Type:" ) );
83  QLabel* lb_z_type = us_label( tr( "Z Axis Type:" ) );
84  QLabel* lb_z_value = us_label( tr( "Z Value/Coeffs." ) );
85  QLabel* lb_range_x = us_label( tr( "X range:" ) );
86  QLabel* lb_range_y = us_label( tr( "Y range:" ) );
87  QLabel* lb_varcount = us_label( tr( "Variations Count:" ) );
88  QLabel* lb_gfiters = us_label( tr( "Grid Fit Iterations:" ) );
89  QLabel* lb_gfthresh = us_label( tr( "Threshold Delta-RMSD Ratio:" ) );
90  QLabel* lb_cresolu = us_label( tr( "Curve Resolution Points:" ) );
91  QLabel* lb_lmmxcall = us_label( tr( "Maximum L-M Evaluate Calls:" ) );
92  QLabel* lb_tralpha = us_label( tr( "Regularization Parameter:" ) );
93  QLabel* lb_thrdcnt = us_label( tr( "Thread Count:" ) );
94  QLabel* lb_minvari = us_label( tr( "Best Model Variance:" ) );
95  QLabel* lb_minrmsd = us_label( tr( "Best Model RMSD:" ) );
96  QLabel* lb_status = us_label( tr( "Status:" ) );
97  bg_x_axis = new QButtonGroup( this );
98  bg_y_axis = new QButtonGroup( this );
99  QGridLayout* gl_x_s = us_radiobutton( tr( "s" ), rb_x_s, true );
100  QGridLayout* gl_x_ff0 = us_radiobutton( tr( "f/f0" ), rb_x_ff0, false );
101  QGridLayout* gl_x_mw = us_radiobutton( tr( "mw" ), rb_x_mw, false );
102  QGridLayout* gl_x_vbar = us_radiobutton( tr( "vbar" ), rb_x_vbar, false );
103  QGridLayout* gl_x_D = us_radiobutton( tr( "D" ), rb_x_D, false );
104  QGridLayout* gl_y_s = us_radiobutton( tr( "s" ), rb_y_s, false );
105  QGridLayout* gl_y_ff0 = us_radiobutton( tr( "f/f0" ), rb_y_ff0, true );
106  QGridLayout* gl_y_mw = us_radiobutton( tr( "mw" ), rb_y_mw, false );
107  QGridLayout* gl_y_vbar = us_radiobutton( tr( "vbar" ), rb_y_vbar, false );
108  QGridLayout* gl_y_D = us_radiobutton( tr( "D" ), rb_y_D, false );
109  le_z_func = us_lineedit( "0.0", -1, false );
110  bg_x_axis->addButton( rb_x_s, ATTR_S );
111  bg_x_axis->addButton( rb_x_ff0, ATTR_K );
112  bg_x_axis->addButton( rb_x_mw, ATTR_W );
113  bg_x_axis->addButton( rb_x_vbar, ATTR_V );
114  bg_x_axis->addButton( rb_x_D, ATTR_D );
115  bg_y_axis->addButton( rb_y_s, ATTR_S );
116  bg_y_axis->addButton( rb_y_ff0, ATTR_K );
117  bg_y_axis->addButton( rb_y_mw, ATTR_W );
118  bg_y_axis->addButton( rb_y_vbar, ATTR_V );
119  bg_y_axis->addButton( rb_y_D, ATTR_D );
120  rb_x_s ->setChecked( true );
121  rb_y_ff0 ->setChecked( true );
122  rb_y_s ->setEnabled( false );
123 
124  QLabel* lb_statinfo = us_banner( tr( "Status Information:" ) );
125 
126  pb_pltlines = us_pushbutton( tr( "Plot Model Lines" ), true );
127  pb_startfit = us_pushbutton( tr( "Start Fit" ), true );
128  pb_scanregp = us_pushbutton( tr( "Perform Regularization Scan" ), false );
129  pb_finalmdl = us_pushbutton( tr( "Recompute Best Model" ), false );
130  pb_stopfit = us_pushbutton( tr( "Stop Fit" ), false );
131  pb_plot = us_pushbutton( tr( "Plot Results" ), false );
132  pb_save = us_pushbutton( tr( "Save Results" ), false );
133  pb_advanaly = us_pushbutton( tr( "Advanced Controls" ), true );
134  pb_help = us_pushbutton( tr( "Help" ) );
135  pb_close = us_pushbutton( tr( "Close" ) );
137  us_setReadOnly( te_status, true );
138 
139  QLayout* lo_lmalpha =
140  us_checkbox( tr( "Regularize in L-M Fits" ), ck_lmalpha );
141  QLayout* lo_fxalpha =
142  us_checkbox( tr( "Regularize in Grid Fits" ), ck_fxalpha );
143  QLayout* lo_tinois =
144  us_checkbox( tr( "Fit Time-Invariant Noise" ), ck_tinoise );
145  QLayout* lo_rinois =
146  us_checkbox( tr( "Fit Radially-Invariant Noise" ), ck_rinoise );
147  ck_fxalpha ->setEnabled( false );
148  ck_lmalpha ->setEnabled( false );
149 
150  int nthr = US_Settings::threads();
151  nthr = ( nthr > 1 ) ? nthr : QThread::idealThreadCount();
152 DbgLv(1) << "idealThrCout" << nthr;
153  ct_lolimitx = us_counter( 2, -10000, 10000, 1 );
154  ct_uplimitx = us_counter( 3, -10000, 10000, 10 );
155  ct_lolimity = us_counter( 2, 1, 8, 1 );
156  ct_uplimity = us_counter( 3, 1, 100, 5 );
157  ct_varcount = us_counter( 2, 3, 200, 6 );
158  ct_gfiters = us_counter( 2, 1, 20, 3 );
159  ct_gfthresh = us_counter( 3, 1.e-6, 1.e-2, 1e-4 );
160  ct_lmmxcall = us_counter( 2, 0, 200, 0 );
161  ct_cresolu = us_counter( 2, 20, 501, 100 );
162  ct_thrdcnt = us_counter( 2, 1, 64, nthr );
163  ct_tralpha = us_counter( 3, 0, 100, 0 );
164  ct_lolimitx->setStep( 0.1 );
165  ct_uplimitx->setStep( 0.1 );
166  ct_lolimity->setStep( 0.01 );
167  ct_uplimity->setStep( 0.01 );
168  ct_varcount->setStep( 1 );
169  ct_gfiters ->setStep( 1 );
170  ct_gfthresh->setStep( 1.e-6 );
171  ct_lmmxcall->setStep( 1 );
172  ct_cresolu ->setStep( 1 );
173  ct_tralpha ->setStep( 0.001 );
174  ct_thrdcnt ->setStep( 1 );
176  cb_curvtype->addItem( "Straight Line" );
177  cb_curvtype->addItem( "Increasing Sigmoid" );
178  cb_curvtype->addItem( "Decreasing Sigmoid" );
179  cb_curvtype->addItem( "Horizontal Line [ C(s) ]" );
180  cb_curvtype->addItem( "Second-Order Power Law" );
181  cb_curvtype->setCurrentIndex( 1 );
183  cb_z_type ->addItem( "vbar" );
184  cb_z_type ->addItem( "f/f0" );
185  cb_z_type ->addItem( "mw" );
186  cb_z_type ->setCurrentIndex( 0 );
187 
188  le_minvari = us_lineedit( "0.000e-05", -1, true );
189  le_minrmsd = us_lineedit( "0.009000" , -1, true );
190 
191  b_progress = us_progressBar( 0, 100, 0 );
192 
193  int row = 0;
194  controlsLayout->addWidget( lb_fitting, row++, 0, 1, 6 );
195  controlsLayout->addWidget( lb_curvtype, row, 0, 1, 2 );
196  controlsLayout->addWidget( cb_curvtype, row++, 2, 1, 4 );
197  controlsLayout->addWidget( lb_x_type, row, 0, 1, 1 );
198  controlsLayout->addLayout( gl_x_s, row, 1, 1, 1 );
199  controlsLayout->addLayout( gl_x_ff0, row, 2, 1, 1 );
200  controlsLayout->addLayout( gl_x_mw, row, 3, 1, 1 );
201  controlsLayout->addLayout( gl_x_vbar, row, 4, 1, 1 );
202  controlsLayout->addLayout( gl_x_D, row++, 5, 1, 1 );
203  controlsLayout->addWidget( lb_y_type, row, 0, 1, 1 );
204  controlsLayout->addLayout( gl_y_s, row, 1, 1, 1 );
205  controlsLayout->addLayout( gl_y_ff0, row, 2, 1, 1 );
206  controlsLayout->addLayout( gl_y_mw, row, 3, 1, 1 );
207  controlsLayout->addLayout( gl_y_vbar, row, 4, 1, 1 );
208  controlsLayout->addLayout( gl_y_D, row++, 5, 1, 1 );
209  controlsLayout->addWidget( lb_z_type, row, 0, 1, 1 );
210  controlsLayout->addWidget( cb_z_type, row, 1, 1, 1 );
211  controlsLayout->addWidget( lb_z_value, row, 2, 1, 2 );
212  controlsLayout->addWidget( le_z_func, row++, 4, 1, 2 );
213  controlsLayout->addWidget( lb_range_x, row, 0, 1, 1 );
214  controlsLayout->addWidget( ct_lolimitx, row, 1, 1, 2 );
215  controlsLayout->addWidget( ct_uplimitx, row++, 3, 1, 3 );
216  controlsLayout->addWidget( lb_range_y, row, 0, 1, 1 );
217  controlsLayout->addWidget( ct_lolimity, row, 1, 1, 2 );
218  controlsLayout->addWidget( ct_uplimity, row++, 3, 1, 3 );
219  controlsLayout->addWidget( lb_varcount, row, 0, 1, 3 );
220  controlsLayout->addWidget( ct_varcount, row++, 3, 1, 3 );
221  controlsLayout->addWidget( lb_gfiters, row, 0, 1, 3 );
222  controlsLayout->addWidget( ct_gfiters, row++, 3, 1, 3 );
223  controlsLayout->addWidget( lb_gfthresh, row, 0, 1, 3 );
224  controlsLayout->addWidget( ct_gfthresh, row++, 3, 1, 3 );
225  controlsLayout->addWidget( lb_cresolu, row, 0, 1, 3 );
226  controlsLayout->addWidget( ct_cresolu, row++, 3, 1, 3 );
227  controlsLayout->addWidget( lb_lmmxcall, row, 0, 1, 3 );
228  controlsLayout->addWidget( ct_lmmxcall, row++, 3, 1, 3 );
229  controlsLayout->addWidget( lb_tralpha, row, 0, 1, 3 );
230  controlsLayout->addWidget( ct_tralpha, row++, 3, 1, 3 );
231  controlsLayout->addWidget( lb_thrdcnt, row, 0, 1, 3 );
232  controlsLayout->addWidget( ct_thrdcnt, row++, 3, 1, 3 );
233  controlsLayout->addLayout( lo_lmalpha, row, 0, 1, 3 );
234  controlsLayout->addWidget( pb_startfit, row++, 3, 1, 3 );
235  controlsLayout->addLayout( lo_fxalpha, row, 0, 1, 3 );
236  controlsLayout->addWidget( pb_stopfit, row++, 3, 1, 3 );
237  controlsLayout->addLayout( lo_tinois, row, 0, 1, 3 );
238  controlsLayout->addWidget( pb_scanregp, row++, 3, 1, 3 );
239  controlsLayout->addLayout( lo_rinois, row, 0, 1, 3 );
240  controlsLayout->addWidget( pb_finalmdl, row++, 3, 1, 3 );
241  controlsLayout->addWidget( pb_plot, row, 0, 1, 3 );
242  controlsLayout->addWidget( pb_save, row++, 3, 1, 3 );
243  controlsLayout->addWidget( pb_advanaly, row++, 0, 1, 6 );
244  controlsLayout->addWidget( pb_pltlines, row, 0, 1, 2 );
245  controlsLayout->addWidget( pb_help, row, 2, 1, 2 );
246  controlsLayout->addWidget( pb_close, row++, 4, 1, 2 );
247  controlsLayout->addWidget( lb_status, row, 0, 1, 1 );
248  controlsLayout->addWidget( b_progress, row++, 1, 1, 5 );
249  QLabel* lb_optspace1 = us_banner( "" );
250  controlsLayout->addWidget( lb_optspace1, row, 0, 1, 6 );
251  controlsLayout->setRowStretch( row, 2 );
252 
253  row = 0;
254  optimizeLayout->addWidget( lb_minvari, row, 0, 1, 2 );
255  optimizeLayout->addWidget( le_minvari, row++, 2, 1, 2 );
256  optimizeLayout->addWidget( lb_minrmsd, row, 0, 1, 2 );
257  optimizeLayout->addWidget( le_minrmsd, row++, 2, 1, 2 );
258  optimizeLayout->addWidget( lb_statinfo, row++, 0, 1, 4 );
259  optimizeLayout->addWidget( te_status, row, 0, 8, 4 );
260  le_minrmsd->setMinimumWidth( lb_minrmsd->width() );
261  te_status ->setMinimumWidth( lb_minrmsd->width()*4 );
262  row += 8;
263 
264  edata = &dsets[ 0 ]->run_data;
265  double vbar = dsets[ 0 ]->vbar20;
266  le_z_func->setText( QString::number( vbar ) );
267 
268  QLabel* lb_optspace = us_banner( "" );
269  optimizeLayout->addWidget( lb_optspace, row, 0, 1, 4 );
270 
272 
273  fitpars_connect( true );
274 
275  connect( ct_tralpha, SIGNAL( valueChanged( double ) ),
276  this, SLOT( set_alpha () ) );
277 
278  connect( pb_pltlines, SIGNAL( clicked() ),
279  this, SLOT( plot_lines() ) );
280  connect( pb_startfit, SIGNAL( clicked() ),
281  this, SLOT( fit_final() ) );
282  connect( pb_scanregp, SIGNAL( clicked() ),
283  this, SLOT( scan_alpha() ) );
284  connect( pb_finalmdl, SIGNAL( clicked() ),
285  this, SLOT( final_only() ) );
286  connect( pb_stopfit, SIGNAL( clicked() ),
287  this, SLOT( stop_fit() ) );
288  connect( pb_plot, SIGNAL( clicked() ),
289  this, SLOT( plot() ) );
290  connect( pb_save, SIGNAL( clicked() ),
291  this, SLOT( save() ) );
292  connect( pb_advanaly, SIGNAL( clicked() ),
293  this, SLOT( advanced() ) );
294  connect( pb_help, SIGNAL( clicked() ),
295  this, SLOT( help() ) );
296  connect( pb_close, SIGNAL( clicked() ),
297  this, SLOT( close_all() ) );
298 
299  pb_pltlines->setEnabled( false );
300  compute();
301 
302 //DbgLv(1) << "Pre-resize AC size" << size();
303  int fwidth = fmet.maxWidth();
304  int rheight = ct_lolimitx->height();
305  int cminw = fwidth * 7;
306  int csizw = cminw + fwidth;
307  ct_lolimitx->setMinimumWidth( cminw );
308  ct_uplimitx->setMinimumWidth( cminw );
309  ct_lolimity->setMinimumWidth( cminw );
310  ct_uplimity->setMinimumWidth( cminw );
311  ct_varcount->setMinimumWidth( cminw );
312  ct_gfiters ->setMinimumWidth( cminw );
313  ct_gfthresh->setMinimumWidth( cminw );
314  ct_lmmxcall->setMinimumWidth( cminw );
315  ct_cresolu ->setMinimumWidth( cminw );
316  ct_thrdcnt ->setMinimumWidth( cminw );
317  ct_lolimitx->resize( csizw, rheight );
318  ct_uplimitx->resize( csizw, rheight );
319  ct_lolimity->resize( csizw, rheight );
320  ct_uplimity->resize( csizw, rheight );
321  ct_varcount->resize( csizw, rheight );
322  ct_gfiters ->resize( csizw, rheight );
323  ct_gfthresh->resize( csizw, rheight );
324  ct_lmmxcall->resize( csizw, rheight );
325  ct_cresolu ->resize( csizw, rheight );
326  ct_thrdcnt ->resize( csizw, rheight );
327 
328  resize( 710, 440 );
329  qApp->processEvents();
330 
331 //DbgLv(1) << "Post-resize AC size" << size();
332 }
333 
334 // enable/disable optimize counters based on chosen method
336 {
337  bool use_noise = ( ct_tralpha->value() == 0.0 );
338  ck_tinoise ->setEnabled( use_noise );
339  ck_rinoise ->setEnabled( use_noise );
340 
341  adjustSize();
342  qApp->processEvents();
343 }
344 
345 // uncheck optimize options other than one just checked
347 {
348 }
349 
350 // start fit button clicked
352 {
353  US_pcsa* mainw = (US_pcsa*)parentw;
354  mainw->analysis_done( -1 ); // Reset counters to zero
355 
356  // Make sure that ranges are reasonable
357  if ( ( ct_uplimitx->value() - ct_lolimitx->value() ) < 0.0 ||
358  ( ct_uplimity->value() - ct_lolimity->value() ) < 0.0 )
359  {
360  QString msg =
361  tr( "The \"s\" or \"f/f0\" ranges are inconsistent.\n"
362  "Please re-check the limits and correct them\n"
363  "before again clicking \"Start Fit\"." );
364 
365  QMessageBox::critical( this, tr( "Limits Inconsistent!" ), msg );
366  return;
367  }
368 
369  // Start a processing object if need be
370  if ( processor == 0 )
371  {
372  need_fit = true;
373  need_final = true;
374  dsets[ 0 ]->solute_type = sol_type;
375  dsets[ 0 ]->zcoeffs[ 0 ] = le_z_func->text().section( " ", 0, 0 )
376  .toDouble();
377  dsets[ 0 ]->zcoeffs[ 1 ] = 0.0;
378  dsets[ 0 ]->zcoeffs[ 2 ] = 0.0;
379  dsets[ 0 ]->zcoeffs[ 3 ] = 0.0;
380 DbgLv(1) << "AnaC: (A)zcoeff0" << dsets[0]->zcoeffs[0];
381 
382  processor = new US_pcsaProcess( dsets, this );
383  }
384 
385  else
386  {
387  processor->disconnect();
388  if ( need_fit )
389  {
390  processor->stop_fit();
392  }
393  }
394 
395  // Check that fit as parameterized will not exceed memory
396  sdata ->scanData.clear();
397  rdata ->scanData.clear();
398  mw_mrecs ->clear();
399  mw_mrecs_mc->clear();
400  mrecs .clear();
401 
402  if ( memory_check() )
403  return;
404 
405  // Check implied grid size does not exceed limits
406  set_solute_type();
407  QString smsg;
408  double s_max = ct_uplimitx->value() * 1.0e-13;
409 
410  if ( attr_x == US_ZSolute::ATTR_S &&
411  US_SolveSim::checkGridSize( dsets, s_max, smsg ) )
412  {
413  QMessageBox::critical( this,
414  tr( "Implied Grid Size is Too Large!" ), smsg );
415  return;
416  }
417 
418  // Set up for the start of fit processing
419  varimin = 9e+99;
420  bmndx = -1;
421  le_minvari ->setText( "0.000e-05" );
422  le_minrmsd ->setText( "0.0000" );
423 
424  int typ = ctypes[ cb_curvtype->currentIndex() ];
425  double slo = ct_lolimitx->value();
426  double sup = ct_uplimitx->value();
427  double klo = ct_lolimity->value();
428  double kup = ct_uplimity->value();
429  int nthr = (int)ct_thrdcnt ->value();
430  int nvar = (int)ct_varcount->value();
431  int noif = ( ck_tinoise->isChecked() ? 1 : 0 ) +
432  ( ck_rinoise->isChecked() ? 2 : 0 );
433  int res = (int)ct_cresolu ->value();
434  double gfthr = ct_gfthresh->value();
435  int gfits = (int)ct_gfiters ->value();
436  int lmmxc = (int)ct_lmmxcall->value();
437  double alpha = ct_tralpha ->value();
438 
439  // Alpha-scan completed: test if we need to re-fit
440 DbgLv(1) << "AnaC: (1)need_fit" << need_fit;
441  need_fit = ( fitpars_string() != fitpars );
442 DbgLv(1) << "AnaC: (2)need_fit" << need_fit;
443 
444  if ( need_fit )
445  { // Not resuming after an Alpha scan
446  if ( ! need_final )
447  alpha = -99.0; // Flag Alpha scan
448  else if ( ck_fxalpha->isChecked() && alpha != 0.0 )
449  alpha = -alpha - 1.0; // Flag use-alpha-for-fixed-fits
450  else if ( ck_lmalpha->isChecked() && alpha != 0.0 )
451  alpha = -alpha; // Flag use-alpha-for-LM-fits
452 
453  mrecs.clear();
454  }
455 DbgLv(1) << "AnaC: need_fit need_fnl" << need_fit << need_final
456  << "alpha" << alpha;
457 
458  ti_noise->values.clear();
459  ri_noise->values.clear();
460  ti_noise->count = 0;
461  ri_noise->count = 0;
462 
463  nctotal = 10000;
464 
465  connect( processor, SIGNAL( progress_update( double ) ),
466  this, SLOT( update_progress( double ) ) );
467  connect( processor, SIGNAL( message_update( QString, bool ) ),
468  this, SLOT( progress_message( QString, bool ) ) );
469  connect( processor, SIGNAL( stage_complete( int, int ) ),
470  this, SLOT( reset_steps( int, int ) ) );
471  connect( processor, SIGNAL( process_complete( int ) ),
472  this, SLOT( completed_process( int ) ) );
473 
474  // Begin or resume the fit
475  pb_startfit->setEnabled( false );
476  pb_scanregp->setEnabled( false );
477  pb_finalmdl->setEnabled( false );
478  pb_stopfit ->setEnabled( true );
479  pb_plot ->setEnabled( false );
480 DbgLv(1) << "(2)pb_plot-Enabled" << pb_plot->isEnabled();
481  pb_save ->setEnabled( false );
482  qApp->processEvents();
483 
484  if ( need_fit )
485  processor->start_fit( slo, sup, klo, kup, nvar, res, typ,
486  nthr, noif, lmmxc, gfits, gfthr, alpha );
487 
488  else if ( need_final )
489  processor->final_fit( alpha );
490 
491  qApp->processEvents();
492 }
493 
494 // stop fit button clicked
496 {
497 DbgLv(1) << "AC:SF:StopFit";
498  b_progress->reset();
499 
500  pb_startfit->setEnabled( true );
501  pb_scanregp->setEnabled( true );
502  pb_finalmdl->setEnabled( true );
503  pb_stopfit ->setEnabled( false );
504  pb_plot ->setEnabled( false );
505  pb_save ->setEnabled( false );
506  qApp->processEvents();
507 DbgLv(1) << "(3)pb_plot-Enabled" << pb_plot->isEnabled();
508 
509  US_pcsa* mainw = (US_pcsa*)parentw;
510  mainw->analysis_done( -1 ); // Reset counters to zero
511 
512  if ( processor != 0 )
513  {
514 DbgLv(1) << "AC:SF: processor stopping...";
515  processor->stop_fit();
517 DbgLv(1) << "AC:SF: processor stopped";
518  }
519 
520  qApp->processEvents();
521 }
522 
523 // plot button clicked
525 {
526  *mw_mrecs = mrecs;
527  *model = mrecs[ 0 ].model;
528  US_pcsa* mainw = (US_pcsa*)parentw;
529  mainw->analysis_done( 1 ); // Plot in main
530 }
531 
532 // advanced controls button clicked
534 {
535  US_pcsa* mainw = (US_pcsa*)parentw;
536 DbgLv(1) << "AC:advanced";
537 DbgLv(1) << "AC:advanced mrecs.size" << mrecs.size();
538 if(mrecs.size()>0)
539  DbgLv(1) << "AC:advanced mrecs0 p1 p2" << mrecs[0].par1 << mrecs[0].par2
540  << "ctype" << mrecs[0].ctype;
541  int nthr = (int)ct_thrdcnt ->value();
542 
543  US_AdvAnalysisPc* aadiag = new US_AdvAnalysisPc( &mrecs, nthr,
544  dsets[ 0 ], this );
545 
546  if ( aadiag->exec() == QDialog::Accepted )
547  {
548 DbgLv(1) << "AC:advanced dialog exec() return - ACCEPTED";
549  int state = aadiag->advanced_results( &mrecs_mc );
550  bool mrsupd = ( ( state & 3 ) != 0 );
551  bool mmcupd = ( ( state & 4 ) != 0 );
552  int ncsols = mrsupd ? mrecs[ 0 ].csolutes.size() : 0;
553  double rmsdf = mrsupd ? mrecs[ 0 ].rmsd : 0.0;
554  double varif = mrsupd ? mrecs[ 0 ].variance : 0.0;
555  int mciter = mmcupd ? mrecs_mc.size() : 0;
556 DbgLv(1) << "AC:advanced dialog state=" << state << "mainw" << mainw;
557 DbgLv(1) << "AC:adv:(1)rmsd" << mrecs[0].rmsd;
558 
559  if ( ck_tinoise->isChecked() || ck_rinoise->isChecked() )
560  {
561  QMessageBox::warning( this, tr( "Problematic combination!" ),
562  tr( "The combination of one or two noise fits selected and "
563  "Advanced Controls chosen is problematic, since model "
564  "records only specify fitting curves and not noise "
565  "parameters.\n\n"
566  "You may proceed, but the safest course is to click on "
567  "the Recompute Best Model button to re-fit with noises.\n\n"
568  "Any Save Results where noise is involved is better "
569  "executed *before* Advanced Controls." ) );
570  }
571 
572  // Update model recs where possible and appropriate
573  if ( mrsupd )
574  {
575  *mw_mrecs = mrecs;
576  *model = mrecs[ 0 ].model;
577  *sdata = mrecs[ 0 ].sim_data;
578  *rdata = mrecs[ 0 ].residuals;
580  }
581 DbgLv(1) << "AC:adv:(2)rmsd" << mrecs[0].rmsd;
582 
583  if ( mmcupd )
584  {
586  }
587 DbgLv(1) << "AC:advanced: mrec0 sols" << mrecs[0].csolutes.size()
588  << "mrecs size" << mrecs.size() << "mrecs_mc size" << mrecs_mc.size()
589  << "model compsize" << model->components.size();
590 
591  if ( mmcupd )
592  { // Report new BFM from MonteCarlo
593  QString fmsg = tr(
594  "\nA newer best model has been created by %1 Monte Carlo\n"
595  " iterations ( %2-solute, with RMSD = %3 )" )
596  .arg( mciter ).arg( ncsols ).arg( rmsdf );
597 
598  progress_message( fmsg, true );
599  le_minvari->setText( QString::number( varif ) );
600  le_minrmsd->setText( QString::number( rmsdf ) );
601  }
602 
603  else if ( mrsupd )
604  { // Report new BFM from other advanced controls action
605  QString fmsg = tr(
606  "\nA newer best model has been created from Advanced Controls\n"
607  " action ( %1-solute, with RMSD = %2 )" )
608  .arg( ncsols ).arg( rmsdf );
609 
610  progress_message( fmsg, true );
611  le_minvari->setText( QString::number( varif ) );
612  le_minrmsd->setText( QString::number( rmsdf ) );
613  }
614 DbgLv(1) << "AC:adv:(3)rmsd" << mrecs[0].rmsd;
615 
616  if ( state != 0 )
617  { // Where advanced controls have made changes, copy them
618  pb_startfit->setEnabled( true );
619  pb_scanregp->setEnabled( true );
620  pb_finalmdl->setEnabled( true );
621  pb_stopfit ->setEnabled( false );
622  pb_plot ->setEnabled( true );
623  pb_save ->setEnabled( true );
624  pb_pltlines->setEnabled( true );
625  need_fit = false;
626  need_final = true;
627  bmndx = mrecs[ 0 ].taskx;
628 DbgLv(1) << "AC:adv:(4)rmsd" << mrecs[0].rmsd;
629 
630  if ( processor == 0 )
631  {
632 
633  processor = new US_pcsaProcess( dsets, this );
634  }
635 
636  dsets[ 0 ]->solute_type = sol_type;
637  dsets[ 0 ]->zcoeffs[ 0 ] = le_z_func->text().section( " ", 0, 0 )
638  .toDouble();
639  dsets[ 0 ]->zcoeffs[ 1 ] = 0.0;
640  dsets[ 0 ]->zcoeffs[ 2 ] = 0.0;
641  dsets[ 0 ]->zcoeffs[ 3 ] = 0.0;
642 
643 DbgLv(1) << "AC: (B)stype" << sol_type << "zcoeff0" << dsets[0]->zcoeffs[0];
644 DbgLv(1) << "AC:advanced: put_mrecs";
645 DbgLv(1) << "AC:adv:putm: rmsd" << mrecs[0].rmsd;
647 DbgLv(1) << "AC:advanced: get_results";
649  bmndx, *mw_modstats, mrecs );
650 
651  ctype = mrecs[ 0 ].ctype;
652  int v_ctype = mrecs[ 0 ].v_ctype;
653  int nmrecs = mrecs.size();
654  int nmtsks = ( mrecs[ 0 ].taskx == mrecs[ 1 ].taskx )
655  ? ( nmrecs - 1 ) : nmrecs;
656  nmtsks = ( mrecs[ 1 ].taskx == mrecs[ 2 ].taskx )
657  ? ( nmrecs - 1 ) : nmrecs;
658  int strec = nmrecs - nmtsks;
659  nypts = ( v_ctype != CTYPE_ALL ) ? nmtsks : ( nmtsks / 3 );
660  nypts = ( ctype != CTYPE_HL && ctype != CTYPE_2O )
661  ? qRound( sqrt( (double)nypts ) ) : nypts;
662  nypts = ( ctype != CTYPE_2O ) ? nypts
663  : qRound( pow( (double)nypts, 0.33333 ) );
664  nlpts = mrecs[ strec ].isolutes.size();
665  xmin = mrecs[ strec ].xmin;
666  xmax = mrecs[ strec ].xmax;
667  ymin = mrecs[ strec ].ymin;
668  ymax = mrecs[ strec ].ymax;
669  int stype = mrecs[ 0 ].stype;
670  int attr_x = ( stype >> 6 ) & 7;
671  int attr_y = ( stype >> 3 ) & 7;
672  double xscl = ( attr_x == US_ZSolute::ATTR_S ) ? 1.0e+13 : 1.0;
673  double yscl = ( attr_y == US_ZSolute::ATTR_S ) ? 1.0e+13 : 1.0;
674 
675  for ( int ii = strec; ii < nmrecs; ii++ )
676  {
677  QVector< US_ZSolute >* isolutes = &mrecs[ ii ].isolutes;
678  nlpts = isolutes->size();
679  ymin = qMin( ymin, mrecs[ ii ].str_y );
680  ymax = qMax( ymax, mrecs[ ii ].end_y );
681 
682  for ( int jj = 0; jj < nlpts; jj++ )
683  {
684  double xval = (*isolutes)[ jj ].x * xscl;
685  double yval = (*isolutes)[ jj ].y * yscl;
686  xmin = qMin( xmin, xval );
687  xmax = qMax( xmax, xval );
688  ymin = qMin( ymin, yval );
689  ymax = qMax( ymax, yval );
690  }
691  }
692 
693  fitpars_connect( false );
694 
695  cb_curvtype->setCurrentIndex( ctypes.indexOf( ctype ) );
696  ct_lolimitx->setValue( xmin );
697  ct_uplimitx->setValue( xmax );
698  ct_lolimity->setValue( ymin );
699  ct_uplimity->setValue( ymax );
700  ct_varcount->setValue( nypts );
701  ct_cresolu ->setValue( nlpts );
702 
704  fitpars_connect( true );
705 
706  mainw->analysis_done( 0 ); // Tell main that new records are done
707  }
708  }
709 else
710 DbgLv(1) << "AC:advanced dialog exec() return - CANCELED";
711  delete aadiag;
712 }
713 
714 // save button clicked
716 {
717  US_pcsa* mainw = (US_pcsa*)parentw;
718 DbgLv(1) << "AC:save: model components size" << model->components.size();
719  *mw_mrecs = mrecs;
720  if ( mw_mrecs_mc->size() == 0 )
721  *model = mrecs[ 0 ].model;
722  else
723  *model = mw_mrecs_mc->at( 0 ).model;
724  mainw->analysis_done( 2 ); // Save in main
725 }
726 
727 // Close all windows
729 {
730 DbgLv(1) << "AC:close: mlnplotd" << mlnplotd;
731  if ( (QObject*)mlnplotd != (QObject*)0 )
732  mlnplotd->close();
733 
734  if ( processor != 0 )
735  delete processor;
736 
737  accept();
738 }
739 
740 // Public close slot
742 {
743  close_all();
744 }
745 
746 // Adjust s-limit ranges when x-limit value changes
748 {
749  double loval = ct_lolimitx->value();
750  double upval = ct_uplimitx->value();
751  double limlo = -1.e6;
752  double limup = 1.e6;
753  if ( loval > upval ) // Insure lower value less than upper
754  ct_lolimitx->setValue( upval );
755 
756  if ( loval < -1.e5 || upval > 1.e5 )
757  { // For larger magnitudes, adjust ranges
758  if ( loval < -1.e6 || upval > 1.e6 )
759  {
760  if ( loval < -1.e7 || upval > 1.e7 )
761  {
762  limlo = -1.e19;
763  limup = 1.e19;
764  }
765  else
766  {
767  limlo = -1.e8;
768  limup = 1.e8;
769  }
770  }
771  else
772  {
773  limlo = -1.e7;
774  limup = 1.e7;
775  }
776  }
777 
778  ct_lolimitx->setRange( limlo, upval );
779  ct_uplimitx->setRange( loval, limup );
780  ct_lolimitx->setStep( 0.1 );
781  ct_uplimitx->setStep( 0.1 );
782 }
783 
784 // Set k-upper-limit to lower when y grid points == 1
786 {
787  compute();
788 }
789 
790 // Handle change in resolution count
792 {
793 DbgLv(1) << "RESO_CHANGE: need_fit" << need_fit
794  << "reso" << ct_cresolu ->value();
795  if ( need_fit )
796  compute();
797 }
798 
799 // Handle change in curve type
801 {
802  ctypex = cb_curvtype->currentIndex();
803  ctype = ctypes[ ctypex ];
804  bmndx = -1;
805 DbgLv(1) << "TYPE_CHANGE: ctypex" << ctypex << "ctype" << ctype;
806 
807  if ( ctype == CTYPE_HL )
808  ct_varcount->setValue( 100 );
809  else if ( ctype == CTYPE_2O )
810  ct_varcount->setValue( 5 );
811  else
812  ct_varcount->setValue( 6 );
813 }
814 
815 // Set regularization factor alpha
817 {
818  bool regular = ( ct_tralpha->value() != 0.0 );
819  ck_tinoise ->setEnabled( !regular );
820  ck_rinoise ->setEnabled( !regular );
821  ck_lmalpha ->setEnabled( regular );
822  ck_fxalpha ->setEnabled( regular );
823 
824  if ( regular )
825  {
826  pb_finalmdl->setText( tr( "Regularize Current Model" ) );
827  ck_tinoise->setChecked( false );
828  ck_rinoise->setChecked( false );
829  }
830 
831  else
832  {
833  pb_finalmdl->setText( tr( "Recompute Best Model" ) );
834  }
835 
836  if ( ct_tralpha->value() >= 10.0 )
837  ct_tralpha->setStep( 0.01 );
838  else
839  ct_tralpha->setStep( 0.001 );
840 }
841 
842 // Slot to handle progress update
844 {
845  ncsteps ++;
846 
847  if ( ncsteps > nctotal )
848  {
849  nctotal = ( nctotal * 11 ) / 10;
850  b_progress->setMaximum( nctotal );
851  }
852 
853  b_progress->setValue( ncsteps );
854 DbgLv(2) << "UpdPr: ncs nts vari" << ncsteps << nctotal << variance;
855  double rmsd = sqrt( variance );
856  if ( variance < varimin )
857  {
858  varimin = variance;
859  le_minvari->setText( QString::number( varimin ) );
860  le_minrmsd->setText( QString::number( rmsd ) );
861  }
862 }
863 
864 // slot to handle updated progress message
865 void US_AnalysisControlPc::progress_message( QString pmsg, bool append )
866 {
867  QString amsg;
868 
869  if ( append )
870  { // append to existing progress message
871  amsg = te_status->toPlainText() + pmsg;
872  }
873 
874  else
875  { // create a new progress message
876  amsg = pmsg;
877  }
878 
879  mw_stattext->setText( amsg );
880  te_status ->setText( amsg );
881 
882  qApp->processEvents();
883 }
884 
885 // Slot to handle resetting progress
886 void US_AnalysisControlPc::reset_steps( int kcs, int nct )
887 {
888 DbgLv(1) << "AC:cs: prmx nct kcs" << b_progress->maximum() << nct << kcs;
889  ncsteps = kcs;
890  nctotal = nct;
891 
892  b_progress->setMaximum( nctotal );
893  b_progress->setValue( ncsteps );
894 
895  qApp->processEvents();
896 }
897 
898 // slot to handle completed processing
900 {
901  US_pcsa* mainw = (US_pcsa*)parentw;
902 DbgLv(1) << "AC:cp: stage" << stage;
903 
904  if ( stage == 7 )
905  { // If an alpha scan can now be done, report L-M info and mark scan-ready
906  US_ModelRecord mrec;
907  processor->get_mrec( mrec );
908  double vari = mrec.variance;
909  double rmsd = mrec.rmsd;
910  le_minvari->setText( QString::number( vari ) );
911  le_minrmsd->setText( QString::number( rmsd ) );
912 DbgLv(1) << "AC:cp: mrec fetched";
913 
914  // Assume we can compute the final and save current fit parameters
915  need_fit = false;
916  need_final = true;
918  return;
919  }
920 
921  if ( stage == 8 )
922  { // If starting L-M, turn off Stop Fit
923  pb_stopfit->setEnabled( false );
924  return;
925  }
926 
927  if ( stage == 6 )
928  { // If stopped because of memory usage, execute stop_fit
929  stop_fit();
930  return;
931  }
932 
934  QStringList modelstats;
935  mrecs.clear();
936 
938  modelstats, mrecs );
939 DbgLv(1) << "AC:cp: RES: ti,ri counts" << ti_noise->count << ri_noise->count;
940 DbgLv(1) << "AC:cp: RES: bmndx" << bmndx;
941 
942  plot_lines();
943 
944  if ( stage == 9 )
945  {
946  *mw_modstats = modelstats;
947  *mw_mrecs = mrecs;
948 
949 DbgLv(1) << "AC:cp: main done -2";
950  mainw->analysis_done( -2 ); // Update RMSD in main
951 
952 DbgLv(1) << "AC:cp: main done 0";
953  mainw->analysis_done( 0 ); // Tell main that records are done
954 
955  pb_startfit->setEnabled( true );
956  pb_scanregp->setEnabled( true );
957  pb_finalmdl->setEnabled( true );
958  pb_stopfit ->setEnabled( false );
959  pb_plot ->setEnabled( true );
960  pb_save ->setEnabled( true );
961  pb_pltlines->setEnabled( true );
962 DbgLv(1) << "(1)pb_plot-Enabled" << pb_plot->isEnabled();
963  need_fit = false;
964  need_final = false;
966 
967  double vari = mrecs[ 0 ].variance;
968  double rmsd = mrecs[ 0 ].rmsd;
969  le_minvari->setText( QString::number( vari ) );
970  le_minrmsd->setText( QString::number( rmsd ) );
971  }
972 }
973 
974 // slot to compute model lines
976 {
977  double parlims[ 12 ];
978 
979  set_solute_type();
980 
981  ctypex = cb_curvtype->currentIndex();
982  ctype = ctypes[ ctypex ];
983  xmin = ct_lolimitx->value();
984  xmax = ct_uplimitx->value();
985  ymin = ct_lolimity->value();
986  ymax = ct_uplimity->value();
987  nypts = (int)ct_varcount->value();
988  nlpts = (int)ct_cresolu ->value();
989  mrecs.clear();
990  parlims[ 0 ] = -1.0;
991  parlims[ 4 ] = sol_type;
992  parlims[ 5 ] = le_z_func->text().section( " ", 0, 0 ).toDouble();
993  int nlmodl = nypts * nypts;
994 DbgLv(1) << "AC:CM: ctype" << ctype << "stype" << sol_type
996 
997  if ( ctype == CTYPE_SL )
998  {
1000  parlims, mrecs );
1001  }
1002  else if ( ctype == CTYPE_IS || ctype == CTYPE_DS )
1003  {
1005  nypts, nlpts, parlims, mrecs );
1006  }
1007  else if ( ctype == CTYPE_HL )
1008  {
1009  nlmodl = nypts;
1010 
1012  parlims, mrecs );
1013  }
1014  else if ( ctype == CTYPE_2O )
1015  {
1016  nlmodl *= nypts;
1017 
1019  nypts, nlpts, parlims, mrecs );
1020  }
1021 DbgLv(1) << "AC:CM: mrecs0.sol0 x y z c"
1022  << mrecs[0].isolutes[0].x << mrecs[0].isolutes[0].y
1023  << mrecs[0].isolutes[0].z << mrecs[0].isolutes[0].c;
1024 
1025  QString amsg =
1026  tr( "The number of test models is %1,\n" ).arg( nlmodl );
1027  if ( ctype == CTYPE_2O )
1028  {
1029  amsg += tr( " derived from the cube of %1 variation points,\n" )
1030  .arg( nypts );
1031  }
1032  else if ( ctype != 8 )
1033  {
1034  amsg += tr( " derived from the square of %1 variation points,\n" )
1035  .arg( nypts );
1036  }
1037  amsg += tr( " with each curve model consisting of %1 points." )
1038  .arg( nlpts );
1039  te_status ->setText( amsg );
1040 
1041  bmndx = -1;
1042  need_fit = ( fitpars != fitpars_string() );
1043 DbgLv(1) << "AC:CM: need_fit" << need_fit;
1044  pb_pltlines->setEnabled( true );
1045  pb_scanregp->setEnabled( !need_fit );
1046  pb_finalmdl->setEnabled( !need_fit );
1047 }
1048 
1049 // slot to launch a plot dialog showing model lines
1051 {
1052  ctypex = cb_curvtype->currentIndex();
1053  ctype = ( mrecs[ 0 ].v_ctype == CTYPE_ALL )
1054  ? CTYPE_ALL : ctypes[ ctypex ];
1055  xmin = ct_lolimitx->value();
1056  xmax = ct_uplimitx->value();
1057  ymin = ct_lolimity->value();
1058  ymax = ct_uplimity->value();
1059  nlpts = (int)ct_cresolu ->value();
1060  nypts = (int)ct_varcount->value();
1061  sol_type = ( attr_x << 6 ) + ( attr_y << 3 ) + attr_z;
1062 
1063  mrecs[ 0 ].stype = sol_type;
1064 
1065 DbgLv(1) << "PL: mlnplotd" << mlnplotd;
1066  if ( mlnplotd != 0 )
1067  mlnplotd->close();
1068 DbgLv(1) << "PL: mlnplotd closed";
1069 
1071  nypts, nlpts, bmndx );
1072 
1073  connect( mlnplotd, SIGNAL( destroyed( QObject* ) ),
1074  this, SLOT ( closed ( QObject* ) ) );
1075 
1076 DbgLv(1) << "PL: new mlnplotd" << mlnplotd << "sol_type" << sol_type;
1077 
1078  if ( bmndx >= 0 )
1079  {
1080 DbgLv(1) << "PL: mlp: setModel bmndx" << bmndx;
1082  }
1083  else
1084  {
1085 DbgLv(1) << "PL: mlp: setModel model=0";
1086  mlnplotd->setModel( 0, mrecs );
1087  }
1088 
1089 DbgLv(1) << "PL: mlp: call plot_data";
1090  mlnplotd->plot_data();
1091 DbgLv(1) << "PL: mlp: rtn fr plot_data";
1092  mlnplotd->setVisible( true );
1093 
1094  QString filepath = US_Settings::tmpDir() + "/PCSA."
1096  + ".mlines."
1097  + QString::number( getpid() ) + ".png";
1098  QPixmap pixmap = QPixmap::grabWidget( mlnplotd, 0, 0,
1099  mlnplotd->width(), mlnplotd->height() );
1100 DbgLv(0) << "PLOTLINE: mlines filepath" << filepath;
1101 DbgLv(0) << "PLOTLINE: mlines w h" << pixmap.width() << pixmap.height();
1102  pixmap.save( filepath );
1103 }
1104 
1105 // Private slot to mark a child widget as closed, if it has been destroyed
1107 {
1108  QString oname = o->objectName();
1109 
1110  if ( oname.contains( "MLinesPlot" ) )
1111  mlnplotd = 0;
1112 }
1113 
1114 // Set flags and start fit where fits and final computation are needed
1116 {
1117  need_fit = true;
1118  need_final = true;
1119  fitpars = QString();
1120 
1121  start();
1122 }
1123 
1124 // Set flags and open the dialog to do an Alpha scan
1126 {
1127  US_ModelRecord mrec;
1128  need_fit = false;
1129  need_final = false;
1130 
1131  int nthr = (int)ct_thrdcnt ->value();
1132  int klpts = (int)ct_cresolu ->value();
1133  double alpha = 0.0;
1134 DbgLv(1) << "AC:sa: nthr klp nlp" << nthr << klpts << nlpts;
1135 
1136  if ( klpts != nlpts )
1137  { // Must recompute final LM model since resol. points value has changed
1138  recompute_mrec();
1139  mrec = mrecs[ 0 ];
1140  nlpts = klpts;
1141  }
1142 
1143  else if ( processor != 0 )
1144  processor->get_mrec( mrec );
1145 
1146  US_RpScan* rpscand = new US_RpScan( dsets, mrec, nthr, alpha );
1147 DbgLv(1) << "AC:sa: RpScan created";
1148 
1149  if ( rpscand->exec() == QDialog::Accepted )
1150  {
1151 DbgLv(1) << "AC:sa: alpha fetched" << alpha;
1152  ct_tralpha ->setValue( alpha );
1153  }
1154 
1155  pb_finalmdl->setEnabled( true );
1156 DbgLv(1) << "AC:sa: RpScan deleting";
1157  delete rpscand;
1158  rpscand = NULL;
1159 DbgLv(1) << "AC:sa: RpScan deleted";
1160 
1161  // Assume we can compute the final and save current fit parameters
1162  fitpars = fitpars_string();
1163  nlpts = (int)ct_cresolu ->value();
1164 }
1165 
1166 // Set flags and start fit where only final computation is needed
1168 {
1169  need_fit = false;
1170  need_final = true;
1171  int klpts = (int)ct_cresolu ->value();
1172 DbgLv(1) << "AC:fo: klp nlp" << klpts << nlpts;
1173 
1174  if ( klpts != nlpts )
1175  { // Must recompute final LM model since resol. points value has changed
1176  recompute_mrec();
1177  nlpts = klpts;
1178  }
1179 
1180  start();
1181 }
1182 
1183 // Compose a string showing the current settings for fit parameters
1185 {
1186  int typ = cb_curvtype->currentIndex();
1187  double xlo = ct_lolimitx->value();
1188  double xup = ct_uplimitx->value();
1189  double ylo = ct_lolimity->value();
1190  double yup = ct_uplimity->value();
1191  int nvar = (int)ct_varcount->value();
1192  int noif = ( ck_tinoise->isChecked() ? 1 : 0 ) +
1193  ( ck_rinoise->isChecked() ? 2 : 0 );
1194 
1195 
1196  return QString().sprintf( "%d %.5e %.5e %.5e %.5e %d %d",
1197  typ, xlo, xup, ylo, yup, nvar, noif );
1198 }
1199 
1200 // Re-Connect or disconnect fit parameters controls
1202 {
1203  if ( reconn )
1204  { // Reconnect controls
1205  connect( bg_x_axis, SIGNAL( buttonReleased( int ) ),
1206  this, SLOT( select_x_axis ( int ) ) );
1207  connect( bg_y_axis, SIGNAL( buttonReleased( int ) ),
1208  this, SLOT( select_y_axis ( int ) ) );
1209  connect( cb_curvtype, SIGNAL( activated ( int ) ),
1210  this, SLOT( type_change() ) );
1211  connect( ct_lolimitx, SIGNAL( valueChanged ( double ) ),
1212  this, SLOT( xlim_change() ) );
1213  connect( ct_uplimitx, SIGNAL( valueChanged ( double ) ),
1214  this, SLOT( xlim_change() ) );
1215  connect( ct_lolimity, SIGNAL( valueChanged ( double ) ),
1216  this, SLOT( ylim_change() ) );
1217  connect( ct_uplimity, SIGNAL( valueChanged ( double ) ),
1218  this, SLOT( ylim_change() ) );
1219  connect( cb_z_type, SIGNAL( activated ( int ) ),
1220  this, SLOT( ztype_change ( int ) ) );
1221  connect( ct_varcount, SIGNAL( valueChanged ( double ) ),
1222  this, SLOT( compute() ) );
1223  connect( ct_cresolu, SIGNAL( valueChanged ( double ) ),
1224  this, SLOT( reso_change() ) );
1225  }
1226 
1227  else
1228  { // Disconnect controls
1229  bg_x_axis ->disconnect();
1230  bg_y_axis ->disconnect();
1231  cb_curvtype->disconnect();
1232  ct_lolimitx->disconnect();
1233  ct_uplimitx->disconnect();
1234  ct_lolimity->disconnect();
1235  ct_uplimity->disconnect();
1236  cb_z_type ->disconnect();
1237  ct_varcount->disconnect();
1238  ct_cresolu ->disconnect();
1239  }
1240 }
1241 
1242 // Recompute the top model record after change to resolution points
1244 {
1245  US_ModelRecord mrec = mrecs[ 0 ];
1246 int nn=mrec.isolutes.size()-1;
1247 int mm=mrec.isolutes.size()/2;
1248 DbgLv(1) << "AC:RM: mrec0 solsize" << mrec.isolutes.size()
1249  << "s0 x,y" << mrec.isolutes[0].x << mrec.isolutes[0].y
1250  << "sm x,y" << mrec.isolutes[mm].x << mrec.isolutes[mm].y
1251  << "sn x,y" << mrec.isolutes[nn].x << mrec.isolutes[nn].y;
1252  mrec.isolutes.clear();
1253  US_ZSolute isol;
1254  xmin = ct_lolimitx->value();
1255  xmax = ct_uplimitx->value();
1256  ymin = ct_lolimity->value();
1257  ymax = ct_uplimity->value();
1258  nlpts = (int)ct_cresolu ->value();
1259  ctypex = cb_curvtype->currentIndex();
1260  ctype = ctypes[ ctypex ];
1261  mrec.ctype = ctype;
1262  mrec.xmin = xmin;
1263  mrec.xmax = xmax;
1264  mrec.ymin = ymin;
1265  mrec.ymax = ymax;
1266  double str_y = mrec.str_y;
1267  double end_y = mrec.end_y;
1268  double par1 = mrec.par1;
1269  double par2 = mrec.par2;
1270  double par3 = mrec.par3;
1271  double prng = (double)( nlpts - 1 );
1272  double xrng = xmax - xmin;
1273  int stype = mrec.stype;
1274  int attr_x = ( stype >> 6 ) & 7;
1275  int attr_y = ( stype >> 3 ) & 7;
1276  double xscl = ( attr_x == US_ZSolute::ATTR_S ) ? 1.0e-13 : 1.0;
1277  double yscl = ( attr_y == US_ZSolute::ATTR_S ) ? 1.0e-13 : 1.0;
1278  isol.z = le_z_func->text().section( " ", 0, 0 ).toDouble();
1279 
1280  if ( ctype == CTYPE_SL )
1281  {
1282  double xval = xmin;
1283  double xinc = xrng / prng;
1284  double yval = str_y;
1285  double yinc = ( end_y - str_y ) / prng;
1286 
1287  for ( int kk = 0; kk < nlpts; kk++ )
1288  { // Loop over points on a line
1289  isol.x = xval * xscl;
1290  isol.y = yval * yscl;
1291  mrec.isolutes << isol;
1292  xval += xinc;
1293  yval += yinc;
1294  } // END: points-per-line loop
1295  }
1296 
1297  else if ( ctype == CTYPE_IS || ctype == CTYPE_DS )
1298  {
1299  double xrng = xmax - xmin;
1300  double ystr = ( ctype == CTYPE_IS ) ? ymin : ymax;
1301  double ydif = ymax - ymin;
1302  ydif = ( ctype == CTYPE_IS ) ? ydif : -ydif;
1303  double xoff = 0.0;
1304  double xoinc = 1.0 / prng;
1305  double p1rt = sqrt( 2.0 * par1 );
1306 
1307  for ( int kk = 0; kk < nlpts; kk++ )
1308  { // Loop over points on a sigmoid curve
1309  double xval = xmin + xoff * xrng;
1310  double efac = 0.5 * erf( ( xoff - par2 ) / p1rt ) + 0.5;
1311  double yval = ystr + ydif * efac;
1312  isol.x = xval * xscl;
1313  isol.y = yval * yscl;
1314  mrec.isolutes << isol;
1315  xoff += xoinc;
1316  } // END: points-on-curve loop
1317  }
1318 
1319  else if ( ctype == CTYPE_HL )
1320  {
1321  double xval = xmin;
1322  double xinc = xrng / prng;
1323  double yval = end_y;
1324 
1325  for ( int kk = 0; kk < nlpts; kk++ )
1326  { // Loop over points on a line
1327  isol.x = xval * xscl;
1328  isol.y = yval * yscl;
1329  mrec.isolutes << isol;
1330  xval += xinc;
1331  } // END: points-per-line loop
1332  }
1333 
1334  else if ( ctype == CTYPE_2O )
1335  {
1336  double xval = xmin;
1337  double xinc = xrng / prng;
1338 
1339  for ( int ll = 0; ll < nlpts; ll++ )
1340  { // Loop over points on a power law curve
1341  isol.x = xval * xscl;
1342  double yval = par1 * pow( xval, par2 ) + par3;
1343  isol.y = yval * yscl;
1344  mrec.isolutes << isol;
1345  xval += xinc;
1346  } // END: points-per-line loop
1347  }
1348 
1349  mrecs[ 0 ] = mrec;
1350 nn=mrec.isolutes.size()-1;
1351 mm=mrec.isolutes.size()/2;
1352 DbgLv(1) << "AC:RM: NEW mrec0 solsize" << mrec.isolutes.size()
1353  << "s0 x,y" << mrec.isolutes[0].x << mrec.isolutes[0].y
1354  << "sm x,y" << mrec.isolutes[mm].x << mrec.isolutes[mm].y
1355  << "sn x,y" << mrec.isolutes[nn].x << mrec.isolutes[nn].y;
1356  if ( processor != 0 )
1357  processor->put_mrec( mrec );
1358 }
1359 
1361 {
1362  const double mb_fact = ( 1024. * 1024. );
1363  const double x_fact = 19.25;
1364  const double y_fact = 2.43;
1365  const int pc_ava = 90;
1366  const int nxdata = 4;
1367  int baserss = *mw_baserss;
1368  if ( baserss == 0 )
1369  {
1370  baserss = qRound( (double)US_Memory::rss_now() / 1024. );
1371  *mw_baserss = baserss;
1372  }
1373  int status = 0;
1374  int nscans = edata->scanCount();
1375  int npoints = edata->pointCount();
1376  int idsize = nscans * npoints * sizeof( double );
1377  int nsols = (int)ct_cresolu ->value();
1378  int nthrds = (int)ct_thrdcnt ->value();
1379  double dsize = (double)idsize * (double)( nsols + nxdata ) / mb_fact;
1380  double msize = ( x_fact + dsize * y_fact ) * (double)nthrds;
1381  int memneed = baserss + qRound( msize );
1382  int memtot, memava, memuse;
1383  int mempca = US_Memory::memory_profile( &memava, &memtot, &memuse );
1384  int memsafe = ( memava * pc_ava ) / 100;
1385 int idsz = qRound(dsize);
1386 int imsz = qRound(msize);
1387 DbgLv(1) << "MEMck: memtot,ava,use,safe,need" << memtot << memava << memuse
1388  << memsafe << memneed << "dsz msz ns nt" << idsz << imsz << nsols << nthrds;
1389 
1390  if ( memneed > memsafe || mempca < 20 )
1391  {
1392  QString title = tr( "High Memory Usage" );
1393  QString memp = tr( "\n\nMemory Profile --\n"
1394  " Total: %1 MB\n"
1395  " Available: %2 MB\n"
1396  " Used: %3 MB\n"
1397  " Estimated Need: %4 MB\n\n" )
1398  .arg( memtot ).arg( memava ).arg( memuse ).arg( memneed );
1399 
1400  if ( memneed > memtot )
1401  {
1402  QMessageBox::critical( this, title,
1403  tr( "Memory needed for this fit exceeds total available." )
1404  + memp + tr( "This fit will not proceed.\n"
1405  "Re-parameterize the fit with adjusted\n"
1406  "Curve Resolution Points and/or\n"
1407  "Thread Count." ) );
1408  status = 1;
1409  }
1410 
1411  else
1412  {
1413  QMessageBox msgBox( this );
1414  msgBox.setWindowTitle( title );
1415  msgBox.setText( tr( "Memory needed for this fit is a\n"
1416  "high percentage of the available memory." )
1417  + memp +
1418  tr( "You may proceed if you wish (\"Yes\")\n"
1419  "Or you may stop this fit (\"No\")\n"
1420  "then re-parameterize the fit with adjusted\n"
1421  "Curve Resolution Points and/or\n"
1422  "Thread Count.\n\nProceed?" ) );
1423  msgBox.addButton( QMessageBox::No );
1424  msgBox.addButton( QMessageBox::Yes );
1425  msgBox.setDefaultButton( QMessageBox::No );
1426 
1427  if ( msgBox.exec() == QMessageBox::No )
1428  status = 2;
1429  }
1430  }
1431 
1432  return status;
1433 }
1434 
1435 // Select the coordinate for the horizontal axis
1437 {
1438 qDebug() << "SelX: ival" << ival;
1439  attr_x = ival;
1440  fitpars_connect( false );
1441 qDebug() << "SelX: attr_x attr_y" << attr_x << attr_y;
1442 
1443  if ( attr_x == attr_y )
1444  { // If new X same as current Y, change Y
1445  attr_y = ( attr_y < ATTR_D ) ? ( attr_y + 1 ) : ATTR_S;
1446 qDebug() << "SelX: NEW attr_y" << attr_y;
1447 
1448  if ( attr_y == ATTR_S )
1449  rb_y_s ->setChecked( true );
1450  else if ( attr_y == ATTR_K )
1451  rb_y_ff0 ->setChecked( true );
1452  else if ( attr_y == ATTR_W )
1453  rb_y_mw ->setChecked( true );
1454  else if ( attr_y == ATTR_V )
1455  rb_y_vbar->setChecked( true );
1456  else if ( attr_y == ATTR_D )
1457  rb_y_D ->setChecked( true );
1458 
1459  adjust_xyz( 2 );
1460  }
1461 
1462  // Disable the Y that matches X
1463  rb_y_s ->setEnabled( attr_x != ATTR_S );
1464  rb_y_ff0 ->setEnabled( attr_x != ATTR_K );
1465  rb_y_mw ->setEnabled( attr_x != ATTR_W );
1466  rb_y_vbar->setEnabled( attr_x != ATTR_V );
1467  rb_y_D ->setEnabled( attr_x != ATTR_D );
1468 
1469  // Change Z selection if it duplicates X or Y
1470  if ( attr_z == attr_x || attr_z == attr_y )
1471  {
1472  if ( attr_x != ATTR_V && attr_y != ATTR_V )
1473  {
1474  cb_z_type ->setCurrentIndex( 0 );
1475  attr_z = ATTR_V;
1476  }
1477  else if ( attr_x != ATTR_K && attr_y != ATTR_K )
1478  {
1479  cb_z_type ->setCurrentIndex( 1 );
1480  attr_z = ATTR_K;
1481  }
1482  else if ( attr_x != ATTR_W && attr_y != ATTR_W )
1483  {
1484  cb_z_type ->setCurrentIndex( 2 );
1485  attr_z = ATTR_W;
1486  }
1487 
1488  adjust_xyz( 0 );
1489  }
1490 
1491  // Adjust XYZ ranges and values
1492  adjust_xyz( 1 );
1493  fitpars_connect( true );
1494 }
1495 
1496 // Select the coordinate for the vertical axis
1498 {
1499 qDebug() << "SelY: ival" << ival;
1500  attr_y = ival;
1501  fitpars_connect( false );
1502 
1503  // Change Z selection if it duplicates X or Y
1504  if ( attr_z == attr_x || attr_z == attr_y )
1505  {
1506  if ( attr_x != ATTR_V && attr_y != ATTR_V )
1507  {
1508  cb_z_type ->setCurrentIndex( 0 );
1509  attr_z = ATTR_V;
1510  }
1511  else if ( attr_x != ATTR_K && attr_y != ATTR_K )
1512  {
1513  cb_z_type ->setCurrentIndex( 1 );
1514  attr_z = ATTR_K;
1515  }
1516  else if ( attr_x != ATTR_W && attr_y != ATTR_W )
1517  {
1518  cb_z_type ->setCurrentIndex( 2 );
1519  attr_z = ATTR_W;
1520  }
1521 
1522  adjust_xyz( 0 );
1523  }
1524 
1525  // Adjust XYZ ranges and values
1526  adjust_xyz( 2 );
1527  fitpars_connect( true );
1528 }
1529 
1530 // Set Z type
1532 {
1533  attr_z = ATTR_V;
1534  attr_z = ( newx == 1 ) ? ATTR_K : attr_z;
1535  attr_z = ( newx == 2 ) ? ATTR_W : attr_z;
1536 
1537  fitpars_connect( false );
1538  adjust_xyz( 0 );
1539  fitpars_connect( true );
1540 }
1541 
1542 // Adjust X,Y,Z ranges and default values based on type
1543 void US_AnalysisControlPc::adjust_xyz( const int chg_ndx )
1544 {
1545  // Types: "s", "f/f0", "MW", "vbar", "D"
1546  const double vllos[] = { 1.0, 1.0, 2e+4, 0.60, 1e-8 };
1547  const double vlhis[] = { 10.0, 4.0, 1e+5, 0.80, 1e-7 };
1548  const double vdefs[] = { 5.0, 1.5, 5e+4, 0.72, 5e-8 };
1549  const double vmins[] = { -10000.0, 1.0, 0.0, 0.01, 1e-9 };
1550  const double vmaxs[] = { 10000.0, 50.0, 1e+10, 3.00, 1e-5 };
1551  const double vincs[] = { 0.01, 0.01, 1000.0, 0.01, 1e-9 };
1552 
1553  // Get X,Y,Z ranges and values
1554  double xlow = vllos[ attr_x ];
1555  double xhigh = vlhis[ attr_x ];
1556  double xmin = vmins[ attr_x ];
1557  double xmax = vmaxs[ attr_x ];
1558  double xinc = vincs[ attr_x ];
1559  double ylow = vllos[ attr_y ];
1560  double yhigh = vlhis[ attr_y ];
1561  double ymin = vmins[ attr_y ];
1562  double ymax = vmaxs[ attr_y ];
1563  double yinc = vincs[ attr_y ];
1564  bmndx = -1;
1565 
1566  // Set ranges and values in GUI elements
1567  ct_lolimitx->setRange( xmin, xmax, xinc );
1568  ct_uplimitx->setRange( xmin, xmax, xinc );
1569  ct_lolimity->setRange( ymin, ymax, yinc );
1570  ct_uplimity->setRange( ymin, ymax, yinc );
1571 
1572  if ( chg_ndx == 1 )
1573  { // X has just changed
1574  ct_lolimitx->setValue( xlow );
1575  ct_uplimitx->setValue( xhigh );
1576  }
1577  else if ( chg_ndx == 2 )
1578  { // Y has just changed
1579  ct_lolimity->setValue( ylow );
1580  ct_uplimity->setValue( yhigh );
1581  }
1582  else
1583  { // Z has just changed
1584  double zdef = ( attr_z == US_ZSolute::ATTR_V )
1585  ? dsets[ 0 ]->vbar20
1586  : vdefs[ attr_z ];
1587  le_z_func->setText( QString::number( zdef ) );
1588  }
1589 
1590  compute();
1591 }
1592 
1593 // Set attribute indecies and the composite solute type
1595 {
1596  attr_x = bg_x_axis->checkedId();
1597  attr_y = bg_y_axis->checkedId();
1598  int zt_ndx = cb_z_type->currentIndex();
1599  attr_z = ATTR_V;
1600  attr_z = ( zt_ndx == 1 ) ? ATTR_K : attr_z;
1601  attr_z = ( zt_ndx == 2 ) ? ATTR_W : attr_z;
1602 
1603  sol_type = ( attr_x << 6 ) + ( attr_y << 3 ) + attr_z;
1604 DbgLv(1) << "AC:SST: ztx x,y,z" << zt_ndx << attr_x << attr_y << attr_z
1605  << "sol_type" << sol_type << US_ModelRecord::stype_text(sol_type);
1606 
1607  dsets[ 0 ]->solute_type = sol_type;
1608  dsets[ 0 ]->zcoeffs[ 0 ] = le_z_func->text().section( " ", 0, 0 )
1609  .toDouble();
1610  dsets[ 0 ]->zcoeffs[ 1 ] = 0.0;
1611  dsets[ 0 ]->zcoeffs[ 2 ] = 0.0;
1612  dsets[ 0 ]->zcoeffs[ 3 ] = 0.0;
1613 }
1614