UltraScan III
us_simulationparameters.cpp
Go to the documentation of this file.
2 #include "us_constants.h"
3 #include "us_gui_settings.h"
4 #include "us_settings.h"
5 
8  : US_WidgetsDialog( 0, 0 ), simparams( params )
9 {
10  setWindowTitle( "Set Simulation Parameters" );
11  setPalette ( US_GuiSettings::frameColor() );
12  setAttribute ( Qt::WA_DeleteOnClose );
13 
14  backup_parms();
15 
16  QGridLayout* main = new QGridLayout( this );
17  main->setContentsMargins ( 2, 2, 2, 2 );
18  main->setSpacing( 2 );
19 
20  int row = 0;
21 
22  QLabel* lb_info = us_banner( tr( "Simulation Run Parameter Setup" ) );
23  main->addWidget( lb_info, row++, 0, 1, 8 );
24 
25  // Left column
26 
27  // Speed Profile count
28  QLabel* lb_speeds = us_label( tr( "Number of Speed Profiles:" ) );
29  main->addWidget( lb_speeds, row, 0, 1, 3 );
30 
31  cnt_speeds = us_counter( 2, 1, 100, 1 );
32  cnt_speeds->setStep ( 1 );
33 
34  main->addWidget( cnt_speeds, row++, 3, 1, 1 );
35  connect( cnt_speeds, SIGNAL( valueChanged ( double ) ),
36  SLOT ( update_speeds( double ) ) );
37  // Speeds combo box
39 
41 
42  for ( int i = 0; i < simparams.speed_step.size(); i++ )
43  {
45 
46  cmb_speeds->addItem( "Speed Profile " +
47  QString::number( i + 1 ) + ": " +
48  QString::number( spi->duration_hours ) + " hr " +
49  QString::number( spi->duration_minutes ) + " min, " +
50  QString::number( spi->rotorspeed ) + " rpm" );
51  }
52 
53  main->addWidget( cmb_speeds, row++, 0, 1, 4 );
54  connect( cmb_speeds, SIGNAL( activated ( int ) ),
55  SLOT ( select_speed_profile( int ) ) );
56 
57  // Experiment hours
58  QLabel* lb_hours = us_label( tr( "Length of Experiment (Hours):" ) );
59  main->addWidget( lb_hours, row, 0, 1, 3 );
60 
61  cnt_duration_hours = us_counter( 3, 0, 5000, sp->duration_hours );
62  cnt_duration_hours->setStep ( 1 );
63  cnt_duration_hours->setIncSteps( QwtCounter::Button1, 1 );
64  cnt_duration_hours->setIncSteps( QwtCounter::Button2, 10 );
65  cnt_duration_hours->setIncSteps( QwtCounter::Button3, 100 );
66 
67  main->addWidget( cnt_duration_hours, row++, 3, 1, 1 );
68  connect( cnt_duration_hours, SIGNAL( valueChanged ( double ) ),
69  SLOT ( update_duration_hours( double ) ) );
70 
71  // Experiment minutes
72  QLabel* lb_mins = us_label( tr( "Length of Experiment (Minutes):" ) );
73  main->addWidget( lb_mins, row, 0, 1, 3 );
74 
76  cnt_duration_mins->setStep ( 1 );
77  cnt_duration_mins->setIncSteps( QwtCounter::Button1, 1 );
78  cnt_duration_mins->setIncSteps( QwtCounter::Button2, 10 );
79  cnt_duration_mins->setIncSteps( QwtCounter::Button3, 10 );
80 
81  main->addWidget( cnt_duration_mins, row++, 3, 1, 1 );
82  connect( cnt_duration_mins, SIGNAL( valueChanged ( double ) ),
83  SLOT ( update_duration_mins( double ) ) );
84 
85  // Delay hours
86  QLabel* lb_delay_hours = us_label( tr( "Time Delay for Scans (Hours):" ) );
87  main->addWidget( lb_delay_hours, row, 0, 1, 3 );
88 
89  cnt_delay_hours = us_counter( 3, 0, 5000, sp->delay_hours );
90  cnt_delay_hours->setStep ( 1 );
91  cnt_delay_hours->setIncSteps( QwtCounter::Button1, 1 );
92  cnt_delay_hours->setIncSteps( QwtCounter::Button2, 10 );
93  cnt_delay_hours->setIncSteps( QwtCounter::Button3, 100 );
94 
95  main->addWidget( cnt_delay_hours, row++, 3, 1, 1 );
96  connect( cnt_delay_hours, SIGNAL( valueChanged ( double ) ),
97  SLOT ( update_delay_hours( double ) ) );
98 
99  // Delay minutes
100  QLabel* lb_delay_mins = us_label( tr( "Time Delay for Scans (Minutes):" ) );
101  main->addWidget( lb_delay_mins, row, 0, 1, 3 );
102 
103  cnt_delay_mins = us_counter( 3, 0, 59, sp->delay_minutes );
104  cnt_delay_mins->setStep ( 0.1 );
105  cnt_delay_mins->setIncSteps( QwtCounter::Button1, 1 );
106  cnt_delay_mins->setIncSteps( QwtCounter::Button2, 10 );
107  cnt_delay_mins->setIncSteps( QwtCounter::Button3, 100 );
108 
109  main->addWidget( cnt_delay_mins, row++, 3, 1, 1 );
110  connect( cnt_delay_mins, SIGNAL( valueChanged ( double ) ),
111  SLOT ( update_delay_mins( double ) ) );
112 
113  // Rotor Speed
114  QLabel* lb_rotor = us_label( tr( "Rotor Speed (rpm):" ) );
115  main->addWidget( lb_rotor, row, 0, 1, 3 );
116 
117  cnt_rotorspeed = us_counter( 3, 1000, 100000, sp->rotorspeed );
118  cnt_rotorspeed->setStep ( 100 );
119  cnt_rotorspeed->setIncSteps( QwtCounter::Button1, 1 );
120  cnt_rotorspeed->setIncSteps( QwtCounter::Button2, 10 );
121  cnt_rotorspeed->setIncSteps( QwtCounter::Button3, 100 );
122 
123  QFontMetrics fm( cnt_rotorspeed->font() );
124  cnt_rotorspeed->setMinimumWidth( fm.maxWidth() * 12 );
125 
126  main->addWidget( cnt_rotorspeed, row++, 3, 1, 1 );
127  connect( cnt_rotorspeed, SIGNAL( valueChanged ( double ) ),
128  SLOT ( update_rotorspeed( double ) ) );
129 
130  // Simulate rotor accel checkbox
131  QLabel* lb_rotorAccel = us_label( tr( "Simulate Rotor Acceleration:" ) );
132  main->addWidget( lb_rotorAccel, row, 0, 1, 3 );
133 
134  QGridLayout* acceleration_flag = us_checkbox( tr( "(Check to enable)" ),
136 
137  main->addLayout( acceleration_flag, row++, 3, 1, 1 );
138 
139  connect( cb_acceleration_flag, SIGNAL( clicked () ),
140  SLOT ( acceleration_flag() ) );
141 
142  // Acceleration Profile
143  QLabel* lb_accelProfile = us_label( tr( "Acceleration Profile (rpm/sec):" ));
144  main->addWidget( lb_accelProfile, row, 0, 1, 3 );
145 
146  cnt_acceleration = us_counter( 3, 5, 400 );
147  cnt_acceleration->setStep ( 5 );
148  cnt_acceleration->setIncSteps( QwtCounter::Button1, 1 );
149  cnt_acceleration->setIncSteps( QwtCounter::Button2, 10 );
150  cnt_acceleration->setIncSteps( QwtCounter::Button3, 100 );
151 
152  cnt_acceleration->setValue( sp->acceleration );
153 
154  main->addWidget( cnt_acceleration, row++, 3, 1, 1 );
155  connect( cnt_acceleration, SIGNAL( valueChanged ( double ) ),
156  SLOT ( update_acceleration( double ) ) );
157 
158  // Scans to be saved
159  QLabel* lb_scans = us_label( tr( "Scans to be saved:" ) );
160  main->addWidget( lb_scans, row, 0, 1, 3 );
161 
162  cnt_scans = us_counter( 3, 2, 5000, sp->scans );
163  cnt_scans->setStep ( 1 );
164  cnt_scans->setIncSteps( QwtCounter::Button1, 1 );
165  cnt_scans->setIncSteps( QwtCounter::Button2, 10 );
166  cnt_scans->setIncSteps( QwtCounter::Button3, 100 );
167 
168  main->addWidget( cnt_scans, row++, 3, 1, 1 );
169  connect( cnt_scans, SIGNAL( valueChanged( double ) ),
170  SLOT ( update_scans( double ) ) );
171 
172  // Speed profile
173  QLabel* lb_speedProfile = us_label( tr( "Select a Speed Profile:" ) );
174  main->addWidget( lb_speedProfile, row, 0, 1, 3 );
175 
176  current_speed_step = 0;
177  cnt_selected_speed = us_counter( 3, 1, simparams.speed_step.size(), 0 );
178  cnt_selected_speed->setStep ( 1 );
179  cnt_selected_speed->setIncSteps( QwtCounter::Button1, 1 );
180  cnt_selected_speed->setIncSteps( QwtCounter::Button2, 1 );
181  cnt_selected_speed->setIncSteps( QwtCounter::Button3, 1 );
182  cnt_selected_speed->setValue( sp->rotorspeed );
183  main->addWidget( cnt_selected_speed, row++, 3, 1, 1 );
184 
185  // Right Column
186  row = 1;
187  // Centerpiece
188 
189  QGridLayout* rb1 = us_radiobutton( tr( "Standard Centerpiece" ),
191 
192  main->addLayout( rb1, row, 4, 1, 2 );
193 
194  QGridLayout* rb2 = us_radiobutton( tr( "Band-forming Centerpiece" ),
196 
197  main->addLayout( rb2, row++, 6, 1, 2 );
198 
199  connect( rb_standard, SIGNAL( toggled ( bool ) ),
200  SLOT ( select_centerpiece( bool ) ) );
201 
202  // Band loading
203  QLabel* lb_lamella = us_label( tr( "Band loading volume (" )
204  + QString( QChar( 181 ) ) + "l):" );
205  main->addWidget( lb_lamella, row, 4, 1, 3 );
206 
207  cnt_lamella = us_counter( 3, 1, 20, 15 );
208  cnt_lamella->setStep ( 0.1 );
209  cnt_lamella->setIncSteps( QwtCounter::Button1, 1 );
210  cnt_lamella->setIncSteps( QwtCounter::Button2, 10 );
211  cnt_lamella->setEnabled( false );
212 
213  main->addWidget( cnt_lamella, row++, 7, 1, 1 );
214  connect( cnt_lamella, SIGNAL( valueChanged ( double ) ),
215  SLOT ( update_lamella( double ) ) );
216 
217  // Meniscus position
218  QLabel* lb_meniscus = us_label( tr( "Meniscus Position (cm):" ) );
219  main->addWidget( lb_meniscus, row, 4, 1, 3 );
220 
221  cnt_meniscus = us_counter( 3, 1.0, 10.0, simparams.meniscus );
222  cnt_meniscus->setStep ( 0.001 );
223  cnt_meniscus->setValue ( simparams.meniscus );
224  cnt_meniscus->setIncSteps( QwtCounter::Button1, 1 );
225  cnt_meniscus->setIncSteps( QwtCounter::Button2, 10 );
226  cnt_meniscus->setIncSteps( QwtCounter::Button3, 100 );
227 
228  main->addWidget( cnt_meniscus, row++, 7, 1, 1 );
229  connect( cnt_meniscus, SIGNAL( valueChanged ( double ) ),
230  SLOT ( update_meniscus( double ) ) );
231 
232  // Cell bottom
233  QLabel* lb_bottom = us_label( tr( "Bottom of Cell Position (cm):" ) );
234  main->addWidget( lb_bottom, row, 4, 1, 3 );
235 
236  cnt_bottom = us_counter( 3, 3.8, 30.0, simparams.bottom_position );
237  cnt_bottom->setStep ( 0.001 );
238  cnt_bottom->setValue ( simparams.bottom_position );
239  cnt_bottom->setIncSteps( QwtCounter::Button1, 1 );
240  cnt_bottom->setIncSteps( QwtCounter::Button2, 10 );
241  cnt_bottom->setIncSteps( QwtCounter::Button3, 100 );
242 
243  main->addWidget( cnt_bottom, row++, 7, 1, 1 );
244  connect( cnt_bottom, SIGNAL( valueChanged ( double ) ),
245  SLOT ( update_bottom( double ) ) );
246 
247  // Radial Discretization
248  QLabel* lb_simpoints = us_label( tr( "Radial Discretization (points):" ) );
249  main->addWidget( lb_simpoints, row, 4, 1, 3 );
250 
251  cnt_simpoints = us_counter( 3, 50, 10000, 200 );
252  cnt_simpoints->setStep ( 10 );
253  cnt_simpoints->setValue( simparams.simpoints );
254 
255  main->addWidget( cnt_simpoints, row++, 7, 1, 1 );
256  connect( cnt_simpoints, SIGNAL( valueChanged ( double ) ),
257  SLOT ( update_simpoints( double ) ) );
258 
259  // Radial Resolution
260  QLabel* lb_radial_res = us_label( tr( "Radial Resolution (cm):" ) );
261  main->addWidget( lb_radial_res, row, 4, 1, 3 );
262 
264  cnt_radial_res->setStep ( 1e-5 );
265  cnt_radial_res->setIncSteps( QwtCounter::Button1, 1 );
266  cnt_radial_res->setIncSteps( QwtCounter::Button2, 10 );
267  cnt_radial_res->setIncSteps( QwtCounter::Button3, 100 );
268 
269  main->addWidget( cnt_radial_res, row++, 7, 1, 1 );
270  connect( cnt_radial_res, SIGNAL( valueChanged ( double ) ),
271  SLOT ( update_radial_res( double ) ) );
272 
273  // Random noise
274  QLabel* lb_rnoise = us_label( tr( "Random Noise (% Conc.):" ) );
275  main->addWidget( lb_rnoise, row, 4, 1, 3 );
276 
277  cnt_rnoise = us_counter( 3, 0, 10, simparams.rnoise );
278  cnt_rnoise->setStep ( 0.01 );
279  cnt_rnoise->setIncSteps( QwtCounter::Button1, 1 );
280  cnt_rnoise->setIncSteps( QwtCounter::Button2, 10 );
281  cnt_rnoise->setIncSteps( QwtCounter::Button3, 100 );
282 
283  main->addWidget( cnt_rnoise, row++, 7, 1, 1 );
284  connect( cnt_rnoise, SIGNAL( valueChanged ( double ) ),
285  SLOT ( update_rnoise( double ) ) );
286 
287  connect( cnt_selected_speed, SIGNAL( valueChanged ( double ) ),
288  SLOT ( update_speed_profile( double ) ) );
289 
290  // Time invariant noise
291  QLabel* lb_tinoise = us_label( tr( "Time Invariant Noise (% Conc.):" ) );
292  main->addWidget( lb_tinoise, row, 4, 1, 3 );
293 
294  cnt_tinoise = us_counter( 3, 0, 10, simparams.tinoise );
295  cnt_tinoise->setStep ( 0.01 );
296  cnt_tinoise->setIncSteps( QwtCounter::Button1, 1 );
297  cnt_tinoise->setIncSteps( QwtCounter::Button2, 10 );
298  cnt_tinoise->setIncSteps( QwtCounter::Button3, 100 );
299 
300  main->addWidget( cnt_tinoise, row++, 7, 1, 1 );
301  connect( cnt_tinoise, SIGNAL( valueChanged ( double ) ),
302  SLOT ( update_tinoise( double ) ) );
303 
304  // Radially invariant noise
305  QLabel* lb_rinoise = us_label( tr( "Radially Invar. Noise (% Conc.):" ) );
306  main->addWidget( lb_rinoise, row, 4, 1, 3 );
307 
308  cnt_rinoise = us_counter( 3, 0, 10, simparams.rinoise );
309  cnt_rinoise->setStep ( 0.01 );
310  cnt_rinoise->setIncSteps( QwtCounter::Button1, 1 );
311  cnt_rinoise->setIncSteps( QwtCounter::Button2, 10 );
312  cnt_rinoise->setIncSteps( QwtCounter::Button3, 100 );
313 
314  main->addWidget( cnt_rinoise, row++, 7, 1, 1 );
315  connect( cnt_rinoise, SIGNAL( valueChanged ( double ) ),
316  SLOT ( update_rinoise( double ) ) );
317 
318  // Temperature
319  QLabel* lb_temperature = us_label( tr( "Temperature (%1):" )
320  .arg( DEGC ) );
321  main->addWidget( lb_temperature, row, 4, 1, 3 );
322 
323  cnt_temperature = us_counter( 3, 10.0, 40.0, NORMAL_TEMP );
324  cnt_temperature->setStep ( 0.1 );
325  cnt_temperature->setIncSteps( QwtCounter::Button1, 1 );
326  cnt_temperature->setIncSteps( QwtCounter::Button2, 10 );
327  cnt_temperature->setIncSteps( QwtCounter::Button3, 100 );
328  cnt_temperature->setValue ( simparams.temperature );
329  main->addWidget( cnt_temperature, row++, 7, 1, 1 );
330  connect( cnt_temperature, SIGNAL( valueChanged( double ) ),
331  SLOT ( update_temp( double ) ) );
332 
333  // Mesh combo box
334  cmb_mesh = us_comboBox();
335  cmb_mesh->setMaxVisibleItems( 5 );
336  cmb_mesh->addItem( "Adaptive Space Time FE Mesh (ASTFEM)" );
337  cmb_mesh->addItem( "Claverie Fixed Mesh" );
338  cmb_mesh->addItem( "Moving Hat Mesh" );
339  cmb_mesh->addItem( "Specified file (mesh.dat)" );
340  cmb_mesh->addItem( "AST Finite Volume Method (ASTFVM)" );
341  cmb_mesh->setCurrentIndex( (int)simparams.meshType );
342 
343  main->addWidget( cmb_mesh, row++, 4, 1, 4 );
344 
345  connect( cmb_mesh, SIGNAL( activated ( int ) ),
346  SLOT ( update_mesh( int ) ) );
347 
348  // Moving Grid Combo Box
350  cmb_moving->setMaxVisibleItems( 5 );
351  cmb_moving->addItem( "Constant Time Grid (Claverie/Acceleration)" );
352  cmb_moving->addItem( "Moving Time Grid (ASTFEM/Moving Hat)" );
353  cmb_moving->setCurrentIndex( (int)simparams.gridType );
354  connect( cmb_moving, SIGNAL( activated ( int ) ),
355  SLOT ( update_moving( int ) ) );
356 
357  main->addWidget( cmb_moving, row++, 4, 1, 4 );
358 
359  // Button bar
360  QBoxLayout* buttons = new QHBoxLayout();
361 
362  QPushButton* pb_load = us_pushbutton( tr( "Load Profile" ) );
363  connect( pb_load, SIGNAL( clicked() ), SLOT( load() ) );
364  buttons ->addWidget( pb_load );
365 
366  QPushButton* pb_save = us_pushbutton( tr( "Save Profile" ) );
367  connect( pb_save, SIGNAL( clicked() ), SLOT( save() ) );
368  buttons ->addWidget( pb_save );
369 
370  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
371  connect( pb_help, SIGNAL( clicked() ), SLOT( help() ) );
372  buttons ->addWidget( pb_help );
373 
374  QPushButton* pb_cancel = us_pushbutton( tr( "Cancel" ) );
375  connect( pb_cancel, SIGNAL( clicked() ), SLOT( revert() ) );
376  buttons ->addWidget( pb_cancel );
377 
378  QPushButton* pb_accept = us_pushbutton( tr( "Accept" ) );
379  connect( pb_accept, SIGNAL( clicked() ), SLOT( accepted() ) );
380  buttons ->addWidget( pb_accept );
381 
382  main->addLayout( buttons, row++, 0, 1, 8 );
383 }
384 
386 {
387  emit complete();
388  accept();
389 }
390 
392 {
393  /*
394  US_SimulationParameters::SpeedProfile sp;
395  simparams_backup.speed_step.clear();
396 
397  for ( int i = 0; i < simparams.speed_step.size(); i ++ )
398  {
399  simparams_backup.speed_step .push_back( sp );
400 
401  US_SimulationParameters::SpeedProfile* ss = &simparams .speed_step[ i ];
402  US_SimulationParameters::SpeedProfile* ssbu = &simparams_backup.speed_step[ i ];
403 
404  ssbu->duration_hours = ss->duration_hours;
405  ssbu->duration_minutes = ss->duration_minutes;
406  ssbu->delay_hours = ss->delay_hours;
407  ssbu->delay_minutes = ss->delay_minutes;
408  ssbu->rotorspeed = ss->rotorspeed;
409  ssbu->scans = ss->scans;
410  ssbu->acceleration = ss->acceleration;
411  ssbu->acceleration_flag = ss->acceleration_flag;
412  }
413 
414  simparams_backup.simpoints = simparams.simpoints;
415  simparams_backup.radial_resolution = simparams.radial_resolution;
416  simparams_backup.meniscus = simparams.meniscus;
417  simparams_backup.bottom = simparams.bottom;
418  simparams_backup.rnoise = simparams.rnoise;
419  simparams_backup.tinoise = simparams.tinoise;
420  simparams_backup.rinoise = simparams.rinoise;
421  */
422 }
423 
425 {
427  simparams.speed_step.clear();
428 
429  for ( int i = 0; i < simparams_backup.speed_step.size(); i ++ )
430  {
431  simparams.speed_step .push_back( sp );
432 
435 
436  ss->duration_hours = ssbu->duration_hours;
438  ss->delay_hours = ssbu->delay_hours;
439  ss->delay_minutes = ssbu->delay_minutes;
440  ss->rotorspeed = ssbu->rotorspeed;
441  ss->scans = ssbu->scans;
442  ss->acceleration = ssbu->acceleration;
444  }
445 
454 
455  reject();
456 }
457 
459 {
460  int old_size = simparams.speed_step.size();
462 
463  for ( int i = old_size; i < (int) value; i++ )
464  {
465  simparams.speed_step .push_back( sp );
466 
467  // Only initialize the new elements, leave the previously assigned
468  // elements alone. New elements simply get copies of the last old
469  // element if old_size > new_size then we won't go through this loop and
470  // simply truncate the list
471 
474 
475  ss->duration_hours = ss_old->duration_hours;
476  ss->duration_minutes = ss_old->duration_minutes;
477  ss->delay_hours = ss_old->delay_hours;
478  ss->delay_minutes = ss_old->delay_minutes;
479  ss->rotorspeed = ss_old->rotorspeed;
480  ss->scans = ss_old->scans;
481  ss->acceleration = ss_old->acceleration;
482  ss->acceleration_flag = ss_old->acceleration_flag;
483  }
484 
485  cnt_selected_speed->setMaxValue( simparams.speed_step.size() );
486  update_combobox();
487 }
488 
490 {
491  cmb_speeds->disconnect();
492  cmb_speeds->clear();
493 
494  for ( int i = 0; i < simparams.speed_step.size(); i++ )
495  {
497 
498  cmb_speeds->addItem( "Speed Profile " +
499  QString::number( i + 1 ) + ": " +
500  QString::number( spi->duration_hours ) + " hr " +
501  QString::number( spi->duration_minutes ) + " min, " +
502  QString::number( spi->rotorspeed ) + " rpm" );
503  }
504 
505  connect( cmb_speeds, SIGNAL( activated ( int ) ),
506  SLOT ( select_speed_profile( int ) ) );
507 
508  cmb_speeds->setCurrentIndex( current_speed_step );
509 }
510 
512 {
513  select_speed_profile( (int) profile - 1 );
514 }
515 
517 {
518  current_speed_step = index;
519  cnt_speeds->setValue( index + 1 );
520 
521  if ( cb_acceleration_flag->isChecked() )
522  {
523  cnt_acceleration->setEnabled( true );
524 
525  // If there is acceleration we need to set the scan delay
526  // minimum to the time it takes to accelerate:
527 
528  check_delay();
529  }
530  else
531  {
532  cnt_acceleration->setEnabled( false );
533  }
534 
535  cmb_speeds->setCurrentIndex( index );
536 
538 
539  cnt_duration_hours->setValue( sp->duration_hours );
540  cnt_duration_mins ->setValue( sp->duration_minutes );
541  cnt_delay_hours ->setValue( sp->delay_hours );
542  cnt_delay_mins ->setValue( sp->delay_minutes );
543  cnt_rotorspeed ->setValue( sp->rotorspeed );
544  cnt_scans ->setValue( sp->scans );
545  cnt_acceleration ->setValue( sp->acceleration );
546 
547  cb_acceleration_flag->setChecked( sp->acceleration_flag );
548 }
549 
551 {
552  QVector< int > hours;
553  QVector< double > minutes;
554  QVector< int > speed;
555 
556  speed.clear();
557  speed .push_back( 0 );
558 
559  int steps = simparams.speed_step.size();
560 
561  for ( int i = 0; i < steps; i++ )
562  {
563  hours .push_back( 0 );
564  minutes.push_back( 0.0 );
565 
567  speed .push_back( ss->rotorspeed );
568 
569  int lower_limit = 1 +
570  ( abs( (speed[ i + 1 ] - speed[ i ] ) ) + 1 ) / ss->acceleration;
571 
572  hours [ i ] = lower_limit / 3600;
573  int secs = lower_limit - hours[ i ] * 3600;
574  int mins = qRound( (double)secs / 60.0 );
575  minutes[ i ] = (double)mins;
576  }
577 
578  //cnt_delay_mins ->setMinValue( minutes[ current_speed_step ] );
579  cnt_delay_hours->setMinValue( hours [ current_speed_step ] );
580 
582 
583  if ( sp->delay_hours == hours[ current_speed_step] &&
584  sp->delay_minutes < minutes[ current_speed_step] )
585  {
586  sp->delay_minutes = minutes[ current_speed_step ];
587  cnt_delay_mins->setValue( minutes[ current_speed_step ] );
588  }
589 
590  if ( sp->delay_hours < (int)hours[ current_speed_step ] )
591  {
592  sp->delay_hours = hours[ current_speed_step ];
593  cnt_delay_hours->setValue( hours[ current_speed_step ] );
594  }
595 
596  if ( sp->duration_hours == 0 && sp->duration_minutes < sp->delay_minutes + 1 )
597  {
598  sp->duration_minutes = (int) sp->delay_minutes + 1;
599 
600  cnt_duration_mins->setValue( sp->duration_minutes);
601 
602  cnt_duration_mins->setMinValue( sp->delay_minutes + 1 );
603  }
604  else if ( sp->duration_hours > 0)
605  {
606  cnt_duration_mins->setMinValue( 0 );
607  }
608  else if ( sp->duration_hours == 0 &&
609  sp->duration_minutes > sp->delay_minutes + 1 )
610  {
611  cnt_duration_mins->disconnect();
612  cnt_duration_mins->setMinValue( sp->delay_minutes + 1 );
613  connect( cnt_duration_mins, SIGNAL( valueChanged ( double ) ),
614  SLOT ( update_duration_mins( double ) ) );
615  }
616 }
617 
619 {
621  sp->duration_hours = (int)hours;
622  check_delay();
623  update_combobox();
624 }
625 
627 {
629  sp->duration_minutes = minutes;
630  check_delay();
631  update_combobox();
632 }
633 
635 {
637  sp->delay_hours = (int) hours;
638 }
639 
641 {
643  sp->delay_minutes = (int) minutes;
644  check_delay();
645 }
646 
648 {
650  sp->rotorspeed = (long) speed;
651  update_combobox();
652 
653  // If there is acceleration we need to set the scan delay
654  // minimum to the time it takes to accelerate:
655  if ( cb_acceleration_flag->isChecked() ) check_delay();
656 }
657 
659 {
661 
662  bool state = cb_acceleration_flag->isChecked();
663 
664  sp->acceleration_flag = state;
665  cnt_acceleration->setEnabled( state );
666 
667  // If there is acceleration we need to set the scan delay
668  // minimum to the time it takes to accelerate:
669  if ( state ) check_delay();
670 }
671 
673 {
675  sp->acceleration = (int)accel;
676 
677  // If there is acceleration we need to set the scan delay
678  // minimum to the time it takes to accelerate:
679  if ( cb_acceleration_flag->isChecked() ) check_delay();
680 }
681 
683 {
685  sp->scans = (int)scans;
686 }
687 
689 {
690  QString fn = QFileDialog::getSaveFileName( this,
691  tr( "Save Simulation Parameters in:" ),
693  tr( "SimParams files (sp_*.xml);;"
694  "All XML files (*.xml);;"
695  "All files (*)" ) );
696 
697  if ( fn.isEmpty() ) return;
698 
699  fn = fn.replace( "\\", "/" );
700  int jj = fn.lastIndexOf( "/" ) + 1;
701  QString fdir = fn.left( jj );
702  QString fnam = fn.mid( jj );
703 
704  // Make sure file name is in "sp_<name>.xml" form
705 
706  if ( fn.endsWith( "." ) )
707  { // ending with '.' signals no ".xml" to be added
708  fn = fn.left( fn.length() - 1 );
709  fnam = fnam.left( fnam.length() - 1 );
710  }
711 
712  else if ( !fn.endsWith( ".xml" ) )
713  { // if no .xml extension, add one
714  fn = fn + ".xml";
715  fnam = fnam + ".xml";
716  }
717 
718  if ( fnam.startsWith( "." ) )
719  { // starting with '.' signals no "sp_" prefix
720  fn = fdir + fnam.mid( 1 );
721  }
722 
723  else if ( !fnam.startsWith( "sp_" ) )
724  { // if no sp_ prefix, add one
725  fn = fdir + "sp_" + fnam;
726  }
727 
728  QFile f( fn );
729 
730  if ( f.exists() )
731  {
732  if( QMessageBox::No == QMessageBox::warning( this,
733  tr( "Warning" ),
734  tr( "Attention:\n"
735  "This file exists already!\n\n"
736  "Do you want to overwrite it?" ),
737  QMessageBox::Yes, QMessageBox::No ) )
738  {
739  return;
740  }
741  }
742 
743  if ( simparams.save_simparms( fn ) == 0 )
744  {
745  QMessageBox::information( this,
746  tr( "UltraScan Information" ),
747  tr( "Please note:\n\n"
748  "The Simulation Profile was successfully saved to:\n\n" ) +
749  fn );
750  }
751  else
752  {
753  QMessageBox::information( this,
754  tr( "UltraScan Error" ),
755  tr( "Please note:\n\n"
756  "The Simulation Profile could not be saved to:\n\n" ) +
757  fn );
758  }
759 }
760 
762 {
763  QString fn = QFileDialog::getOpenFileName( this,
764  tr( "Load Simulation Parameters from:" ),
766  tr( "SimParams files (sp_*.xml);;"
767  "All XML files (*.xml);;"
768  "All files (*)" ) );
769 
770  if ( fn.isEmpty() ) return;
771 
772  if ( simparams.load_simparms( fn ) == 0 )
773  {
774  current_speed_step = 0;
775  int steps = simparams.speed_step.size();
776  disconnect_all();
777 
778  cnt_speeds->setValue( steps );
779  cmb_speeds->clear();
780 
781  for ( int i = 0; i < steps; i++ )
782  {
784 
785  cmb_speeds->addItem( "Speed Profile " +
786  QString::number( i + 1 ) + ": " +
787  QString::number( spi->duration_hours ) + " hr " +
788  QString::number( spi->duration_minutes ) + " min, " +
789  QString::number( spi->rotorspeed ) + " rpm" );
790  }
791 
792  connect( cmb_speeds, SIGNAL( activated ( int ) ),
793  SLOT ( select_speed_profile( int ) ) );
794 
795  // Initialize all counters with the first speed profile:
796 
798 
799  cnt_duration_hours ->setValue( 5.0 );
800  cnt_duration_hours ->setValue( 5 );
801  cnt_duration_hours ->setValue( sp->duration_hours );
802  cnt_duration_mins ->setValue( sp->duration_minutes );
803  cnt_delay_hours ->setValue( sp->delay_hours );
804  cnt_delay_mins ->setValue( sp->delay_minutes );
805  cnt_rotorspeed ->setValue( sp->rotorspeed );
806  cnt_acceleration ->setValue( sp->acceleration );
807  cnt_scans ->setValue( sp->scans );
808 
809  cb_acceleration_flag->setChecked( sp->acceleration_flag );
810  cnt_acceleration ->setEnabled( sp->acceleration_flag );
811 
812  cnt_lamella ->setValue( simparams.band_volume * 1000.0 );
813  cnt_simpoints ->setValue( simparams.simpoints );
815  cnt_meniscus ->setValue( simparams.meniscus );
816  cnt_bottom ->setValue( simparams.bottom );
817  cnt_rnoise ->setValue( simparams.rnoise );
818  cnt_tinoise ->setValue( simparams.tinoise );
819  cnt_rinoise ->setValue( simparams.rinoise );
820  cnt_temperature ->setValue( simparams.temperature );
821 
822  cmb_mesh ->setCurrentIndex( (int)simparams.meshType );
823  cmb_moving ->setCurrentIndex( (int)simparams.gridType );
824 
825  rb_band ->setChecked( simparams.band_forming );
826  rb_standard->setChecked( ! simparams.band_forming );
827  cnt_lamella->setEnabled( simparams.band_forming );
828 
829  reconnect_all();
830 
831  QMessageBox::information( this,
832  tr( "UltraScan Information" ),
833  tr( "Please note:\n\n"
834  "The Simulation Profile was successfully loaded from:\n\n" ) +
835  fn );
836  }
837 
838  else
839  {
840  QMessageBox::information( this,
841  tr( "UltraScan Error" ),
842  tr( "Please note:\n\n"
843  "Could not read the Simulation Profile:\n\n" ) +
844  fn );
845  }
846 }
847 
849 {
851 
852  // By default, the simpoints can be set by the user
853  cnt_simpoints->setEnabled( true );
854 
855  if ( mesh == 3 )
856  {
857  QMessageBox::information( this,
858  tr( "UltraScan Information" ),
859  tr( "Please note:\n\n"
860  "The radial mesh file should have\n"
861  "the following format:\n\n"
862  "radius_value1\n"
863  "radius_value2\n"
864  "radius_value3\n"
865  "etc...\n\n"
866  "Radius values smaller than the meniscus or\n"
867  "larger than the bottom of the cell will be\n"
868  "excluded from the concentration vector." ) );
869 
870  QFile meshfile( US_Settings::appBaseDir() + "/mesh.dat");
871 
872  if ( meshfile.open( QIODevice::ReadOnly | QIODevice::Text ) )
873  {
874  QTextStream ts( &meshfile );
875  simparams.mesh_radius.clear();
876 
877  bool first = true;
878 
879  while ( ! ts.atEnd() )
880  {
881  double value;
882  ts >> value;
883 
884  // Ignore values outside the meniscus/bottom range
885  if ( value >= simparams.meniscus && value <= simparams.bottom )
886  {
887  if ( first )
888  {
889  if ( value > simparams.meniscus )
890  {
891  simparams.mesh_radius .push_back( simparams.meniscus );
892  }
893 
894  first = false;
895  }
896 
897  simparams.mesh_radius .push_back( value );
898  }
899  }
900 
901  meshfile.close();
902 
903  int mesh_size = simparams.mesh_radius.size();
904 
905  if ( simparams.mesh_radius[ mesh_size - 1 ] < simparams.bottom )
906  {
907  simparams.mesh_radius .push_back( simparams.bottom );
908  }
909 
910 
912  cnt_simpoints->setValue( (double) simparams.simpoints );
913 
914  // Can't change the simulation points after defining a mesh
915  cnt_simpoints->setEnabled( false );
916  }
917  else
918  {
919  //simparams.mesh = 0; // Set to default mesh
920  cmb_mesh->setCurrentIndex( 0 );
921 
922  // By default, the simpoints can be set by the user
923  cnt_simpoints->setEnabled( true );
924 
925  QMessageBox::warning( this,
926  tr( "UltraScan Warning" ),
927  tr( "Please note:\n\n"
928  "UltraScan could not open the mesh file!\n"
929  "The file:\n\n" ) +
930  US_Settings::appBaseDir() + tr( "/mesh.dat\n\n"
931  "could not be opened." ) );
932  }
933  }
934 }
935 
937 {
938  cnt_speeds ->disconnect();
939  cmb_speeds ->disconnect();
940  cnt_duration_hours ->disconnect();
941  cnt_duration_mins ->disconnect();
942  cnt_delay_hours ->disconnect();
943  cnt_delay_mins ->disconnect();
944  cnt_rotorspeed ->disconnect();
945  cb_acceleration_flag->disconnect();
946  cnt_acceleration ->disconnect();
947  cnt_scans ->disconnect();
948  cnt_selected_speed ->disconnect();
949  cnt_lamella ->disconnect();
950  cnt_meniscus ->disconnect();
951  cnt_bottom ->disconnect();
952  cnt_simpoints ->disconnect();
953  cnt_radial_res ->disconnect();
954  cnt_rnoise ->disconnect();
955  cnt_tinoise ->disconnect();
956  cnt_rinoise ->disconnect();
957  cmb_mesh ->disconnect();
958  cmb_moving ->disconnect();
959 }
960 
962 {
963  connect( cnt_speeds, SIGNAL( valueChanged ( double ) ),
964  SLOT ( update_speeds( double ) ) );
965  connect( cmb_speeds, SIGNAL( activated ( int ) ),
966  SLOT ( select_speed_profile( int ) ) );
967  connect( cnt_duration_hours, SIGNAL( valueChanged ( double ) ),
968  SLOT ( update_duration_hours( double ) ) );
969  connect( cnt_duration_mins, SIGNAL( valueChanged ( double ) ),
970  SLOT ( update_duration_mins( double ) ) );
971  connect( cnt_delay_hours, SIGNAL( valueChanged ( double ) ),
972  SLOT ( update_delay_hours( double ) ) );
973  connect( cnt_delay_mins, SIGNAL( valueChanged ( double ) ),
974  SLOT ( update_delay_mins( double ) ) );
975  connect( cnt_rotorspeed, SIGNAL( valueChanged ( double ) ),
976  SLOT ( update_rotorspeed( double ) ) );
977  connect( cb_acceleration_flag, SIGNAL( clicked () ),
978  SLOT ( acceleration_flag() ) );
979  connect( cnt_acceleration, SIGNAL( valueChanged ( double ) ),
980  SLOT ( update_acceleration( double ) ) );
981  connect( cnt_scans, SIGNAL( valueChanged( double ) ),
982  SLOT ( update_scans( double ) ) );
983  connect( cnt_selected_speed, SIGNAL( valueChanged ( double ) ),
984  SLOT ( update_speed_profile( double ) ) );
985  connect( cnt_lamella, SIGNAL( valueChanged ( double ) ),
986  SLOT ( update_lamella( double ) ) );
987  connect( cnt_meniscus, SIGNAL( valueChanged ( double ) ),
988  SLOT ( update_meniscus( double ) ) );
989  connect( cnt_bottom, SIGNAL( valueChanged ( double ) ),
990  SLOT ( update_bottom( double ) ) );
991  connect( cnt_simpoints, SIGNAL( valueChanged ( double ) ),
992  SLOT ( update_simpoints( double ) ) );
993  connect( cnt_radial_res, SIGNAL( valueChanged ( double ) ),
994  SLOT ( update_radial_res( double ) ) );
995  connect( cnt_rnoise, SIGNAL( valueChanged ( double ) ),
996  SLOT ( update_rnoise( double ) ) );
997  connect( cnt_tinoise, SIGNAL( valueChanged ( double ) ),
998  SLOT ( update_tinoise( double ) ) );
999  connect( cnt_rinoise, SIGNAL( valueChanged ( double ) ),
1000  SLOT ( update_rinoise( double ) ) );
1001  connect( cmb_mesh, SIGNAL( activated ( int ) ),
1002  SLOT ( update_mesh( int ) ) );
1003  connect( cmb_moving, SIGNAL( activated ( int ) ),
1004  SLOT ( update_moving( int ) ) );
1005 }
1006