UltraScan III
us_analysis_control_2d.cpp
Go to the documentation of this file.
1 
3 #include "us_2dsa.h"
5 #include "us_adv_analysis_2d.h"
6 #include "us_settings.h"
7 #include "us_passwd.h"
8 #include "us_db2.h"
9 #include "us_gui_settings.h"
10 #include "us_memory.h"
11 
12 #include <qwt_legend.h>
13 
14 // constructor: 2dsa analysis controls widget
15 US_AnalysisControl2D::US_AnalysisControl2D( QList< SS_DATASET* >& dsets,
16  bool& loadDB, QWidget* p ) : US_WidgetsDialog( p, 0 ),
17  dsets( dsets ), loadDB( loadDB )
18 {
19  parentw = p;
20  processor = 0;
23  baserss = 0;
24 
25  setObjectName( "US_AnalysisControl2D" );
26  setAttribute( Qt::WA_DeleteOnClose, true );
27  setPalette( US_GuiSettings::frameColor() );
29 
30  // lay out the GUI
31  setWindowTitle( tr( "2-D Spectrum Analysis Controls" ) );
32 
33  mainLayout = new QHBoxLayout( this );
34  controlsLayout = new QGridLayout( );
35  optimizeLayout = new QGridLayout( );
36 
37  mainLayout->setSpacing ( 2 );
38  mainLayout->setContentsMargins( 2, 2, 2, 2 );
39 
40  mainLayout->addLayout( controlsLayout );
41  mainLayout->addLayout( optimizeLayout );
42 
43  QLabel* lb_fitting = us_banner( tr( "Fitting Controls:" ) );
44  QLabel* lb_lolimits = us_label( tr( "Lower Limit (s x 1e-13):" ) );
45  QLabel* lb_uplimits = us_label( tr( "Upper Limit (s):" ) );
46  QLabel* lb_nstepss = us_label( tr( "Number Grid Points (s):" ) );
47  lb_lolimitk = us_label( tr( "Lower Limit (f/f0):" ) );
48  lb_uplimitk = us_label( tr( "Upper Limit (f/f0):" ) );
49  lb_nstepsk = us_label( tr( "Number Grid Points (f/f0):" ) );
50  lb_constff0 = us_label( tr( "Constant f/f0:" ) );
51  QLabel* lb_thrdcnt = us_label( tr( "Thread Count:" ) );
52  QLabel* lb_estmemory = us_label( tr( "Estimated Memory:" ) );
53  QLabel* lb_iteration = us_label( tr( "Completed Iteration:" ) );
54  QLabel* lb_oldvari = us_label( tr( "Old Variance:" ) );
55  QLabel* lb_newvari = us_label( tr( "New Variance:" ) );
56  QLabel* lb_improve = us_label( tr( "Improvement:" ) );
57  QLabel* lb_status = us_label( tr( "Status:" ) );
58 
59  QLabel* lb_optimiz = us_banner( tr( "Optimization Methods:" ) );
60  QLabel* lb_gridreps = us_label( tr( "Grid Repetitions:" ) );
61  QLabel* lb_menisrng = us_label( tr( "Meniscus Fit Range (cm):" ) );
62  QLabel* lb_menispts = us_label( tr( "Meniscus Grid Points:" ) );
63  QLabel* lb_mciters = us_label( tr( "Monte Carlo Iterations:" ) );
64  QLabel* lb_iters = us_label( tr( "Maximum Iterations:" ) );
65  QLabel* lb_statinfo = us_banner( tr( "Status Information:" ) );
66 
67  pb_strtfit = us_pushbutton( tr( "Start Fit" ), true );
68  pb_stopfit = us_pushbutton( tr( "Stop Fit" ), false );
69  pb_plot = us_pushbutton( tr( "Plot Results" ), false );
70  pb_save = us_pushbutton( tr( "Save Results" ), false );
71  pb_ldmodel = us_pushbutton( tr( "Load Model" ), false );
72  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
73  QPushButton* pb_close = us_pushbutton( tr( "Close" ) );
74  QPushButton* pb_advance = us_pushbutton( tr( "Advanced Analysis Controls" ));
76  us_setReadOnly( te_status, true );
77 
78  QLayout* lo_tinois =
79  us_checkbox( tr( "Fit Time-Invariant Noise" ), ck_tinoise );
80  QLayout* lo_rinois =
81  us_checkbox( tr( "Fit Radially-Invariant Noise" ), ck_rinoise );
82  QLayout* lo_autoplt =
83  us_checkbox( tr( "Automatically Plot" ), ck_autoplt );
84  QLayout* lo_varvbar =
85  us_checkbox( tr( "Vary Vbar with Constant f/f0" ), ck_varvbar );
86 
87  int nthr = US_Settings::threads();
88  nthr = ( nthr > 1 ) ? nthr : QThread::idealThreadCount();
89 DbgLv(1) << "idealThrCout" << nthr;
90  ct_lolimits = us_counter( 3, -10000, 10000, 1 );
91  ct_uplimits = us_counter( 3, -10000, 10000, 10 );
92  ct_nstepss = us_counter( 3, 1, 1000, 64 );
93  ct_lolimitk = us_counter( 3, 1, 8, 1 );
94  ct_uplimitk = us_counter( 3, 1, 20, 4 );
95  ct_nstepsk = us_counter( 3, 1, 1000, 64 );
96  ct_thrdcnt = us_counter( 2, 1, 64, nthr );
97  ct_constff0 = us_counter( 3, 1, 10, 1 );
98  ct_lolimits->setStep( 0.1 );
99  ct_uplimits->setStep( 0.1 );
100  ct_nstepss ->setStep( 1 );
101  ct_lolimitk->setStep( 0.01 );
102  ct_uplimitk->setStep( 0.01 );
103  ct_nstepsk ->setStep( 1 );
104  ct_thrdcnt ->setStep( 1 );
105  ct_constff0->setStep( 0.01 );
106 
107  le_estmemory = us_lineedit( tr( "100 MB" ), -1, true );
108  le_iteration = us_lineedit( "0", -1, true );
109  le_oldvari = us_lineedit( "0.000e-05", -1, true );
110  le_newvari = us_lineedit( "0.000e-05", -1, true );
111  le_improve = us_lineedit( "0.000e-08", -1, true );
113  tr( "8 ( -> 64 64-point subgrids )" ), -1, true );
114 
115  b_progress = us_progressBar( 0, 100, 0 );
116 
117  QLayout* lo_iters =
118  us_checkbox( tr( "Use Iterative Method" ), ck_iters, false );
119  QLayout* lo_unifgr =
120  us_checkbox( tr( "Uniform Grid" ), ck_unifgr, true );
121  QLayout* lo_custgr =
122  us_checkbox( tr( "Custom Grid" ), ck_custgr, false );
123  QLayout* lo_menisc =
124  us_checkbox( tr( "Float Meniscus Position" ), ck_menisc, false );
125  QLayout* lo_mcarlo =
126  us_checkbox( tr( "Monte Carlo Iterations" ), ck_mcarlo, false );
127 
128 
129  ct_iters = us_counter( 2, 1, 16, 1 );
130  ct_menisrng = us_counter( 3, 0.01, 0.65, 0.03 );
131  ct_menispts = us_counter( 2, 3, 21, 10 );
132  ct_mciters = us_counter( 3, 3, 2000, 20 );
133  ct_menisrng ->setStep( 0.01 );
134  ct_menispts ->setStep( 1 );
135  ct_mciters ->setStep( 1 );
136  ct_iters ->setStep( 1 );
137 
138  int row = 0;
139  controlsLayout->addWidget( lb_fitting, row++, 0, 1, 4 );
140  controlsLayout->addWidget( lb_lolimits, row, 0, 1, 2 );
141  controlsLayout->addWidget( ct_lolimits, row++, 2, 1, 2 );
142  controlsLayout->addWidget( lb_uplimits, row, 0, 1, 2 );
143  controlsLayout->addWidget( ct_uplimits, row++, 2, 1, 2 );
144  controlsLayout->addWidget( lb_nstepss, row, 0, 1, 2 );
145  controlsLayout->addWidget( ct_nstepss, row++, 2, 1, 2 );
146  controlsLayout->addWidget( lb_lolimitk, row, 0, 1, 2 );
147  controlsLayout->addWidget( ct_lolimitk, row++, 2, 1, 2 );
148  controlsLayout->addWidget( lb_uplimitk, row, 0, 1, 2 );
149  controlsLayout->addWidget( ct_uplimitk, row++, 2, 1, 2 );
150  controlsLayout->addWidget( lb_nstepsk, row, 0, 1, 2 );
151  controlsLayout->addWidget( ct_nstepsk, row++, 2, 1, 2 );
152  controlsLayout->addWidget( lb_thrdcnt, row, 0, 1, 2 );
153  controlsLayout->addWidget( ct_thrdcnt, row++, 2, 1, 2 );
154  controlsLayout->addLayout( lo_tinois, row, 0, 1, 2 );
155  controlsLayout->addLayout( lo_rinois, row++, 2, 1, 2 );
156  controlsLayout->addLayout( lo_autoplt, row, 0, 1, 2 );
157  controlsLayout->addLayout( lo_varvbar, row++, 2, 1, 2 );
158  controlsLayout->addWidget( lb_constff0, row, 0, 1, 2 );
159  controlsLayout->addWidget( ct_constff0, row++, 2, 1, 2 );
160  controlsLayout->addWidget( pb_strtfit, row, 0, 1, 2 );
161  controlsLayout->addWidget( pb_stopfit, row++, 2, 1, 2 );
162  controlsLayout->addWidget( pb_plot, row, 0, 1, 2 );
163  controlsLayout->addWidget( pb_save, row++, 2, 1, 2 );
164  controlsLayout->addWidget( pb_help, row, 0, 1, 2 );
165  controlsLayout->addWidget( pb_close, row++, 2, 1, 2 );
166  controlsLayout->addWidget( lb_estmemory, row, 0, 1, 2 );
167  controlsLayout->addWidget( le_estmemory, row++, 2, 1, 2 );
168  controlsLayout->addWidget( lb_iteration, row, 0, 1, 2 );
169  controlsLayout->addWidget( le_iteration, row++, 2, 1, 2 );
170  controlsLayout->addWidget( lb_oldvari, row, 0, 1, 2 );
171  controlsLayout->addWidget( le_oldvari, row++, 2, 1, 2 );
172  controlsLayout->addWidget( lb_newvari, row, 0, 1, 2 );
173  controlsLayout->addWidget( le_newvari, row++, 2, 1, 2 );
174  controlsLayout->addWidget( lb_improve, row, 0, 1, 2 );
175  controlsLayout->addWidget( le_improve, row++, 2, 1, 2 );
176  controlsLayout->addWidget( lb_status, row, 0, 1, 1 );
177  controlsLayout->addWidget( b_progress, row++, 1, 1, 3 );
178  QLabel* lb_optspace1 = us_banner( "" );
179  controlsLayout->addWidget( lb_optspace1, row, 0, 1, 4 );
180  controlsLayout->setRowStretch( row, 2 );
181 
182  row = 0;
183  optimizeLayout->addWidget( lb_optimiz, row++, 0, 1, 4 );
184  optimizeLayout->addLayout( lo_unifgr, row++, 0, 1, 4 );
185  optimizeLayout->addWidget( lb_gridreps, row, 0, 1, 1 );
186  optimizeLayout->addWidget( le_gridreps, row++, 1, 1, 3 );
187  optimizeLayout->addLayout( lo_custgr, row, 0, 1, 2 );
188  optimizeLayout->addWidget( pb_ldmodel, row++, 2, 1, 4 );
189  optimizeLayout->addLayout( lo_menisc, row++, 0, 1, 4 );
190  optimizeLayout->addWidget( lb_menisrng, row, 0, 1, 2 );
191  optimizeLayout->addWidget( ct_menisrng, row++, 2, 1, 2 );
192  optimizeLayout->addWidget( lb_menispts, row, 0, 1, 2 );
193  optimizeLayout->addWidget( ct_menispts, row++, 2, 1, 2 );
194  optimizeLayout->addLayout( lo_mcarlo, row++, 0, 1, 4 );
195  optimizeLayout->addWidget( lb_mciters, row, 0, 1, 2 );
196  optimizeLayout->addWidget( ct_mciters, row++, 2, 1, 2 );
197  optimizeLayout->addWidget( pb_advance, row++, 0, 1, 4 );
198  optimizeLayout->addLayout( lo_iters, row++, 0, 1, 4 );
199  optimizeLayout->addWidget( lb_iters, row, 0, 1, 2 );
200  optimizeLayout->addWidget( ct_iters, row++, 2, 1, 2 );
201  optimizeLayout->addWidget( lb_statinfo, row++, 0, 1, 4 );
202  optimizeLayout->addWidget( te_status, row, 0, 2, 4 );
203  row += 6;
204 
205  QLabel* lb_optspace = us_banner( "" );
206  optimizeLayout->addWidget( lb_optspace, row, 0, 1, 2 );
207  optimizeLayout->setRowStretch( row, 2 );
208 
209  lb_constff0 ->setVisible( false );
210  ct_constff0 ->setVisible( false );
211 
212  ck_unifgr->setChecked( true );
213  ck_custgr->setChecked( false );
214  ck_iters ->setEnabled( true );
215  ct_iters ->setEnabled( false );
216 
218 
219  connect( ck_unifgr, SIGNAL( toggled( bool ) ),
220  this, SLOT( checkUniGrid( bool ) ) );
221  connect( ck_custgr, SIGNAL( toggled( bool ) ),
222  this, SLOT( checkCusGrid( bool ) ) );
223  connect( ck_menisc, SIGNAL( toggled( bool ) ),
224  this, SLOT( checkMeniscus( bool ) ) );
225  connect( ck_mcarlo, SIGNAL( toggled( bool ) ),
226  this, SLOT( checkMonteCar( bool ) ) );
227  connect( ck_iters, SIGNAL( toggled( bool ) ),
228  this, SLOT( checkIterate( bool ) ) );
229  connect( ck_varvbar, SIGNAL( toggled( bool ) ),
230  this, SLOT( checkVaryVbar( bool ) ) );
231 
232  connect( ct_nstepss, SIGNAL( valueChanged( double ) ),
233  this, SLOT( grid_change() ) );
234  connect( ct_nstepsk, SIGNAL( valueChanged( double ) ),
235  this, SLOT( grid_change() ) );
236  connect( ct_thrdcnt, SIGNAL( valueChanged( double ) ),
237  this, SLOT( grid_change() ) );
238  connect( ct_lolimits, SIGNAL( valueChanged( double ) ),
239  this, SLOT( slim_change() ) );
240  connect( ct_uplimits, SIGNAL( valueChanged( double ) ),
241  this, SLOT( slim_change() ) );
242  connect( ct_lolimitk, SIGNAL( valueChanged( double ) ),
243  this, SLOT( klim_change() ) );
244  connect( ct_nstepsk, SIGNAL( valueChanged( double ) ),
245  this, SLOT( kstep_change() ) );
246 
247  connect( pb_strtfit, SIGNAL( clicked() ),
248  this, SLOT( start() ) );
249  connect( pb_stopfit, SIGNAL( clicked() ),
250  this, SLOT( stop_fit() ) );
251  connect( pb_ldmodel, SIGNAL( clicked() ),
252  this, SLOT( load_model() ) );
253  connect( pb_plot, SIGNAL( clicked() ),
254  this, SLOT( plot() ) );
255  connect( pb_save, SIGNAL( clicked() ),
256  this, SLOT( save() ) );
257  connect( pb_help, SIGNAL( clicked() ),
258  this, SLOT( help() ) );
259  connect( pb_close, SIGNAL( clicked() ),
260  this, SLOT( close_all() ) );
261  connect( pb_advance, SIGNAL( clicked() ),
262  this, SLOT( advanced() ) );
263 
264  edata = &dsets[ 0 ]->run_data;
265 
266  grid_change();
267 
268 //DbgLv(2) << "Pre-resize AC size" << size();
269  resize( 710, 440 );
270 //DbgLv(2) << "Post-resize AC size" << size();
271 }
272 
273 // enable/disable optimize counters based on chosen method
275 {
276  ct_menisrng->setEnabled( ck_menisc->isChecked() );
277  ct_menispts->setEnabled( ck_menisc->isChecked() );
278  ct_mciters ->setEnabled( ck_mcarlo->isChecked() );
279 
280  ck_tinoise ->setEnabled( ! ck_mcarlo->isChecked() );
281  ck_rinoise ->setEnabled( ! ck_mcarlo->isChecked() );
282 
283  if ( ck_mcarlo->isChecked() )
284  {
285  ck_tinoise ->setChecked( false );
286  ck_rinoise ->setChecked( false );
287  }
288 
289  ct_menisrng->adjustSize();
290  adjustSize();
291 }
292 
293 // uncheck optimize options other than one just checked
295 {
296  if ( ckflag > 3 ) ck_unifgr->setChecked( false );
297  if ( ckflag == 3 ) ck_menisc->setChecked( false );
298  if ( ckflag == 2 ) ck_mcarlo->setChecked( false );
299 }
300 
301 // handle uniform grid checked
303 {
304  if ( checked )
305  uncheck_optimize( 1 );
306 
308 
309  ct_lolimits->setEnabled( checked );
310  ct_uplimits->setEnabled( checked );
311  ct_nstepss ->setEnabled( checked );
312  ct_lolimitk->setEnabled( checked );
313  ct_uplimitk->setEnabled( checked );
314  ct_nstepsk ->setEnabled( checked );
315  ct_thrdcnt ->setEnabled( checked );
316  ck_tinoise ->setEnabled( checked );
317  ck_rinoise ->setEnabled( checked );
318  if ( checked )
319  {
320  int nthr = US_Settings::threads();
321  nthr = ( nthr > 1 ) ? nthr : QThread::idealThreadCount();
322  ct_thrdcnt ->setValue ( nthr );
323  ck_varvbar ->setEnabled( true );
324  ct_constff0->setEnabled( true );
326  }
327 
328  ck_custgr ->disconnect();
329  ck_custgr ->setChecked( ! checked );
330  pb_ldmodel->setEnabled( ! checked );
331  connect( ck_custgr, SIGNAL( toggled( bool ) ),
332  this, SLOT( checkCusGrid( bool ) ) );
333 }
334 
335 // Handle custom grid checked
337 {
338  ck_unifgr ->setChecked( ! checked );
339  ck_varvbar->setEnabled( ! checked );
340 
341  if ( checked )
342  {
343  ct_thrdcnt ->setEnabled( true );
344  ck_tinoise ->setEnabled( true );
345  ck_rinoise ->setEnabled( true );
346  ct_constff0->setEnabled( false );
347  }
348 }
349 
350 // handle float meniscus position checkec
352 {
353  if ( checked )
354  uncheck_optimize( 2 );
355 
357 }
358 
359 // handle Monte Carlo checked
361 {
362  if ( checked )
363  {
364  uncheck_optimize( 3 );
365  }
366 
368 }
369 
370 // handle local uniform grid checked
372 {
373  if ( checked ) { uncheck_optimize( 4 ); optimize_options(); }
374 }
375 
376 // handle random local grid checked
378 {
379  if ( checked ) { uncheck_optimize( 5 ); optimize_options(); }
380 }
381 
382 // handle solute coalescing checked
384 {
385  if ( checked ) { uncheck_optimize( 6 ); optimize_options(); }
386 }
387 
388 // handle clip lowest conc. solute checked
390 {
391  if ( checked ) { uncheck_optimize( 7 ); optimize_options(); }
392 }
393 
394 // handle Regularization checked
396 {
397  if ( checked ) { uncheck_optimize( 8 ); optimize_options(); }
398 }
399 
400 // handle iterations checked
402 {
403  ct_iters->setEnabled( checked );
404  ct_iters->setValue( ( checked ? 3 : 1 ) );
405 }
406 
407 // handle vary-vbar checked
409 {
410  lb_constff0->setVisible( checked );
411  ct_constff0->setVisible( checked );
412 
413  if ( checked )
414  {
415  double vblo = dsets[ 0 ]->vbar20 - 0.02;
416  double vbhi = dsets[ 0 ]->vbar20 + 0.02;
417  vblo = (double)( (int)( vblo * 1000.0 ) ) * 0.001;
418  vbhi = (double)( (int)( vbhi * 1000.0 ) + 1 ) * 0.001;
419  lb_lolimitk->setText( tr( "Lower Limit (vbar):" ) );
420  lb_uplimitk->setText( tr( "Upper Limit (vbar):" ) );
421  lb_nstepsk ->setText( tr( "Number Grid Points (vbar):" ) );
422  ct_lolimitk->setMinValue( 0.025 );
423  ct_lolimitk->setMaxValue( 1.500 );
424  ct_lolimitk->setStep ( 0.001 );
425  ct_lolimitk->setValue ( vblo );
426  ct_uplimitk->setMinValue( 0.025 );
427  ct_uplimitk->setMaxValue( 1.500 );
428  ct_uplimitk->setStep ( 0.001 );
429  ct_uplimitk->setValue ( vbhi );
430  ct_constff0->setValue ( 2.000 );
431  }
432 
433  else
434  {
435  lb_lolimitk->setText( tr( "Lower Limit (f/f0):" ) );
436  lb_uplimitk->setText( tr( "Upper Limit (f/f0):" ) );
437  lb_nstepsk ->setText( tr( "Number Grid Points (f/f0):" ) );
438  ct_lolimitk->setMinValue( 1.0 );
439  ct_lolimitk->setMaxValue( 8.0 );
440  ct_lolimitk->setStep ( 0.01 );
441  ct_lolimitk->setValue ( 1.0 );
442  ct_uplimitk->setMinValue( 1.0 );
443  ct_uplimitk->setMaxValue( 20.0 );
444  ct_uplimitk->setStep ( 0.01 );
445  ct_uplimitk->setValue ( 4.0 );
446  }
447 }
448 
449 // start fit button clicked
451 {
452  if ( parentw )
453  { // Get pointers to needed objects from the main
454  US_2dsa* mainw = (US_2dsa*)parentw;
455  edata = mainw->mw_editdata();
456  sdata = mainw->mw_simdata();
457  rdata = mainw->mw_resdata();
458  model = mainw->mw_model();
459  ti_noise = mainw->mw_ti_noise();
460  ri_noise = mainw->mw_ri_noise();
461  mw_stattext = mainw->mw_status_text();
462  mw_baserss = mainw->mw_base_rss();
463  baserss = *mw_baserss;
464 
465  if ( baserss == 0 )
466  {
467  baserss = qRound( (double)US_Memory::rss_now() / 1024. );
468  *mw_baserss = baserss;
469  }
470 
471  mainw->analysis_done( -1 ); // reset counters to zero
472 DbgLv(1) << "AnaC: edata scans, baserss" << edata->scanData.size() << baserss;
473 DbgLv(1) << "AnaC: edata" << edata;
474  }
475 
476  // Make sure that ranges are reasonable
477  if ( ( ct_uplimits->value() - ct_lolimits->value() ) < 0.0 ||
478  ( ct_uplimitk->value() - ct_lolimitk->value() ) < 0.0 )
479  {
480  QString msg =
481  tr( "The \"s\" or \"f/f0\" ranges are inconsistent.\n"
482  "Please re-check the limits and correct them\n"
483  "before again clicking \"Start Fit\"." );
484 
485  if ( ck_varvbar->isChecked() )
486  msg = msg.replace( "f/f0", "vbar" );
487 
488  QMessageBox::critical( this, tr( "Limits Inconsistent!" ), msg );
489  return;
490  }
491 
492  // Make sure that any fit-meniscus is reasonable
493  if ( ck_menisc->isChecked() )
494  {
495  double menrng = ct_menisrng->value();
496  double bmenis = edata->meniscus;
497  double hmenis = bmenis + menrng * 0.5;
498  double lrdata = edata->xvalues[ 0 ];
499 
500  if ( hmenis >= lrdata )
501  {
502  QMessageBox::critical( this, tr( "Meniscus-Data Overlap!" ),
503  tr( "The highest meniscus (%1), implied in the range given,\n"
504  "equals or exceeds the low data range radius (%2).\n\n"
505  "You must either quit this program and re-edit the data\n"
506  "to have a low radius value farther from the meniscus;\n"
507  "or change the fit-meniscus range given here." )
508  .arg( hmenis ).arg( lrdata ) );
509  return;
510  }
511  }
512 
513  // Insure that max RPM and S-value imply a reasonable grid size
514  double s_max = ct_uplimits->value() * 1e-13;
515  QString smsg;
516 
517  if ( US_SolveSim::checkGridSize( dsets, s_max, smsg ) )
518  {
519  QMessageBox::critical( this,
520  tr( "Implied Grid Size is Too Large!" ),
521  smsg );
522 // return;
523  }
524 
525 DbgLv(1) << "AnaC:St:MEM (1)rssnow,proc" << US_Memory::rss_now() << processor;
526  // Start a processing object if need be
527  if ( processor == 0 )
528  processor = new US_2dsaProcess( dsets, this );
529 
530  else
531  {
532  processor->disconnect();
533  processor->stop_fit();
535  }
536 DbgLv(1) << "AnaC:St:MEM (2)rssnow" << US_Memory::rss_now();
537 
538  // Set up for the start of fit processing
539  le_iteration->setText( "0" );
540  le_oldvari ->setText( "0.000e-05" );
541  le_newvari ->setText( "0.000e-05" );
542  le_improve ->setText( "0.000e-08" );
543 
544  double slo = ct_lolimits->value();
545  double sup = ct_uplimits->value();
546  int nss = (int)ct_nstepss->value();
547  double klo = ct_lolimitk->value();
548  double kup = ct_uplimitk->value();
549  int nks = (int)ct_nstepsk->value();
550  int nthr = (int)ct_thrdcnt->value();
551  int noif = ( ck_tinoise->isChecked() ? 1 : 0 ) +
552  ( ck_rinoise->isChecked() ? 2 : 0 );
553 
554  int ngrr = ( grtype < 0 ) ? grtype
555  : US_Math2::best_grid_reps( nss, nks );
556 
557  ct_nstepss->setValue( nss );
558  ct_nstepsk->setValue( nks );
559 
560  ti_noise->values.clear();
561  ri_noise->values.clear();
562  ti_noise->count = 0;
563  ri_noise->count = 0;
564 
565  connect( processor, SIGNAL( progress_update( int ) ),
566  this, SLOT( update_progress( int ) ) );
567  connect( processor, SIGNAL( message_update( QString, bool ) ),
568  this, SLOT( progress_message( QString, bool ) ) );
569  connect( processor, SIGNAL( stage_complete( int, int ) ),
570  this, SLOT( reset_steps( int, int ) ) );
571  connect( processor, SIGNAL( process_complete( int ) ),
572  this, SLOT( completed_process( int ) ) );
573 
574  int mxiter = (int)ct_iters->value();
575  int mniter = ck_menisc->isChecked() ?
576  (int)ct_menispts->value() : 0;
577  int mciter = ck_mcarlo->isChecked() ?
578  (int)ct_mciters ->value() : 0;
579  double vtoler = 1.0e-12;
580  double menrng = ct_menisrng->value();
581  double cff0 = ck_varvbar->isChecked() ? ct_constff0->value() : 0.0;
582  nctotal = 10000;
583 
584  // Check memory and possibly abort fit if too much needed
585  if ( memory_check() != 0 )
586  return;
587 
588  // Begin the fit
589  processor->set_iters( mxiter, mciter, mniter, vtoler, menrng, cff0, ngrr );
590 
591  processor->start_fit( slo, sup, nss, klo, kup, nks,
592  ngrr, nthr, noif );
593 
594  pb_strtfit->setEnabled( false );
595  pb_stopfit->setEnabled( true );
596  pb_plot ->setEnabled( false );
597  pb_save ->setEnabled( false );
598 }
599 
600 // stop fit button clicked
602 {
603 DbgLv(1) << "AC:SF:StopFit";
604  if ( processor != 0 )
605  {
606 DbgLv(1) << "AC:SF: processor stopping...";
607  processor->disconnect();
608  processor->stop_fit();
609 DbgLv(1) << "AC:SF: processor stopped";
610  delete processor;
611 DbgLv(1) << "AC:SF: processor deleted";
612  }
613 
614  //delete processor;
615  processor = 0;
616 //DbgLv(1) << "AC:SF: processor deleted";
617 
618  qApp->processEvents();
619  b_progress->reset();
620 
621  pb_strtfit->setEnabled( true );
622  pb_stopfit->setEnabled( false );
623  pb_plot ->setEnabled( false );
624  pb_save ->setEnabled( false );
625  qApp->processEvents();
626 
627  if ( parentw )
628  {
629  US_2dsa* mainw = (US_2dsa*)parentw;
630  mainw->analysis_done( -1 );
631  }
632 
633  qApp->processEvents();
634 }
635 
636 // Load Model button clicked
638 {
639  QString mdesc( "" );
640  QString mfilter( "" );
641  US_Model cusmodel;
642  US_2dsa* mainw = NULL;
643 
644  if ( parentw )
645  {
646  mainw = (US_2dsa*)parentw;
647  mfilter = QString( "CustomGrid" );
648  mainw->analysis_done( -1 );
649  }
650 
651  US_ModelLoader dialog( loadDB, mfilter, cusmodel, mdesc, "" );
652 
653  if ( dialog.exec() == QDialog::Accepted )
654  {
655  int nsol = cusmodel.components.size();
656  int nsubg = cusmodel.subGrids;
657  int sgsize = nsol / nsubg;
658 
659  if ( sgsize > 150 )
660  { // Implied subgrid size too large: change subgrid count
661  int ksubg = nsubg;
662  int kssiz = sgsize;
663  nsubg = ( nsol / 100 + 1 ) | 1;
664  sgsize = nsol / nsubg;
665  DbgLv(0) << "Subgrid count adjusted from" << ksubg << "to" << nsubg;
666  DbgLv(0) << "Subgrid size adjusted from" << kssiz << "to" << sgsize;
667  cusmodel.subGrids = nsubg;
668  }
669 
670  QString amsg =
671  tr( "Grid from loaded model\n ( " )
672  + QString::number( nsol ) + tr( " solutes, " )
673  + QString::number( nsubg ) + tr( " subgrids )" );
674  te_status ->setText( amsg );
675 
676  if ( parentw )
677  {
678  model = mainw->mw_model();
679  *model = cusmodel;
680  }
681 
682  dsets[ 0 ]->model = cusmodel;
683  grtype = -1;
684  bool cnst_ff0 = ! cusmodel.constant_vbar();
685  ck_varvbar ->setChecked( cnst_ff0 );
686 
687  if ( cnst_ff0 )
688  ct_constff0->setValue( cusmodel.components[ 0 ].f_f0 );
689  }
690 }
691 
692 // plot button clicked
694 {
695  US_2dsa* mainw = (US_2dsa*)parentw;
696  mainw->analysis_done( 1 );
697 }
698 
699 // save button clicked
701 {
702  US_2dsa* mainw = (US_2dsa*)parentw;
703  mainw->analysis_done( 2 );
704 }
705 
706 // Close button clicked
708 {
709  close();
710 }
711 
712 // Reset memory estimate when grid steps, threads or repetitions changes
714 {
715  int nsteps = (int)ct_nstepss ->value(); // # steps s
716  int nstepk = (int)ct_nstepsk ->value(); // # steps k
717  int nthrd = (int)ct_thrdcnt ->value(); // # threads
718  int nscan = edata->scanCount(); // # scans
719  int nconc = edata->pointCount(); // # concentrations
720  int ntconc = nconc * nscan; // # total readings
721  double megas = sq( 1024.0 );
722 
723  int ngrrep = US_Math2::best_grid_reps( nsteps, nstepk );
724 
725  int ngstep = nsteps * nstepk; // # grid steps
726 
727  if ( parentw )
728  { // Get the starting base rss memory of this dataset and parameters
729  US_2dsa* mainw = (US_2dsa*)parentw;
730  mw_baserss = mainw->mw_base_rss();
731  baserss = *mw_baserss;
732 
733  if ( baserss == 0 )
734  {
735  baserss = qRound( (double)US_Memory::rss_now() / 1024. );
736  *mw_baserss = baserss;
737  }
738  }
739  const double x_fact = 17.20;
740  const double y_fact = 2.28;
741  const int nxdata = 4;
742  int nsstep = ( nsteps / ngrrep ) * ( nstepk / ngrrep );
743  int noif = ( ck_tinoise->isChecked() ? 1 : 0 ) +
744  ( ck_rinoise->isChecked() ? 2 : 0 );
745  int ndatas = nsstep + nxdata + noif;
746  double mdata = ( (double)ntconc * ndatas * sizeof( double ) ) / megas;
747  double tdata = x_fact + mdata * y_fact;
748  memneed = baserss + qRound( tdata * (double)nthrd );
749 DbgLv(1) << "GC: baserss tdata mdata ndatas nthrd" << baserss
750  << qRound(tdata) << qRound(mdata) << ndatas << nthrd << "memneed" << memneed;
751 
752  int memava, memtot;
753  US_Memory::memory_profile( &memava, &memtot );
754 
755  le_estmemory->setText( tr( "%1 MB (of %2 MB total real)" )
756  .arg( memneed ).arg( memtot ) );
757 
758 DbgLv(1) << "GC: ngrrep nsteps nstepk" << ngrrep << nsteps << nstepk;
759 
760  // Output a message documenting the grid and subgrid dimensions
761 // int nss = nsteps / ngrrep;
762 // int nsk = nstepk / ngrrep;
763  int nss = nsteps / ngrrep;
764  int nsk = nstepk / ngrrep;
765  int nspts = nss * nsk;
766  int nsubg = sq( ngrrep );
767  QString gmsg = tr( "Total grid is approximately %1 points (%2 x %3).\n" )
768  .arg( ngstep ).arg( nsteps ).arg( nstepk );
769  gmsg += tr( "Subgrid repetitions is %1 subgrids (%2 ^ 2)\n"
770  " with a maximum of %3 points each (%4 x %5)." )
771  .arg( nsubg ).arg( ngrrep ).arg( nspts ).arg( nss ).arg( nsk );
772  te_status ->setText( gmsg );
773  le_gridreps->setText( tr( "%1 ( -> %2 %3-point subgrids )" )
774  .arg( ngrrep ).arg( nsubg ).arg( nspts ) );
775 }
776 
777 // Adjust s-limit ranges when s-limit value changes
779 {
780  double loval = ct_lolimits->value();
781  double upval = ct_uplimits->value();
782  double limlo = -1.e6;
783  double limup = 1.e6;
784  if ( loval > upval ) // Insure lower value less than upper
785  ct_lolimits->setValue( upval );
786 
787  if ( loval < -1.e5 || upval > 1.e5 )
788  { // For larger magnitudes, adjust ranges
789  if ( loval < -1.e6 || upval > 1.e6 )
790  {
791  if ( loval < -1.e7 || upval > 1.e7 )
792  {
793  limlo = -1.e19;
794  limup = 1.e19;
795  }
796  else
797  {
798  limlo = -1.e8;
799  limup = 1.e8;
800  }
801  }
802  else
803  {
804  limlo = -1.e7;
805  limup = 1.e7;
806  }
807  }
808 
809  ct_lolimits->setRange( limlo, upval );
810  ct_uplimits->setRange( loval, limup );
811  ct_lolimits->setStep( 0.1 );
812  ct_uplimits->setStep( 0.1 );
813 }
814 
815 // Set k-upper-limit to lower when k grid points == 1
817 {
818  if ( ct_nstepsk->value() == 1.0 )
819  {
820  ct_uplimitk->setValue( ct_lolimitk->value() );
821  }
822 }
823 
824 // Test for k-steps==1 when k-step value changes
826 {
827  if ( ct_nstepsk->value() == 1.0 )
828  { // Set up for C(s) parameters
829  ct_uplimitk->setValue( ct_lolimitk->value() );
830  ct_thrdcnt ->setValue( 1.0 );
831  ct_uplimitk->setEnabled( false );
832  ct_thrdcnt ->setEnabled( false );
833  }
834 
835  else if ( ct_uplimitk->value() == ct_lolimitk->value() )
836  { // Set up for normal 2dsa parameters
837  ct_uplimitk->setValue( 4.0 );
838  int nthr = US_Settings::threads();
839  nthr = ( nthr > 1 ) ? nthr : QThread::idealThreadCount();
840  ct_thrdcnt ->setValue( nthr );
841  ct_uplimitk->setEnabled( true );
842  ct_thrdcnt ->setEnabled( true );
843  }
844 }
845 
846 // slot to handle progress update
848 {
849  ncsteps += ksteps;
850 
851  if ( ncsteps > nctotal )
852  {
853  nctotal = ( nctotal * 11 ) / 10;
854  b_progress->setMaximum( nctotal );
855  }
856 
857  b_progress->setValue( ncsteps );
858 DbgLv(2) << "UpdPr: ks ncs nts" << ksteps << ncsteps << nctotal;
859 }
860 
861 // slot to handle updated progress message
862 void US_AnalysisControl2D::progress_message( QString pmsg, bool append )
863 {
864  QString amsg;
865 
866  if ( append )
867  { // append to existing progress message
868  amsg = te_status->toPlainText() + "\n" + pmsg;
869  }
870 
871  else
872  { // create a new progress message
873  amsg = pmsg;
874  }
875 
876  mw_stattext->setText( amsg );
877  te_status ->setText( amsg );
878 
879  qApp->processEvents();
880 }
881 
882 // Slot to handle resetting progress
883 void US_AnalysisControl2D::reset_steps( int kcs, int nct )
884 {
885 DbgLv(1) << "AC:cs: prmx nct kcs" << b_progress->maximum() << nct << kcs;
886  ncsteps = kcs;
887  nctotal = nct;
888 
889  b_progress->setMaximum( nctotal );
890  b_progress->setValue( ncsteps );
891 
892  qApp->processEvents();
893 }
894 
895 // slot to handle completed processing
897 {
898  bool alldone = ( stage == 9 );
899 DbgLv(1) << "AC:cp: stage alldone" << stage << alldone;
900 
901  b_progress->setValue( nctotal );
902  qApp->processEvents();
903 
904  if ( stage == 6 )
905  { // If stopped because of memory usage, execute Stop Fit
906  stop_fit();
907  return;
908  }
909 
911 DbgLv(1) << "AC:cp: RES: ti,ri counts" << ti_noise->count << ri_noise->count;
912 //DBG-DATA
913 #if 1
914 if (dbg_level>0)
915 {
916  double dtot=0.0;
917  double ntot=0.0;
918  double stot=0.0;
919  int nnoi=ti_noise->count;
920  int knoi=ti_noise->values.count();
921  for (int ii=0; ii<edata->scanCount(); ii++ )
922  for (int jj=0; jj<edata->pointCount(); jj++ )
923  {
924  dtot += edata->value(ii,jj);
925  stot += sdata->value(ii,jj);
926  }
927  for (int jj=0; jj<knoi; jj++ )
928  ntot += ti_noise->values[jj];
929  DbgLv(1) << "AC:cp DTOT" << dtot << "edata" << edata << "NTOT" << ntot
930  << "nnoi knoi" << nnoi << knoi << "STOT" << stot;
931 }
932 #endif
933 //DBG-DATA
934 
935  US_DataIO::Scan* rscan0 = &rdata->scanData[ 0 ];
936  int iternum = (int)rscan0->rpm;
937  int mmitnum = (int)rscan0->seconds;
938  double varinew = rscan0->delta_r;
939  double meniscus = rscan0->plateau;
940  double variold = le_newvari ->text().toDouble();
941  double vimprov = variold - varinew;
942  le_oldvari ->setText( QString::number( variold ) );
943  le_newvari ->setText( QString::number( varinew ) );
944  le_improve ->setText( QString::number( vimprov ) );
945 
946  if ( mmitnum == 0 )
947  { // simple refinement iteration (no MC/Meniscus)
948  le_iteration->setText( QString::number( iternum ) );
949  model->description = QString( "MMITER=%1 VARI=%2 " )
950  .arg( mmitnum ).arg( varinew );
951  }
952 
953  else if ( ck_menisc->isChecked() )
954  { // Meniscus
956  model->description = QString( "MMITER=%1 VARI=%2 MENISCUS=%3" )
957  .arg( mmitnum ).arg( varinew ).arg( meniscus );
958  le_iteration->setText( QString::number( iternum ) + " ( Model " +
959  QString::number( mmitnum ) + " , Meniscus " +
960  QString::number( meniscus ) + " )" );
961  }
962 
963  else
964  { // Monte Carlo
965  model->monteCarlo = true;
966  model->description = QString( "MMITER=%1 VARI=%2 " )
967  .arg( mmitnum ).arg( varinew );
968  le_iteration->setText( QString::number( iternum ) + " ( MC Model " +
969  QString::number( mmitnum ) + " )" );
970  }
971 
972  if ( ck_custgr->isChecked() )
973  model->description = model->description + QString( " CUSTOMGRID" );
974 
975  US_2dsa* mainw = (US_2dsa*)parentw;
976 
977  if ( alldone )
978  {
979  mainw->analysis_done( -2 );
980 
981  mainw->analysis_done( ck_autoplt->isChecked() ? 1 : 0 );
982 
983  pb_strtfit->setEnabled( true );
984  pb_stopfit->setEnabled( false );
985  pb_plot ->setEnabled( true );
986  pb_save ->setEnabled( true );
987  }
988 
989  else if ( mmitnum > 0 && stage > 0 )
990  { // signal main to update lists of models,noises
991  mainw->analysis_done( -2 );
992  }
993 }
994 
995 // slot to handle advanced analysis controls
997 {
998  US_SimulationParameters* sparms = &dsets[ 0 ]->simparams;
999 DbgLv(1) << "Adv sparms.bf sect" << sparms->band_forming << sparms->cp_sector;
1000 
1001  US_AdvAnalysis2D* aadiag = new US_AdvAnalysis2D( sparms, loadDB, this );
1002  if ( aadiag->exec() == QDialog::Accepted )
1003  {
1005  double grpar1 = 0.0;
1006  double grpar2 = 0.0;
1007  double grpar3 = 0.0;
1008  bool reg = false;
1009  double repar1 = 0.0;
1010  US_Model modpar;
1011 
1012  aadiag->get_parameters( grtype, grpar1, grpar2, grpar3,
1013  modpar, reg, repar1 );
1014 DbgLv(1) << "Adv ACCEPT";
1015 DbgLv(1) << "Adv grtype par123" << grtype << grpar1 << grpar2 << grpar3;
1016 DbgLv(1) << "Adv modpar size " << modpar.components.size();
1017 DbgLv(1) << "Adv reg par1 " << reg << repar1;
1018 DbgLv(1) << "Adv BANDVOL" << sparms->band_volume << " MUL" << sparms->cp_width;
1019  if ( grtype < 0 )
1020  {
1021  int nsol = modpar.components.size();
1022  int nsubg = modpar.subGrids;
1023  int sgsize = nsol / nsubg;
1024 
1025  if ( sgsize > 150 )
1026  { // Implied subgrid size too large: change subgrid count
1027  int ksubg = nsubg;
1028  int kssiz = sgsize;
1029  nsubg = ( nsol / 100 + 1 ) | 1;
1030  sgsize = nsol / nsubg;
1031  DbgLv(0) << "Subgrid count adjusted from" << ksubg << "to" << nsubg;
1032  DbgLv(0) << "Subgrid size adjusted from" << kssiz << "to" << sgsize;
1033  modpar.subGrids = nsubg;
1034  }
1035 
1036  QString amsg = ( grtype == (-1 )
1037  ? tr( "Grid from loaded model\n ( " )
1038  : tr( "Grid and signal ratios from loaded model\n\n ( " ) )
1039  + QString::number( nsol ) + tr( " solutes, " )
1040  + QString::number( nsubg ) + tr( " subgrids )" );
1041  te_status ->setText( amsg );
1042 
1043  US_2dsa* mainw = (US_2dsa*)parentw;
1044  model = mainw->mw_model();
1045  *model = modpar;
1046  dsets[ 0 ]->model = modpar;
1047 
1048  if ( nsol > 0 )
1049  {
1050  uncheck_optimize( 4 );
1051  optimize_options();
1052  ct_lolimits->setEnabled( false );
1053  ct_uplimits->setEnabled( false );
1054  ct_nstepss ->setEnabled( false );
1055  ct_lolimitk->setEnabled( false );
1056  ct_uplimitk->setEnabled( false );
1057  ct_nstepsk ->setEnabled( false );
1058  ct_thrdcnt ->setEnabled( true );
1059  ck_varvbar ->setEnabled( false );
1060  ck_varvbar ->setChecked( ! model->constant_vbar() );
1061  ct_constff0->setEnabled( false );
1062  }
1063 
1064  else
1066  }
1067  }
1068 else
1069 DbgLv(1) << "Adv REJECT";
1070 
1071  qApp->processEvents();
1072 
1073  delete aadiag;
1074 }
1075 
1076 // Output warning if need be about memory needs, return continue flag
1078 {
1079  const int pc_ava = 90;
1080  int status = 0;
1081  int memava, memtot, memuse;
1082  int mempca = US_Memory::memory_profile( &memava, &memtot, &memuse );
1083  int memsafe = ( memava * pc_ava ) / 100;
1084 
1085  if ( memneed > memsafe || mempca < 20 )
1086  {
1087  QString title = tr( "High Memory Usage" );
1088  QString memp = tr( "\n\nMemory Profile --\n"
1089  " Total: %1 MB\n"
1090  " Available: %2 MB\n"
1091  " Used: %3 MB\n"
1092  " Estimated Need: %4 MB\n\n" )
1093  .arg( memtot ).arg( memava ).arg( memuse ).arg( memneed );
1094 
1095  if ( memneed > memtot )
1096  {
1097  QMessageBox::critical( this, title,
1098  tr( "Memory needed for this fit exceeds total available." )
1099  + memp + tr( "This fit will not proceed.\n"
1100  "Re-parameterize the fit with adjusted\n"
1101  "Grid Refinements and/or Thread Count." ) );
1102  status = 1;
1103  }
1104 
1105  else
1106  {
1107  QMessageBox msgBox( this );
1108  msgBox.setWindowTitle( title );
1109  msgBox.setText( tr( "Memory needed for this fit is a\n"
1110  "high percentage of the available memory." )
1111  + memp +
1112  tr( "You may proceed if you wish (\"Yes\")\n"
1113  "Or you may stop this fit (\"No\")\n"
1114  "then re-parameterize the fit with adjusted\n"
1115  "Grid Refinements and/or Thread Count.\n\nProceed?" ) );
1116  msgBox.addButton( QMessageBox::No );
1117  msgBox.addButton( QMessageBox::Yes );
1118  msgBox.setDefaultButton( QMessageBox::No );
1119 
1120  if ( msgBox.exec() == QMessageBox::No )
1121  status = 2;
1122  }
1123  }
1124 
1125  return status;
1126 }
1127