UltraScan III
us_ddist_combine.cpp
Go to the documentation of this file.
1 
3 #include <QApplication>
4 
5 #include "us_ddist_combine.h"
6 #include "us_select_rundd.h"
7 #include "us_license_t.h"
8 #include "us_license.h"
9 #include "us_settings.h"
10 #include "us_gui_settings.h"
11 #include "us_gui_util.h"
12 #include "us_matrix.h"
13 #include "us_constants.h"
14 #include "us_passwd.h"
15 #include "us_report.h"
16 #include "us_util.h"
17 #include "us_model.h"
18 #include "us_math2.h"
19 #include "qwt_legend.h"
20 
21 // Main program
22 int main( int argc, char* argv[] )
23 {
24  QApplication application( argc, argv );
25 
26  #include "main1.inc"
27 
28  // License is OK. Start up.
29 
31  w.show();
32  return application.exec();
33 }
34 
35 const double epsilon = 0.0005; // Equivalence magnitude ratio radius
36 
37 // US_DDistr_Combine class constructor
39 {
40  // set up the GUI
41  setWindowTitle( tr( "Combined Discrete Distributions:" ) );
42  setPalette( US_GuiSettings::frameColor() );
44  xtype = 0;
45 
46  QBoxLayout* mainLayout = new QHBoxLayout( this );
47  QGridLayout* leftLayout = new QGridLayout;
48  QVBoxLayout* rightLayout = new QVBoxLayout;
49  mainLayout ->setSpacing ( 2 );
50  mainLayout ->setContentsMargins( 2, 2, 2, 2 );
51  leftLayout ->setSpacing ( 0 );
52  leftLayout ->setContentsMargins( 0, 1, 0, 1 );
53  rightLayout->setSpacing ( 0 );
54  rightLayout->setContentsMargins( 0, 1, 0, 1 );
55 
58  QPushButton* pb_loadda = us_pushbutton( tr( "Select Run ID(s)" ) );
59  pb_saveda = us_pushbutton( tr( "Save Data" ) );
60  pb_resetd = us_pushbutton( tr( "Reset Data" ) );
61  pb_resetp = us_pushbutton( tr( "Reset Plot" ) );
62  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
63  QPushButton* pb_close = us_pushbutton( tr( "Close" ) );
64 
65  pb_saveda->setEnabled( false );
66  pb_resetd->setEnabled( false );
67  pb_resetp->setEnabled( false );
68 
69  QLabel* lb_distrtype = us_banner( tr( "Select Distribution Type(s):" ) );
70  QLabel* lb_plottype = us_banner( tr( "Plot Type and Control:" ) );
71  QLabel* lb_runinfo = us_banner( tr( "Information for this Run:" ) );
72  QLabel* lb_runid = us_label ( tr( "Current Run ID:" ) );
73  QLabel* lb_svproj = us_label ( tr( "Save Plot under Project:" ) );
74  QLabel* lb_runids = us_banner( tr( "Run IDs:" ) );
75  QLabel* lb_models = us_banner( tr( "Distributions:" ) );
76 
77  QLayout* lo_2dsa = us_checkbox( tr( "2DSA" ), ck_2dsa, true );
78  QLayout* lo_2dsamc = us_checkbox( tr( "2DSA-MC" ), ck_2dsamc, false );
79  QLayout* lo_2dsamw = us_checkbox( tr( "2DSA-MW" ), ck_2dsamw, false );
80  QLayout* lo_2dsamcmw = us_checkbox( tr( "2DSA-MC-MW" ), ck_2dsamcmw, false );
81  QLayout* lo_2dsagl = us_checkbox( tr( "2DSA-GL" ), ck_2dsagl, false );
82  QLayout* lo_2dsaglmc = us_checkbox( tr( "2DSA-GL-MC" ), ck_2dsaglmc, false );
83  QLayout* lo_2dsacg = us_checkbox( tr( "2DSA-CG" ), ck_2dsacg, false );
84  QLayout* lo_2dsacgmc = us_checkbox( tr( "2DSA-CG-MC" ), ck_2dsacgmc, false );
85  QLayout* lo_2dsafm = us_checkbox( tr( "2DSA-FM" ), ck_2dsafm, false );
86  QLayout* lo_ga = us_checkbox( tr( "GA" ), ck_ga, false );
87  QLayout* lo_gamc = us_checkbox( tr( "GA-MC" ), ck_gamc, false );
88  QLayout* lo_gamw = us_checkbox( tr( "GA-MW" ), ck_gamw, false );
89  QLayout* lo_gamcmw = us_checkbox( tr( "GA-MC-MW" ), ck_gamcmw, false );
90  QLayout* lo_gagl = us_checkbox( tr( "GA-GL" ), ck_gagl, false );
91  QLayout* lo_gaglmc = us_checkbox( tr( "GA-GL-MC" ), ck_gaglmc, false );
92  QLayout* lo_pcsais = us_checkbox( tr( "PCSA-IS" ), ck_pcsais, false );
93  QLayout* lo_pcsasl = us_checkbox( tr( "PCSA-SL" ), ck_pcsasl, false );
94  QLayout* lo_pcsads = us_checkbox( tr( "PCSA-DS" ), ck_pcsads, false );
95  QLayout* lo_pcsahl = us_checkbox( tr( "PCSA-HL" ), ck_pcsahl, false );
96  QLayout* lo_pcsaismc = us_checkbox( tr( "PCSA-IS-MC" ), ck_pcsaismc, false );
97  QLayout* lo_pcsaslmc = us_checkbox( tr( "PCSA-SL-MC" ), ck_pcsaslmc, false );
98  QLayout* lo_pcsadsmc = us_checkbox( tr( "PCSA-DS-MC" ), ck_pcsadsmc, false );
99  QLayout* lo_pcsahlmc = us_checkbox( tr( "PCSA-HL-MC" ), ck_pcsahlmc, false );
100  QLayout* lo_pcsaistr = us_checkbox( tr( "PCSA-IS-TR" ), ck_pcsaistr, false );
101  QLayout* lo_pcsasltr = us_checkbox( tr( "PCSA-SL-TR" ), ck_pcsasltr, false );
102  QLayout* lo_pcsadstr = us_checkbox( tr( "PCSA-DS-TR" ), ck_pcsadstr, false );
103  QLayout* lo_pcsahltr = us_checkbox( tr( "PCSA-HL-TR" ), ck_pcsahltr, false );
104  QLayout* lo_pcsa2o = us_checkbox( tr( "PCSA-2O" ), ck_pcsa2o, false );
105  QLayout* lo_pcsa2omc = us_checkbox( tr( "PCSA-2O-MC" ), ck_pcsa2omc, false );
106  QLayout* lo_pcsa2otr = us_checkbox( tr( "PCSA-2O-TR" ), ck_pcsa2otr, false );
107  QLayout* lo_dmga = us_checkbox( tr( "DMGA" ), ck_dmga, false );
108  QLayout* lo_dmgamc = us_checkbox( tr( "DMGA-MC" ), ck_dmgamc, false );
109  QLayout* lo_dmgara = us_checkbox( tr( "DMGA-RA" ), ck_dmgara, false );
110  QLayout* lo_dmgaramc = us_checkbox( tr( "DMGA-RA-MC" ), ck_dmgaramc, false );
111  QLayout* lo_dmgagl = us_checkbox( tr( "DMGA-GL" ), ck_dmgagl, false );
112  QLayout* lo_dmgaglmc = us_checkbox( tr( "DMGA-GL-MC" ), ck_dmgaglmc, false );
113  QLayout* lo_dtall = us_checkbox( tr( "All" ), ck_dtall, false );
115  QFont::Bold );
116  ck_2dsa ->setFont( cfont );
117  ck_2dsamc ->setFont( cfont );
118  ck_2dsamw ->setFont( cfont );
119  ck_2dsamcmw->setFont( cfont );
120  ck_2dsagl ->setFont( cfont );
121  ck_2dsaglmc->setFont( cfont );
122  ck_2dsacg ->setFont( cfont );
123  ck_2dsacgmc->setFont( cfont );
124  ck_2dsafm ->setFont( cfont );
125  ck_ga ->setFont( cfont );
126  ck_gamc ->setFont( cfont );
127  ck_gamw ->setFont( cfont );
128  ck_gamcmw ->setFont( cfont );
129  ck_gagl ->setFont( cfont );
130  ck_gaglmc ->setFont( cfont );
131  ck_pcsais ->setFont( cfont );
132  ck_pcsasl ->setFont( cfont );
133  ck_pcsads ->setFont( cfont );
134  ck_pcsahl ->setFont( cfont );
135  ck_pcsaismc->setFont( cfont );
136  ck_pcsaslmc->setFont( cfont );
137  ck_pcsadsmc->setFont( cfont );
138  ck_pcsahlmc->setFont( cfont );
139  ck_pcsaistr->setFont( cfont );
140  ck_pcsasltr->setFont( cfont );
141  ck_pcsadstr->setFont( cfont );
142  ck_pcsahltr->setFont( cfont );
143  ck_dmga ->setFont( cfont );
144  ck_dmgamc ->setFont( cfont );
145  ck_dmgara ->setFont( cfont );
146  ck_dmgaramc->setFont( cfont );
147  ck_dmgagl ->setFont( cfont );
148  ck_dmgaglmc->setFont( cfont );
149  ck_pcsa2o ->setFont( cfont );
150  ck_pcsa2omc->setFont( cfont );
151  ck_pcsa2otr->setFont( cfont );
152  ck_dtall ->setFont( cfont );
153  //ck_2dsagl ->setVisible( false );
154  //ck_2dsaglmc->setVisible( false );
155  //ck_2dsamw ->setVisible( false );
156  //ck_2dsamcmw->setVisible( false );
157 
158  QButtonGroup* sel_plt = new QButtonGroup( this );
159  QGridLayout* lo_pltsw = us_radiobutton( tr( "s20,W" ), rb_pltsw, true );
160  QGridLayout* lo_pltMW = us_radiobutton( tr( "MW" ), rb_pltMW, false );
161  QGridLayout* lo_pltDw = us_radiobutton( tr( "D20,W" ), rb_pltDw, false );
162  QGridLayout* lo_pltff0 = us_radiobutton( tr( "f/f0" ), rb_pltff0, false );
163  QGridLayout* lo_pltvb = us_radiobutton( tr( "vbar" ), rb_pltvb, false );
164  QGridLayout* lo_pltMWl = us_radiobutton( tr( "MWlog" ), rb_pltMWl, false );
165  sel_plt->addButton( rb_pltsw, 0 );
166  sel_plt->addButton( rb_pltMW, 1 );
167  sel_plt->addButton( rb_pltDw, 2 );
168  sel_plt->addButton( rb_pltff0, 3 );
169  sel_plt->addButton( rb_pltvb, 4 );
170  sel_plt->addButton( rb_pltMWl, 5 );
171  QLayout* lo_mdltype = us_checkbox(
172  tr( "Use model descriptions for list and legend" ),
173  ck_mdltype, false );
174 
176  QFontMetrics fmet( sfont );
177  int fwid = fmet.maxWidth();
178  lb_sigma = us_label( tr( "Envelope Gaussian Sigma:" ) );
179  ct_sigma = us_counter( 3, 0, 5, 1 );
180  ct_sigma->setStep( 0.001 );
181  ct_sigma->setFont( sfont );
182  ct_sigma->setValue( 0.05 );
183  int rhgt = ct_sigma ->height();
184  int csizw = fwid * 5;
185  ct_sigma->setMinimumWidth( fwid );
186  ct_sigma->resize( rhgt, csizw );
187  lb_plxmin = us_label( tr( "Plot X Minimum:" ) );
188  lb_plxmax = us_label( tr( "Plot X Maximum:" ) );
189  le_plxmin = us_lineedit( "0" );
190  le_plxmax = us_lineedit( "0" );
191 
192  le_runid = us_lineedit( "(current run ID)", -1, true );
197  us_setReadOnly( te_status, true );
198  te_status->setTextColor( Qt::blue );
199 
200  int row = 0;
201  leftLayout->addLayout( dkdb_cntrls, row++, 0, 1, 8 );
202  leftLayout->addWidget( pb_loadda, row, 0, 1, 4 );
203  leftLayout->addWidget( pb_saveda, row++, 4, 1, 4 );
204  leftLayout->addWidget( pb_resetd, row, 0, 1, 2 );
205  leftLayout->addWidget( pb_resetp, row, 2, 1, 2 );
206  leftLayout->addWidget( pb_help, row, 4, 1, 2 );
207  leftLayout->addWidget( pb_close, row++, 6, 1, 2 );
208  leftLayout->addWidget( lb_distrtype, row++, 0, 1, 8 );
209  leftLayout->addLayout( lo_2dsa, row, 0, 1, 2 );
210  leftLayout->addLayout( lo_2dsafm, row, 2, 1, 2 );
211  leftLayout->addLayout( lo_2dsamc, row, 4, 1, 2 );
212  leftLayout->addLayout( lo_2dsacg, row++, 6, 1, 2 );
213  leftLayout->addLayout( lo_ga, row, 0, 1, 2 );
214  leftLayout->addLayout( lo_gamc, row, 2, 1, 4 );
215  leftLayout->addLayout( lo_dtall, row++, 6, 1, 2 );
216  leftLayout->addLayout( lo_pcsais, row, 0, 1, 2 );
217  leftLayout->addLayout( lo_pcsasl, row, 2, 1, 2 );
218  leftLayout->addLayout( lo_pcsads, row, 4, 1, 2 );
219  leftLayout->addLayout( lo_pcsahl, row++, 6, 1, 2 );
220  leftLayout->addLayout( lo_pcsaismc, row, 0, 1, 2 );
221  leftLayout->addLayout( lo_pcsaslmc, row, 2, 1, 2 );
222  leftLayout->addLayout( lo_pcsadsmc, row, 4, 1, 2 );
223  leftLayout->addLayout( lo_pcsahlmc, row++, 6, 1, 2 );
224  leftLayout->addLayout( lo_dmga, row, 0, 1, 2 );
225  leftLayout->addLayout( lo_dmgamc, row, 2, 1, 2 );
226  leftLayout->addLayout( lo_dmgara, row, 4, 1, 2 );
227  leftLayout->addLayout( lo_dmgaramc, row++, 6, 1, 2 );
228  leftLayout->addLayout( lo_2dsacgmc, row, 0, 1, 2 );
229  leftLayout->addLayout( lo_2dsamw, row, 2, 1, 2 );
230  leftLayout->addLayout( lo_2dsamcmw, row++, 4, 1, 4 );
231  leftLayout->addLayout( lo_2dsagl, row, 0, 1, 2 );
232  leftLayout->addLayout( lo_2dsaglmc, row++, 2, 1, 6 );
233  leftLayout->addLayout( lo_gamw, row, 0, 1, 2 );
234  leftLayout->addLayout( lo_gamcmw, row, 2, 1, 2 );
235  leftLayout->addLayout( lo_gagl, row, 4, 1, 2 );
236  leftLayout->addLayout( lo_gaglmc, row++, 6, 1, 2 );
237  leftLayout->addLayout( lo_pcsaistr, row, 0, 1, 2 );
238  leftLayout->addLayout( lo_pcsasltr, row, 2, 1, 2 );
239  leftLayout->addLayout( lo_pcsadstr, row, 4, 1, 2 );
240  leftLayout->addLayout( lo_pcsahltr, row++, 6, 1, 2 );
241  leftLayout->addLayout( lo_pcsa2o, row, 0, 1, 2 );
242  leftLayout->addLayout( lo_pcsa2omc, row, 2, 1, 2 );
243  leftLayout->addLayout( lo_pcsa2otr, row++, 4, 1, 4 );
244  leftLayout->addLayout( lo_dmgagl, row, 0, 1, 2 );
245  leftLayout->addLayout( lo_dmgaglmc, row++, 2, 1, 6 );
246 
247  leftLayout->addWidget( lb_plottype, row++, 0, 1, 8 );
248  leftLayout->addLayout( lo_pltsw, row, 0, 1, 2 );
249  leftLayout->addLayout( lo_pltMW, row, 2, 1, 2 );
250  leftLayout->addLayout( lo_pltDw, row, 4, 1, 2 );
251  leftLayout->addLayout( lo_pltff0, row++, 6, 1, 2 );
252  leftLayout->addLayout( lo_pltvb, row, 0, 1, 8 );
253  leftLayout->addLayout( lo_pltMWl, row++, 2, 1, 8 );
254 
255  leftLayout->addWidget( lb_sigma, row, 0, 1, 5 );
256  leftLayout->addWidget( ct_sigma, row++, 5, 1, 3 );
257  leftLayout->addWidget( lb_plxmin, row, 0, 1, 2 );
258  leftLayout->addWidget( le_plxmin, row, 2, 1, 2 );
259  leftLayout->addWidget( lb_plxmax, row, 4, 1, 2 );
260  leftLayout->addWidget( le_plxmax, row++, 6, 1, 2 );
261 
262  leftLayout->addWidget( lb_runinfo, row++, 0, 1, 8 );
263  leftLayout->addWidget( lb_runid, row, 0, 1, 3 );
264  leftLayout->addWidget( le_runid, row++, 3, 1, 5 );
265  leftLayout->addWidget( lb_svproj, row, 0, 1, 3 );
266  leftLayout->addWidget( cmb_svproj, row++, 3, 1, 5 );
267  leftLayout->addWidget( lb_runids, row++, 0, 1, 8 );
268  leftLayout->addWidget( lw_runids, row, 0, 1, 8 );
269  row += 2;
270  leftLayout->addLayout( lo_mdltype, row++, 0, 1, 8 );
271  leftLayout->addWidget( lb_models, row++, 0, 1, 8 );
272  //leftLayout->setRowStretch( row, 0 );
273  leftLayout->addWidget( lw_models, row, 0, 5, 8 );
274  row += 5;
275  leftLayout->setRowStretch( row, 1 );
276  leftLayout->addWidget( te_status, row++, 0, 1, 8 );
277 
278  connect( dkdb_cntrls, SIGNAL( changed( bool ) ),
279  this, SLOT( update_disk_db( bool ) ) );
280 
281  connect( pb_loadda, SIGNAL( clicked() ),
282  this, SLOT( load() ) );
283  connect( pb_saveda, SIGNAL( clicked() ),
284  this, SLOT( save() ) );
285  connect( pb_resetd, SIGNAL( clicked() ),
286  this, SLOT( reset_data() ) );
287  connect( pb_resetp, SIGNAL( clicked() ),
288  this, SLOT( reset_plot() ) );
289  connect( pb_help, SIGNAL( clicked() ),
290  this, SLOT( help() ) );
291  connect( pb_close, SIGNAL( clicked() ),
292  this, SLOT( close() ) );
293 
294  connect( ck_2dsa, SIGNAL( stateChanged ( int ) ),
295  this, SLOT( methodChanged ( int ) ) );
296  connect( ck_2dsamc, SIGNAL( stateChanged ( int ) ),
297  this, SLOT( methodChanged ( int ) ) );
298  connect( ck_2dsamw, SIGNAL( stateChanged ( int ) ),
299  this, SLOT( methodChanged ( int ) ) );
300  connect( ck_2dsamcmw, SIGNAL( stateChanged ( int ) ),
301  this, SLOT( methodChanged ( int ) ) );
302  connect( ck_2dsagl, SIGNAL( stateChanged ( int ) ),
303  this, SLOT( methodChanged ( int ) ) );
304  connect( ck_2dsaglmc, SIGNAL( stateChanged ( int ) ),
305  this, SLOT( methodChanged ( int ) ) );
306  connect( ck_2dsacg, SIGNAL( stateChanged ( int ) ),
307  this, SLOT( methodChanged ( int ) ) );
308  connect( ck_2dsacgmc, SIGNAL( stateChanged ( int ) ),
309  this, SLOT( methodChanged ( int ) ) );
310  connect( ck_2dsafm, SIGNAL( stateChanged ( int ) ),
311  this, SLOT( methodChanged ( int ) ) );
312  connect( ck_ga, SIGNAL( stateChanged ( int ) ),
313  this, SLOT( methodChanged ( int ) ) );
314  connect( ck_gamc, SIGNAL( stateChanged ( int ) ),
315  this, SLOT( methodChanged ( int ) ) );
316  connect( ck_gamw, SIGNAL( stateChanged ( int ) ),
317  this, SLOT( methodChanged ( int ) ) );
318  connect( ck_gamcmw, SIGNAL( stateChanged ( int ) ),
319  this, SLOT( methodChanged ( int ) ) );
320  connect( ck_gagl, SIGNAL( stateChanged ( int ) ),
321  this, SLOT( methodChanged ( int ) ) );
322  connect( ck_gaglmc, SIGNAL( stateChanged ( int ) ),
323  this, SLOT( methodChanged ( int ) ) );
324  connect( ck_pcsais, SIGNAL( stateChanged ( int ) ),
325  this, SLOT( methodChanged ( int ) ) );
326  connect( ck_pcsasl, SIGNAL( stateChanged ( int ) ),
327  this, SLOT( methodChanged ( int ) ) );
328  connect( ck_pcsads, SIGNAL( stateChanged ( int ) ),
329  this, SLOT( methodChanged ( int ) ) );
330  connect( ck_pcsahl, SIGNAL( stateChanged ( int ) ),
331  this, SLOT( methodChanged ( int ) ) );
332  connect( ck_pcsaismc, SIGNAL( stateChanged ( int ) ),
333  this, SLOT( methodChanged ( int ) ) );
334  connect( ck_pcsaslmc, SIGNAL( stateChanged ( int ) ),
335  this, SLOT( methodChanged ( int ) ) );
336  connect( ck_pcsadsmc, SIGNAL( stateChanged ( int ) ),
337  this, SLOT( methodChanged ( int ) ) );
338  connect( ck_pcsahlmc, SIGNAL( stateChanged ( int ) ),
339  this, SLOT( methodChanged ( int ) ) );
340  connect( ck_pcsaistr, SIGNAL( stateChanged ( int ) ),
341  this, SLOT( methodChanged ( int ) ) );
342  connect( ck_pcsasltr, SIGNAL( stateChanged ( int ) ),
343  this, SLOT( methodChanged ( int ) ) );
344  connect( ck_pcsadstr, SIGNAL( stateChanged ( int ) ),
345  this, SLOT( methodChanged ( int ) ) );
346  connect( ck_pcsahltr, SIGNAL( stateChanged ( int ) ),
347  this, SLOT( methodChanged ( int ) ) );
348  connect( ck_pcsa2o, SIGNAL( stateChanged ( int ) ),
349  this, SLOT( methodChanged ( int ) ) );
350  connect( ck_pcsa2omc, SIGNAL( stateChanged ( int ) ),
351  this, SLOT( methodChanged ( int ) ) );
352  connect( ck_pcsa2otr, SIGNAL( stateChanged ( int ) ),
353  this, SLOT( methodChanged ( int ) ) );
354  connect( ck_dtall, SIGNAL( stateChanged ( int ) ),
355  this, SLOT( allMethodChanged( int ) ) );
356 
357  connect( rb_pltsw, SIGNAL( toggled ( bool ) ),
358  this, SLOT( changedPlotX( bool ) ) );
359  connect( rb_pltMW, SIGNAL( toggled ( bool ) ),
360  this, SLOT( changedPlotX( bool ) ) );
361  connect( rb_pltDw, SIGNAL( toggled ( bool ) ),
362  this, SLOT( changedPlotX( bool ) ) );
363  connect( rb_pltff0, SIGNAL( toggled ( bool ) ),
364  this, SLOT( changedPlotX( bool ) ) );
365  connect( rb_pltvb, SIGNAL( toggled ( bool ) ),
366  this, SLOT( changedPlotX( bool ) ) );
367  connect( rb_pltMWl, SIGNAL( toggled ( bool ) ),
368  this, SLOT( changedPlotX( bool ) ) );
369 
370  connect( ct_sigma, SIGNAL( valueChanged( double ) ),
371  this, SLOT( envvalChange( ) ) );
372  connect( le_plxmin, SIGNAL( editingFinished( ) ),
373  this, SLOT( envvalChange( ) ) );
374  connect( le_plxmax, SIGNAL( editingFinished( ) ),
375  this, SLOT( envvalChange( ) ) );
376 
377  connect( ck_mdltype, SIGNAL( stateChanged( int ) ),
378  this, SLOT( ltypeChanged( ) ) );
379 
380  connect( lw_runids, SIGNAL( currentRowChanged( int ) ),
381  this, SLOT( runid_select( int ) ) );
382  connect( lw_models, SIGNAL( currentRowChanged( int ) ),
383  this, SLOT( model_select( int ) ) );
384 
385  QBoxLayout* plot = new US_Plot( data_plot1,
386  tr( "Discrete s20,W Distributions" ),
387  tr( "Sedimentation Coefficient x 1e+13 (corr. for 20,W)" ),
388  tr( "Signal Concentration" ) );
389 
390  data_plot1->setMinimumSize( 560, 400 );
391  data_plot1->setAxisScale( QwtPlot::xBottom, 1.0, 10.0 );
392  data_plot1->setAxisScale( QwtPlot::yLeft, 0.0, 100.0 );
393  QwtPlotGrid* grid = us_grid( data_plot1 );
394  grid->enableXMin( true );
395  grid->enableYMin( true );
396  grid->setMajPen( QPen( US_GuiSettings::plotMajGrid(), 0, Qt::DashLine ) );
397  grid->setMinPen( QPen( US_GuiSettings::plotMinGrid(), 0, Qt::DotLine ) );
398 
399  QwtLegend *legend = new QwtLegend;
400  legend->setFrameStyle( QFrame::Box | QFrame::Sunken );
401  legend->setFont( sfont );
402  data_plot1->insertLegend( legend, QwtPlot::BottomLegend );
403 
404  rightLayout->addLayout( plot );
405 
406  mainLayout ->addLayout( leftLayout );
407  mainLayout ->addLayout( rightLayout );
408  mainLayout ->setStretchFactor( leftLayout, 2 );
409  mainLayout ->setStretchFactor( rightLayout, 3 );
410 
411  le_runid ->setText( "(current run ID)" );
412  cmb_svproj ->addItem( "(project name for plot save)" );
413 
414  adjustSize();
415  int hh = lb_svproj->height();
416  int ww = lb_svproj->width() / 6;
417  lw_runids ->setMinimumHeight( hh * 2 );
418  lw_runids ->setMaximumHeight( hh * 4 );
419  lw_models ->setMinimumHeight( hh * 5 );
420  cmb_svproj ->setMinimumWidth ( ww * 2 );
421  for ( int ii = 0; ii < 8; ii++ )
422  leftLayout ->setColumnMinimumWidth( ii, ww );
423  leftLayout ->setColumnStretch ( 0, 1 );
424  leftLayout ->setColumnStretch ( 1, 1 );
425  te_status ->setMaximumHeight( ( hh * 3 ) / 2 );
426 
427  adjustSize();
428  resize( 1180, 580 );
429  reset_data();
430 }
431 
432 // Load data
434 {
435  QStringList runids;
436  QString runid;
437  te_status->setText( tr( "Building a list of selectable run IDs..." ) );
438  qApp->processEvents();
439 
440  // Open a dialog and get the runID(s)
441  US_SelectRunDD srdiag( dkdb_cntrls->db(), runids, aDescrs );
442  connect( &srdiag, SIGNAL( changed( bool ) ),
443  this, SLOT( update_disk_db( bool ) ) );
444  srdiag.exec();
445 
446  int nrunids = runids.count();
447  int nsprojs = cmb_svproj->count();
448  if ( nrunids < 1 ) return;
449 
450  te_status->setText( tr( "Updating the distributions list..." ) );
451  update_distros();
452 //*DEBUG*
453 if(dbg_level>0)
454 {
455  DbgLv(1) << "Selected runIDs[0]" << runids[0] << "count" << nrunids;
456  DbgLv(1) << "Selected models count" << aDescrs.count();
457  for(int ii=0;ii<aDescrs.count();ii++)
458  {
459  QString mrun=aDescrs[ii].section("\t",0,0);
460  QString mgid=aDescrs[ii].section("\t",1,1).left(9)+"...";
461  QString mdes=aDescrs[ii].section("\t",2,2);
462  QString ddes=aDescrs[ii].section("\t",3,3);
463  bool iter=mdes.contains("-MC_");
464  if(iter&&!mdes.contains("_mcN")) continue;
465  mdes="..."+mdes.section(".",1,-1);
466  DbgLv(1) << " ii" << ii << "mrun" << mrun << "mgid" << mgid
467  << "mdes" << mdes << "iter" << iter << "ddes" << ddes;
468  }
469 }
470 //*DEBUG*
471  te_status->setText( tr( "Added: %1 run(s), %2 implied total models." )
472  .arg( nrunids ).arg( distros.count() ) );
473 
474  if ( nsprojs == 1 )
475  {
476  cmb_svproj->clear();
477  }
478  else
479  {
480  cmb_svproj->removeItem( nsprojs - 1 );
481  }
482 
483  for ( int ii = 0; ii < nrunids; ii++ )
484  { // Add run IDs to list and to project combo box
485  lw_runids->addItem( runids[ ii ] );
486  cmb_svproj->addItem( runids[ ii ] );
487  }
488 
489  cmb_svproj->addItem( "All" );
490  le_runid->setText( runids[ 0 ] );
491  pb_resetd->setEnabled( true );
492  QStringList methods;
493 
494  for ( int ii = 0; ii < distros.count(); ii++ )
495  { // Build a list of unique methods of distros
496  QString method = distros[ ii ].mdescr.section( ".", -1, -1 )
497  .section( "_", -3, -3 );
498  if ( ! methods.contains( method ) )
499  methods << method;
500  }
501 
502  bool hv_2dsa = methods.contains( "2DSA" );
503  bool hv_2dsamc = methods.contains( "2DSA-MC" );
504  bool hv_2dsamw = methods.contains( "2DSA-MW" );
505  bool hv_2dsamcmw = methods.contains( "2DSA-MC-MW" );
506  bool hv_2dsagl = methods.contains( "2DSA-GL" );
507  bool hv_2dsaglmc = methods.contains( "2DSA-GL-MC" );
508  bool hv_2dsacg = methods.contains( "2DSA-CG" );
509  bool hv_2dsacgmc = methods.contains( "2DSA-CG-MC" );
510  bool hv_2dsafm = methods.contains( "2DSA-FM" );
511  bool hv_ga = methods.contains( "GA" );
512  bool hv_gamc = methods.contains( "GA-MC" );
513  bool hv_gamw = methods.contains( "GA-MW" );
514  bool hv_gamcmw = methods.contains( "GA-MC-MW" );
515  bool hv_gagl = methods.contains( "GA-GL" );
516  bool hv_gaglmc = methods.contains( "GA-GL-MC" );
517  bool hv_pcsais = methods.contains( "PCSA-IS" );
518  bool hv_pcsasl = methods.contains( "PCSA-SL" );
519  bool hv_pcsads = methods.contains( "PCSA-DS" );
520  bool hv_pcsahl = methods.contains( "PCSA-HL" );
521  bool hv_pcsaismc = methods.contains( "PCSA-IS-MC" );
522  bool hv_pcsaslmc = methods.contains( "PCSA-SL-MC" );
523  bool hv_pcsadsmc = methods.contains( "PCSA-DS-MC" );
524  bool hv_pcsahlmc = methods.contains( "PCSA-HL-MC" );
525  bool hv_pcsaistr = methods.contains( "PCSA-IS-TR" );
526  bool hv_pcsasltr = methods.contains( "PCSA-SL-TR" );
527  bool hv_pcsadstr = methods.contains( "PCSA-DS-TR" );
528  bool hv_pcsahltr = methods.contains( "PCSA-HL-TR" );
529  bool hv_pcsa2o = methods.contains( "PCSA-2O" );
530  bool hv_pcsa2omc = methods.contains( "PCSA-2O-MC" );
531  bool hv_pcsa2otr = methods.contains( "PCSA-2O-TR" );
532  bool hv_dmga = methods.contains( "DMGA" );
533  bool hv_dmgamc = methods.contains( "DMGA-MC" );
534  bool hv_dmgara = methods.contains( "DMGA-RA" );
535  bool hv_dmgaramc = methods.contains( "DMGA-RA-MC" );
536  bool hv_dmgagl = methods.contains( "DMGA-GL" );
537  bool hv_dmgaglmc = methods.contains( "DMGA-GL-MC" );
538  bool hv_dtall = methods.size() > 0;
539 
540  ck_2dsa ->setEnabled( hv_2dsa );
541  ck_2dsamc ->setEnabled( hv_2dsamc );
542  ck_2dsamw ->setEnabled( hv_2dsamw );
543  ck_2dsamcmw->setEnabled( hv_2dsamcmw );
544  ck_2dsagl ->setEnabled( hv_2dsagl );
545  ck_2dsaglmc->setEnabled( hv_2dsaglmc );
546  ck_2dsacg ->setEnabled( hv_2dsacg );
547  ck_2dsacgmc->setEnabled( hv_2dsacgmc );
548  ck_2dsafm ->setEnabled( hv_2dsafm );
549  ck_ga ->setEnabled( hv_ga );
550  ck_gamc ->setEnabled( hv_gamc );
551  ck_gamw ->setEnabled( hv_gamw );
552  ck_gamcmw ->setEnabled( hv_gamcmw );
553  ck_gagl ->setEnabled( hv_gagl );
554  ck_gaglmc ->setEnabled( hv_gaglmc );
555  ck_pcsais ->setEnabled( hv_pcsais );
556  ck_pcsasl ->setEnabled( hv_pcsasl );
557  ck_pcsads ->setEnabled( hv_pcsads );
558  ck_pcsahl ->setEnabled( hv_pcsahl );
559  ck_pcsaismc->setEnabled( hv_pcsaismc );
560  ck_pcsaslmc->setEnabled( hv_pcsaslmc );
561  ck_pcsadsmc->setEnabled( hv_pcsadsmc );
562  ck_pcsahlmc->setEnabled( hv_pcsahlmc );
563  ck_pcsaistr->setEnabled( hv_pcsaistr );
564  ck_pcsasltr->setEnabled( hv_pcsasltr );
565  ck_pcsadstr->setEnabled( hv_pcsadstr );
566  ck_pcsahltr->setEnabled( hv_pcsahltr );
567  ck_pcsa2o ->setEnabled( hv_pcsa2o );
568  ck_pcsa2omc->setEnabled( hv_pcsa2omc );
569  ck_pcsa2otr->setEnabled( hv_pcsa2otr );
570  ck_dmga ->setEnabled( hv_dmga );
571  ck_dmgamc ->setEnabled( hv_dmgamc );
572  ck_dmgara ->setEnabled( hv_dmgara );
573  ck_dmgaramc->setEnabled( hv_dmgaramc );
574  ck_dmgagl ->setEnabled( hv_dmgagl );
575  ck_dmgaglmc->setEnabled( hv_dmgaglmc );
576  ck_dtall ->setEnabled( hv_dtall );
577 
578  ck_2dsa ->setChecked( hv_2dsa );
579  ck_2dsamc ->setChecked( hv_2dsamc );
580  ck_2dsamw ->setChecked( hv_2dsamw );
581  ck_2dsamcmw->setChecked( hv_2dsamcmw );
582  ck_2dsagl ->setChecked( hv_2dsagl );
583  ck_2dsaglmc->setChecked( hv_2dsaglmc );
584  ck_2dsacg ->setChecked( hv_2dsacg );
585  ck_2dsacgmc->setChecked( hv_2dsacgmc );
586  ck_2dsafm ->setChecked( hv_2dsafm );
587  ck_ga ->setChecked( hv_ga );
588  ck_gamc ->setChecked( hv_gamc );
589  ck_gamw ->setChecked( hv_gamw );
590  ck_gamcmw ->setChecked( hv_gamcmw );
591  ck_gagl ->setChecked( hv_gagl );
592  ck_gaglmc ->setChecked( hv_gaglmc );
593  ck_pcsais ->setChecked( hv_pcsais );
594  ck_pcsasl ->setChecked( hv_pcsasl );
595  ck_pcsads ->setChecked( hv_pcsads );
596  ck_pcsahl ->setChecked( hv_pcsahl );
597  ck_pcsaismc->setChecked( hv_pcsaismc );
598  ck_pcsaslmc->setChecked( hv_pcsaslmc );
599  ck_pcsadsmc->setChecked( hv_pcsadsmc );
600  ck_pcsahlmc->setChecked( hv_pcsahlmc );
601  ck_pcsaistr->setChecked( hv_pcsaistr );
602  ck_pcsasltr->setChecked( hv_pcsasltr );
603  ck_pcsadstr->setChecked( hv_pcsadstr );
604  ck_pcsahltr->setChecked( hv_pcsahltr );
605  ck_pcsa2o ->setChecked( hv_pcsa2o );
606  ck_pcsa2omc->setChecked( hv_pcsa2omc );
607  ck_pcsa2otr->setChecked( hv_pcsa2otr );
608  ck_dmga ->setChecked( hv_dmga );
609  ck_dmgamc ->setChecked( hv_dmgamc );
610  ck_dmgara ->setChecked( hv_dmgara );
611  ck_dmgaramc->setChecked( hv_dmgaramc );
612  ck_dmgagl ->setChecked( hv_dmgagl );
613  ck_dmgaglmc->setChecked( hv_dmgaglmc );
614  ck_dtall ->setChecked( hv_dtall );
615 }
616 
617 // Reset data: remove all loaded data and clear plots
619 {
620  distros.clear();
621  distIDs.clear();
622  aDescrs.clear();
623 
624  lw_runids ->clear();
625  lw_models ->clear();
626  le_runid ->clear();
627  cmb_svproj ->clear();
628 
629  reset_plot();
630 
631  pb_resetd->setEnabled( false );
632  pb_resetp->setEnabled( false );
633 DbgLv(1) << "main size" << size();
634 }
635 
636 // Reset plot: Clear plots and lists of plotted data
638 {
639  data_plot1->detachItems();
640  data_plot1->clear();
641  data_plot1->replot();
642 
643  pdistrs.clear();
644  pdisIDs.clear();
645  pb_saveda->setEnabled( false );
646 
647  lw_models ->setCurrentRow( -1 );
648 }
649 
650 // Plot all data
652 {
653 DbgLv(1) << "pDa: xtype" << xtype;
654  data_plot1->detachItems();
656  data_grid->enableXMin( true );
657  data_grid->enableYMin( true );
658  data_grid->setMajPen(
659  QPen( US_GuiSettings::plotMajGrid(), 0, Qt::DashLine ) );
660  data_grid->setMinPen(
661  QPen( US_GuiSettings::plotMinGrid(), 0, Qt::DotLine ) );
662 
663  QString titleY = tr( "Signal Concentration" );
664 DbgLv(1) << "pDa: titleY" << titleY;
665  QString titleP;
666  QString titleX;
667 
668  if ( rb_pltsw->isChecked() )
669  {
670  titleP = tr( "Discrete s20,W Distributions" );
671  titleX = tr( "Sedimentation Coefficient x 1.e+13 (20,W)" );
672  }
673  else if ( rb_pltMW->isChecked() )
674  {
675  titleP = tr( "Discrete Molecular Weight Distributions" );
676  titleX = tr( "Molecular Weight (Dalton)" );
677  }
678  else if ( rb_pltDw->isChecked() )
679  {
680  titleP = tr( "Discrete D20,W Distributions" );
681  titleX = tr( "Diffusion Coefficient (20,W)" );
682  }
683  else if ( rb_pltff0->isChecked() )
684  {
685  titleP = tr( "Discrete Frictional Ratio Distributions" );
686  titleX = tr( "Frictional Ratio (f/f0)" );
687  }
688  else if ( rb_pltvb->isChecked() )
689  {
690  titleP = tr( "Discrete Vbar Distributions" );
691  titleX = tr( "Vbar (Specific Density)" );
692  }
693  else if ( rb_pltMWl->isChecked() )
694  {
695  titleP = tr( "Discrete Log of Molecular Weight Distributions" );
696  titleX = tr( "Molecular Weight (Log, Dalton)" );
697  }
698 DbgLv(1) << "pDa: titleP" << titleP;
699 DbgLv(1) << "pDa: titleX" << titleX;
700  data_plot1->setTitle ( titleP );
701  data_plot1->setAxisTitle( QwtPlot::xBottom, titleX );
702  data_plot1->setAxisTitle( QwtPlot::yLeft, titleY );
703  double plxmin = 1e+30;
704  double plxmax = -1e+30;
705 
706  for ( int ii = 0; ii < pdistrs.size(); ii++ )
707  {
708  setColor( pdistrs[ ii ], ii );
709  plot_distr( pdistrs[ ii ], pdisIDs[ ii ] );
710 
711  for ( int jj = 0; jj < pdistrs[ ii ].xvals.size(); jj++ )
712  {
713  plxmin = qMin( plxmin, pdistrs[ ii ].xvals[ jj ] );
714  plxmax = qMax( plxmax, pdistrs[ ii ].xvals[ jj ] );
715  }
716  }
717 
718  //if ( le_plxmax->text().toDouble() == 0.0 )
719  {
720  double plxinc = ( plxmax - plxmin ) / 299.0;
721  int rpwr = qRound( log10( plxinc ) );
722  plxinc = pow( 10.0, rpwr - 3 );
723  plxmin = (double)qFloor( plxmin / plxinc ) * plxinc;
724  plxmax = (double)qRound( plxmax / plxinc ) * plxinc;
725  le_plxmin->disconnect();
726  le_plxmax->disconnect();
727  le_plxmin->setText( QString::number( plxmin ) );
728  le_plxmax->setText( QString::number( plxmax ) );
729  connect( le_plxmin, SIGNAL( editingFinished( ) ),
730  this, SLOT( envvalChange( ) ) );
731  connect( le_plxmax, SIGNAL( editingFinished( ) ),
732  this, SLOT( envvalChange( ) ) );
733  }
734 }
735 
736 // Add a single distribution to the plot
737 void US_DDistr_Combine::plot_distr( DistrDesc ddesc, QString distrID )
738 {
739  int ndispt = ddesc.xvals.size();
740  double* xx = ddesc.xvals.data();
741  double* yy = ddesc.yvals.data();
742  QVector< double > xenv;
743  QVector< double > yenv;
744 DbgLv(1) << "pDi: ndispt" << ndispt << "ID" << distrID.left(20);
745 
746  QwtPlotCurve* data_curv = us_curve( data_plot1, distrID );
747 
748  if ( ct_sigma->value() > 0.0 )
749  {
750  data_curv->setPen ( QPen( QBrush( ddesc.color ), 2.0, Qt::SolidLine ) );
751  data_curv->setStyle( QwtPlotCurve::Lines );
752 
753  ndispt = envel_data( ddesc.xvals, ddesc.yvals, xenv, yenv );
754 
755  xx = xenv.data();
756  yy = yenv.data();
757  }
758  else
759  {
760  data_curv->setPen ( QPen( QBrush( ddesc.color ), 3.0, Qt::SolidLine ) );
761  data_curv->setStyle( QwtPlotCurve::Sticks );
762  }
763 
764  data_curv->setData ( xx, yy, ndispt );
765  data_curv->setItemAttribute( QwtPlotItem::Legend, true );
766 
767  double minx = le_plxmin->text().toDouble();
768  double maxx = le_plxmax->text().toDouble();
769  if ( maxx == 0.0 )
770  data_plot1->setAxisAutoScale( QwtPlot::xBottom );
771  else
772  data_plot1->setAxisScale( QwtPlot::xBottom, minx, maxx );
773  data_plot1->setAxisAutoScale( QwtPlot::yLeft );
774  data_plot1->enableAxis ( QwtPlot::xBottom, true );
775  data_plot1->enableAxis ( QwtPlot::yLeft, true );
776 
777  if ( pdistrs.size() < 2 )
778  { // Set up grid if first distribution in plot
780  data_grid->enableXMin( true );
781  data_grid->enableYMin( true );
782  data_grid->setMajPen(
783  QPen( US_GuiSettings::plotMajGrid(), 0, Qt::DashLine ) );
784  data_grid->setMinPen(
785  QPen( US_GuiSettings::plotMinGrid(), 0, Qt::DotLine ) );
786  }
787 
788  data_plot1->replot();
789 }
790 
791 // Save the plot data
793 {
794  QString oproj = cmb_svproj->currentText();
795  QString runID = ( oproj == "All" ) ? pdistrs[ 0 ].runID : oproj;
796  QString fdir = US_Settings::reportDir() + "/" + runID;
797  QString mdescr = pdistrs[ 0 ].mdescr;
798  QString annode = mdescr.section( ".", -1, -1 ).section( "_", -3, -3 );
799  QString trnode = "0Z9999";
800  QString sanode1 = "combo-distrib-s";
801  QString sanode2 = "combo-vcdat-s";
802  QString sanode3 = "combo-listincl-s";
803 
804  if ( xtype == 1 )
805  {
806  sanode1 = "combo-distrib-mw";
807  sanode2 = "combo-vcdat-mw";
808  sanode3 = "combo-listincl-mw";
809  }
810  else if ( xtype == 2 )
811  {
812  sanode1 = "combo-distrib-d";
813  sanode2 = "combo-vcdat-d";
814  sanode3 = "combo-listincl-d";
815  }
816  else if ( xtype == 3 )
817  {
818  sanode1 = "combo-distrib-ff0";
819  sanode2 = "combo-vcdat-ff0";
820  sanode3 = "combo-listincl-ff0";
821  }
822  else if ( xtype == 4 )
823  {
824  sanode1 = "combo-distrib-vbar";
825  sanode2 = "combo-vcdat-vbar";
826  sanode3 = "combo-listincl-vbar";
827  }
828  else if ( xtype == 5 )
829  {
830  sanode1 = "combo-distrib-mwl";
831  sanode2 = "combo-vcdat-mwl";
832  sanode3 = "combo-listincl-mwl";
833  }
834  QString fnamsvg = annode + "." + trnode + "." + sanode1 + ".svgz";
835  QString fnampng = annode + "." + trnode + "." + sanode1 + ".png";
836  //QString fnamdat = annode + "." + trnode + "." + sanode2 + ".dat";
837  QString fnamdat = annode + "." + trnode + "." + sanode2 + ".csv";
838  QString fnamlst = annode + "." + trnode + "." + sanode3 + ".rpt";
839  QString plotFile = fdir + "/" + fnamsvg;
840  QString dataFile = fdir + "/" + fnamdat;
841  QString listFile = fdir + "/" + fnamlst;
842  QStringList prunids;
843  QList< int > prndxs;
844  QString svmsg = tr( "Saved:\n " ) + fnampng + "\n "
845  + fnamsvg + "\n "
846  + fnamdat + "\n "
847  + fnamlst + "\n";
848  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
849 
850  // Look for multiple run IDs
851  for ( int ii = 0; ii < pdistrs.size(); ii++ )
852  {
853  QString prun = pdistrs[ ii ].runID;
854  if ( oproj == "All" )
855  { // If save-plot project is "All", save lists of runids and indexes
856  if ( ! prunids.contains( prun ) )
857  {
858  prunids << prun;
859  prndxs << ii;
860  }
861  }
862 
863  else if ( prun == runID )
864  { // If save-plot project matches current run, save it and its index
865  prunids << prun;
866  prndxs << ii;
867  break;
868  }
869  }
870 
871  int iruns = 0;
872  int nruns = prunids.size();
873 
874  while( iruns < nruns )
875  {
876  if ( ! QFile( fdir ).exists() )
877  { // If need be, create runID directory
878  QDir().mkpath( fdir );
879  }
880 
881  // Save plot file as SVG and as PNG; write data and list files
882  write_plot( plotFile, data_plot1 );
883  write_data( dataFile, listFile, iruns );
884  svmsg += tr( "in directory:" ) + "\n " + fdir + "\n";
885 
886  if ( dkdb_cntrls->db() )
887  {
888  US_Passwd pw;
889  US_DB2 db( pw.getPasswd() );
890  int idEdit = 0;
891  int kl = pdistrs.size() - 1;
892 
893  QString trfirst = pdistrs[ 0 ].mdescr.section( ".", -2, -2 );
894  QString trlast = pdistrs[ kl ].mdescr.section( ".", -2, -2 );
895  QString trdesc = "Combined Analyses (" + trfirst
896  + "..." + trlast + ")";
897 
898  QString editID; // Edit ID for matching experiment,triple
899  QString eeditID; // First edit ID from experiment match
900  // Get test triple to match file part and investigator
901  QString trip1 = "";
902  QString invID = QString::number( US_Settings::us_inv_ID() );
903  // Query for the experiment ID matching the run ID
904  QStringList query;
905  query << "get_experiment_info_by_runID" << runID << invID;
906  db.query( query );
907  db.next();
908  QString expID = db.value( 1 ).toString();
909 DbgLv(1) << "SV: runID expID" << runID << expID;
910  // Query for the raw ID in experiment matching a triple
911  QString rawID;
912  query.clear();
913  query << "get_rawDataIDs" << expID;
914  db.query( query );
915  while ( db.next() )
916  {
917  rawID = db.value( 0 ).toString();
918  QString efname = db.value( 2 ).toString();
919 DbgLv(1) << "SV: rawID" << rawID << "efname" << efname << "trip1" << trip1;
920  // Save rawID when we have found a triple match
921  if ( efname.contains( trip1 ) )
922  break;
923  }
924  // Query edit IDs for raw ID and look for triple match
925  query.clear();
926  query << "get_editedDataIDs" << rawID;
927  db.query( query );
928  while ( db.next() )
929  {
930  QString aeditID = db.value( 0 ).toString();
931  QString efname = db.value( 2 ).toString();
932  if ( eeditID.isEmpty() )
933  eeditID = aeditID; // Save 1st valid from experiment
934 DbgLv(1) << "SV: editID" << eeditID << "raw exp trip1 fname"
935  << rawID << expID << trip1 << efname;
936  if ( efname.contains( trip1 ) )
937  { // Keep saving editID from last triple match
938  editID = aeditID;
939 DbgLv(1) << "SV: Name-Trip MATCH: editID" << editID;
940  }
941  }
942 
943  if ( ! editID.isEmpty() )
944  { // Use edit ID from last matching triple
945  idEdit = editID.toInt();
946  }
947  else
948  { // Or fall back to one from first valid edit in experiment
949  idEdit = eeditID.toInt();
950  }
951 DbgLv(1) << "SV: editID idEdit" << editID << idEdit << " eeditID" << eeditID;
952 
953  // Add or update report documents in the database
954  QStringList rfiles;
955  rfiles << fnamsvg << fnampng << fnamdat << fnamlst;
956  int st = reportDocsFromFiles( runID, fdir, rfiles, &db,
957  idEdit, trdesc );
958 
959 DbgLv(1) << "SV:runID" << runID << "idEdit" << idEdit
960  << "fnamlst" << fnamlst << "trdesc" << trdesc;
961  if ( iruns == ( nruns - 1 ) )
962  { // Append message line after last run save
963  if ( st == 0 )
964  svmsg += tr( "\nThe files were also saved to the database" );
965  else
966  svmsg += tr( "\n*ERROR* in saving files to the database" );
967  }
968  } // END: database
969 
970  if ( ++iruns >= nruns ) break;
971 
972  runID = prunids[ iruns ];
973  fdir = US_Settings::reportDir() + "/" + runID;
974  plotFile = fdir + "/" + fnamsvg;
975  dataFile = fdir + "/" + fnamdat;
976  listFile = fdir + "/" + fnamlst;
977  } // END: runs loop
978 
979  QApplication::restoreOverrideCursor();
980 
981  // Report saved files
982  QMessageBox::information( this, tr( "Combo Distro Plot File Save" ), svmsg );
983 }
984 
985 // RunID selected
987 {
988 DbgLv(1) << "RunIDSel:row" << row;
989  if ( row < 0 ) return;
990 
991  // Get selected run item and its ID
992  QListWidgetItem* item = lw_runids->item( row );
993  runID = item->text();
994 DbgLv(1) << "RunIDSel:runID" << runID << "distrsize" << distros.size();
995  le_runid ->setText( runID );
996 
997  // Check for filtering by method
998  bool mfilter = ! ck_dtall->isChecked();
999  QStringList methods;
1000 
1001  if ( mfilter )
1002  {
1003  if ( ck_2dsa ->isChecked() ) methods << "2DSA";
1004  if ( ck_2dsamc ->isChecked() ) methods << "2DSA-MC";
1005  if ( ck_2dsamw ->isChecked() ) methods << "2DSA-MW";
1006  if ( ck_2dsamcmw->isChecked() ) methods << "2DSA-MC-MW";
1007  if ( ck_2dsagl ->isChecked() ) methods << "2DSA-GL";
1008  if ( ck_2dsaglmc->isChecked() ) methods << "2DSA-GL-MC";
1009  if ( ck_2dsacg ->isChecked() ) methods << "2DSA-CG";
1010  if ( ck_2dsacgmc->isChecked() ) methods << "2DSA-CG-MC";
1011  if ( ck_2dsafm ->isChecked() ) methods << "2DSA-FM";
1012  if ( ck_ga ->isChecked() ) methods << "GA";
1013  if ( ck_gamc ->isChecked() ) methods << "GA-MC";
1014  if ( ck_gamw ->isChecked() ) methods << "GA-MW";
1015  if ( ck_gamcmw ->isChecked() ) methods << "GA-MC-MW";
1016  if ( ck_gagl ->isChecked() ) methods << "GA-GL";
1017  if ( ck_gaglmc ->isChecked() ) methods << "GA-GL-MC";
1018  if ( ck_pcsais ->isChecked() ) methods << "PCSA-IS";
1019  if ( ck_pcsasl ->isChecked() ) methods << "PCSA-SL";
1020  if ( ck_pcsads ->isChecked() ) methods << "PCSA-DS";
1021  if ( ck_pcsahl ->isChecked() ) methods << "PCSA-HL";
1022  if ( ck_pcsaismc->isChecked() ) methods << "PCSA-IS-MC";
1023  if ( ck_pcsaslmc->isChecked() ) methods << "PCSA-SL-MC";
1024  if ( ck_pcsadsmc->isChecked() ) methods << "PCSA-DS-MC";
1025  if ( ck_pcsahlmc->isChecked() ) methods << "PCSA-HL-MC";
1026  if ( ck_pcsaistr->isChecked() ) methods << "PCSA-IS-TR";
1027  if ( ck_pcsasltr->isChecked() ) methods << "PCSA-SL-TR";
1028  if ( ck_pcsadstr->isChecked() ) methods << "PCSA-DS-TR";
1029  if ( ck_pcsahltr->isChecked() ) methods << "PCSA-HL-TR";
1030  if ( ck_pcsa2o ->isChecked() ) methods << "PCSA-2O";
1031  if ( ck_pcsa2omc->isChecked() ) methods << "PCSA-2O-MC";
1032  if ( ck_pcsa2otr->isChecked() ) methods << "PCSA-2O-TR";
1033  if ( ck_dmga ->isChecked() ) methods << "DMGA";
1034  if ( ck_dmgamc ->isChecked() ) methods << "DMGA-MC";
1035  if ( ck_dmgara ->isChecked() ) methods << "DMGA-RA";
1036  if ( ck_dmgaramc->isChecked() ) methods << "DMGA-RA-MC";
1037  if ( ck_dmgagl ->isChecked() ) methods << "DMGA-GL";
1038  if ( ck_dmgaglmc->isChecked() ) methods << "DMGA-GL-MC";
1039  }
1040 
1041  lw_models ->clear();
1042  QString grunID = "global-" + runID;
1043 
1044  for ( int ii = 0; ii < distros.size(); ii++ )
1045  {
1046 DbgLv(1) << "RunIDSel: ii runID" << ii << distros[ii].runID;
1047  if ( distros[ ii ].runID == runID ||
1048  distros[ ii ].runID.startsWith( grunID ) )
1049  { // Only (possibly) add item with matching run ID
1050  QString mdesc = distros[ ii ].mdescr;
1051  QString ddesc = distros[ ii ].ddescr;
1052 
1053  if ( mfilter )
1054  { // If method-filtering, skip any item whose method is not checked
1055  QString meth = mdesc.section( ".", -1, -1 ).section( "_", -3, -3 );
1056 DbgLv(1) << "RunIDSel: meth" << meth;
1057  if ( ! methods.contains( meth ) ) continue;
1058  }
1059 
1060 DbgLv(1) << "RunIDSel: added: ddesc" << ddesc;
1061  lw_models->addItem( distribID( mdesc, ddesc ) );
1062  }
1063  }
1064 
1065  if ( pdistrs.size() == 0 )
1066  {
1067  cmb_svproj->setCurrentIndex( cmb_svproj->findText( runID ) );
1068  }
1069 }
1070 
1071 // Model distribution selected
1073 {
1074 DbgLv(1) << "ModelSel:row" << row;
1075  if ( row < 0 ) return;
1076  QListWidgetItem* item = lw_models ->item( row );
1077  QString distrID = item->text();
1078  int mdx = distro_by_descr( distrID );
1079 DbgLv(1) << "ModelSel: model" << distrID << "mdx" << mdx;
1080  DistrDesc* ddesc = &distros[ mdx ];
1081 
1082  if ( ! pdisIDs.contains( distrID ) )
1083  { // If this distro not yet filled out, do so now
1084 
1085  fill_in_desc( distros[ mdx ], pdistrs.size() );
1086 
1087  pdistrs << *ddesc; // Add to list of plotted distros
1088  pdisIDs << distrID; // Add to list of IDs of plotted distros
1089  }
1090 
1091  if ( ddesc->model.components.size() == 0 )
1092  {
1093  QMessageBox::critical( this, tr( "Zero-Components Model" ),
1094  tr( "*ERROR* The selected model has zero components.\n"
1095  "This selection is ignored" ) );
1096  return;
1097  }
1098 
1099  plot_data();
1100 
1101  pb_saveda->setEnabled( true );
1102  pb_resetd->setEnabled( true );
1103  pb_resetp->setEnabled( true );
1104 
1105  te_status->setText( tr( "Count of plotted distributions: %1." )
1106  .arg( pdistrs.count() ) );
1107 }
1108 
1109 // Assign color for a distribution
1110 void US_DDistr_Combine::setColor( DistrDesc& ddesc, int distx )
1111 {
1112  possibleColors(); // Make sure possible colors exist
1113 
1114  int ncolors = colors.size();
1115  int color_index = distx;
1116 
1117  while ( color_index >= ncolors )
1118  color_index -= ncolors;
1119 
1120 DbgLv(1) << "sC: color_index" << color_index;
1121  ddesc.color = colors[ color_index ];
1122  return;
1123 }
1124 
1125 // Generate list of colors if need be
1127 {
1128  if ( colors.size() > 0 )
1129  return;
1130 
1131  colors << QColor( 255, 0, 0 );
1132  colors << QColor( 0, 255, 0 );
1133  colors << QColor( 0, 0, 255 );
1134  colors << QColor( 255, 255, 0 );
1135  colors << QColor( 255, 0, 255 );
1136  colors << QColor( 0, 255, 255 );
1137  colors << QColor( 122, 0, 255 );
1138  colors << QColor( 0, 255, 122 );
1139  colors << QColor( 0, 122, 255 );
1140  colors << QColor( 255, 122, 0 );
1141  colors << QColor( 122, 255, 0 );
1142  colors << QColor( 80, 0, 255 );
1143  colors << QColor( 255, 0, 80 );
1144  colors << QColor( 80, 0, 255 );
1145  colors << QColor( 255, 0, 80 );
1146  colors << QColor( 0, 255, 80 );
1147  colors << QColor( 0, 80, 255 );
1148  colors << QColor( 80, 255, 0 );
1149  colors << QColor( 255, 80, 40 );
1150  colors << QColor( 40, 255, 40 );
1151  colors << QColor( 40, 40, 255 );
1152  return;
1153 }
1154 
1155 // Return a distribution ID string: shortened model or cell description
1156 QString US_DDistr_Combine::distribID( QString mdescr, QString ddescr )
1157 {
1158  const int mxrch = 30;
1159  int mdx = 9999;
1160  QString distrID;
1161  QString runID = mdescr.section( ".", 0, -3 );
1162  runID = runID.length() <= mxrch ?
1163  runID : runID.left( mxrch ) + "(++)";
1164  QString triple = mdescr.section( ".", -2, -2 );
1165  QString iterID = mdescr.section( ".", -1, -1 );
1166  QString andate = iterID.section( "_", 1, 1 );
1167  QString method = iterID.section( "_", 2, 2 );
1168  iterID = ( method != "2DSA-FM" )
1169  ? iterID.section( "_", -2, -2 )
1170  : iterID.section( "_", -1, -1 );
1171 
1172  if ( ck_mdltype->isChecked() )
1173  { // Model-description list/legend type
1174  distrID = runID + "." + triple + "." + andate + "_" + method
1175  + "_" + iterID;
1176  }
1177  else
1178  { // Data-description list/legend type (the default)
1179  distrID = runID + " (" + triple + ", " + method + ") " + ddescr;
1180  }
1181 
1182  for ( int ii = 0; ii < distros.size(); ii++ )
1183  { // Find index of full model description match as distinguishing suffix
1184  if ( mdescr == distros[ ii ].mdescr )
1185  {
1186  mdx = ii + 1;
1187  break;
1188  }
1189  }
1190 
1191  distrID += "[" + QString::number( mdx ) + "]";
1192 
1193  return distrID;
1194 }
1195 
1196 // Reset Disk_DB control whenever data source is changed in any dialog
1198 { isDB ? dkdb_cntrls->set_db() : dkdb_cntrls->set_disk();
1199 DbgLv(1) << "Upd_Dk_Db isDB" << isDB;
1200 
1201  reset_data();
1202 }
1203 
1204 // Fill in a distribution description object with model and values
1206 {
1207  if ( ddesc.xvals.size() > 0 &&
1208  ddesc.model.components.size() > 0 &&
1209  ddesc.xtype == xtype )
1210  return;
1211 
1212  // The distribution record is at least partially uninitialized
1213  QVector< double > mxvals;
1214  QVector< double > myvals;
1215  QString mdescr = ddesc.mdescr;
1216  ddesc.iters = mdescr.contains( "-MC_" ) ? 1 : 0;
1217 DbgLv(1) << "FID: mdescr" << mdescr << "iters" << ddesc.iters;
1218  bool isDB = dkdb_cntrls->db();
1219  US_Passwd pw;
1220  US_DB2* db = isDB ? new US_DB2( pw.getPasswd() ) : 0;
1221  int ncomps = ddesc.model.components.size();
1222 DbgLv(1) << "FID: ncomps" << ncomps;
1223 
1224  // Read in the (first) model
1225  if ( ncomps == 0 )
1226  { // Model not yet loaded, so load it now
1227  ddesc.model.load( isDB, ddesc.mGUID, db );
1228 
1229  ncomps = ddesc.model.components.size(); // Composite components
1230 DbgLv(1) << "FID: (2)ncomps" << ncomps;
1231  }
1232 DbgLv(1) << "FID: (3)ncomps" << ncomps;
1233 
1234  // Build the X,Y vectors with values at every component point
1235  for ( int jj = 0; jj < ncomps; jj++ )
1236  {
1237  myvals << ddesc.model.components[ jj ].signal_concentration;
1238  double xval = ddesc.model.components[ jj ].s * 1.e+13;
1239  if ( xtype == 1 ) xval = ddesc.model.components[ jj ].mw;
1240  else if ( xtype == 2 ) xval = ddesc.model.components[ jj ].D;
1241  else if ( xtype == 3 ) xval = ddesc.model.components[ jj ].f_f0;
1242  else if ( xtype == 4 ) xval = ddesc.model.components[ jj ].vbar20;
1243  else if ( xtype == 5 ) xval = log( ddesc.model.components[ jj ].mw );
1244 
1245  mxvals << xval;
1246  }
1247 
1248  ddesc.xtype = xtype;
1249  if ( ncomps == 0 )
1250  return;
1251 DbgLv(1) << "FID: xtype" << xtype << "mxval.size" << mxvals.size();
1252  ddesc.xvals.fill( 0.0, ncomps );
1253  ddesc.yvals.fill( 0.0, ncomps );
1254  int kk = 0;
1255  int nn = 1;
1256  double xval = mxvals[ 0 ];
1257  double yval = myvals[ 0 ];
1258  ddesc.xvals[ 0 ] = xval;
1259  ddesc.yvals[ 0 ] = yval;
1260 
1261  // Sum y values where x values are effectively equivalent
1262  for ( int jj = 1; jj < ncomps; jj++ )
1263  {
1264  double xvpr = xval;
1265  double yvpr = yval;
1266  xval = mxvals[ jj ];
1267  yval = myvals[ jj ];
1268 
1269  if ( equivalent( xval, xvpr, epsilon ) )
1270  { // Effectively equal x values: sum y values
1271  yval += yvpr;
1272  ddesc.xvals[ kk ] = ( xvpr + xval ) * 0.5;
1273  ddesc.yvals[ kk ] = yval;
1274  }
1275 
1276  else
1277  { // New x value: save y value and bump count
1278  kk = nn;
1279  ddesc.xvals[ nn ] = xval;
1280  ddesc.yvals[ nn++ ] = yval;
1281  }
1282  }
1283 
1284  kk = 0;
1285 
1286  // Compress the vectors down to only non-zero-Y points
1287  for ( int jj = 0; jj < nn; jj++ )
1288  {
1289  if ( ddesc.yvals[ jj ] != 0.0 )
1290  { // Move point to next non-zero output location
1291  ddesc.xvals[ kk ] = ddesc.xvals[ jj ];
1292  ddesc.yvals[ kk++ ] = ddesc.yvals[ jj ];
1293  }
1294  }
1295 
1296  ddesc.xvals.resize( kk ); // Resize to just the non-zero points
1297  ddesc.yvals.resize( kk );
1298 
1299  setColor( ddesc, distx );
1300 }
1301 
1302 // Write data and list report files
1303 void US_DDistr_Combine::write_data( QString& dataFile, QString& listFile,
1304  int& irun )
1305 {
1306  int arrsize = 300;
1307 
1308  if ( irun > 0 )
1309  { // After first/only time: just make a copy of the files
1310  QFile( dat1File ).copy( dataFile );
1311  QFile( lis1File ).copy( listFile );
1312  return;
1313  }
1314 
1315  // First/only time through: compute the data and create files
1316  QStringList pdlong;
1317  QString line;
1318  dat1File = dataFile;
1319  lis1File = listFile;
1320 
1321  QFile dfile( dataFile );
1322 
1323  if ( ! dfile.open( QIODevice::WriteOnly | QIODevice::Text ) )
1324  {
1325  qDebug() << "***Error opening output file" << dataFile;
1326  return;
1327  }
1328 
1329  QTextStream tsd( &dfile );
1330 
1331  QVector< QVector< double > > peyvals;
1332  QVector< double > xenvs;
1333  QVector< double > yenvs;
1334  QVector< double >* xvals;
1335  QVector< double >* yvals;
1336  int nplots = pdistrs.size();
1337  int lplot = nplots - 1;
1338  int maxnvl = 0;
1339  int nenvvl = arrsize;
1340  line = "";
1341 
1342  // Build header lines and accumulate envelope Y vectors for each plot
1343 
1344  for ( int ii = 0; ii < nplots; ii++ )
1345  {
1346  // Accumulate long descriptions and build header line
1347  maxnvl = qMax( maxnvl, pdistrs[ ii ].xvals.size() );
1348  QString mdescr = pdistrs[ ii ].mdescr;
1349  QString mdtrip = mdescr.section( ".", -2, -2 );
1350  QString mditer = mdescr.section( ".", -1, -1 );
1351  QString mdmeth = mditer.section( "_", 2, 2 );
1352  QString pd = "\"" + mdtrip + "." + mdmeth + ".";
1353 
1354  pdlong << mdescr;
1355 
1356 DbgLv(1) << "WrDa: plot" << ii << "pd" << pd;
1357  // X,Y header entries for contributor
1358  line += pd + "raw-x\"," + pd + "raw-y\",";
1359 
1360  // Compute envelope vectors and save the Y vector for each plot
1361  envel_data( pdistrs[ ii ].xvals, pdistrs[ ii ].yvals, xenvs, yenvs );
1362 
1363  peyvals << yenvs;
1364  }
1365 
1366  // Add the single smooth X header string
1367  line += "\"all.smooth-x\",";
1368 
1369  for ( int ii = 0; ii < nplots; ii++ )
1370  { // Add smooth Y header strings
1371  QString mdescr = pdistrs[ ii ].mdescr;
1372  QString mdtrip = mdescr.section( ".", -2, -2 );
1373  QString mditer = mdescr.section( ".", -1, -1 );
1374  QString mdmeth = mditer.section( "_", 2, 2 );
1375  QString pd = "\"" + mdtrip + "." + mdmeth + ".";
1376  line += pd + "smooth-y\"";
1377  line += ( ( ii < lplot ) ? "," : "\n" );
1378  }
1379 
1380  tsd << line; // Write header line
1381 
1382 DbgLv(1) << "WrDa: maxnvl" << maxnvl << "nplots" << nplots;
1383  char valfm1[] = "\"%.5f\",\"%.5f\"";
1384  char valfm2[] = "\"%.4e\",\"%.5f\"";
1385  char valfx1[] = "\"%.5f\"";
1386  char valfy1[] = "\"%.5f\"";
1387  char valfx2[] = "\"%.4e\"";
1388  char valfy2[] = "\"%.5f\"";
1389  QString dummy_pair( "\"\",\"\"," );
1390  QString dummy_valu( "\"\"" );
1391  char* valfmt = valfm1;
1392  char* valfmx = valfx1;
1393  char* valfmy = valfy1;
1394  maxnvl = qMax( maxnvl, nenvvl );
1395  if ( xtype == 1 || xtype == 2 || xtype == 5 )
1396  {
1397  valfmt = valfm2; // Formatting for "MW"/"D"/"MWlog"
1398  valfmx = valfx2;
1399  valfmy = valfy2;
1400  }
1401 
1402  for ( int jj = 0; jj < maxnvl; jj++ )
1403  { // Build and write xvalue+concentration data line
1404  line = "";
1405 
1406  // First add X,Y for raw plots
1407  for ( int ii = 0; ii < nplots; ii++ )
1408  { // Add each pair of X,Y data pairs
1409  xvals = &pdistrs[ ii ].xvals;
1410  yvals = &pdistrs[ ii ].yvals;
1411 
1412  // Get and add raw data to line
1413  if ( jj < xvals->size() )
1414  line += QString().sprintf(
1415  valfmt, xvals->at( jj ), yvals->at( jj ) ) + ",";
1416  else
1417  line += dummy_pair;
1418 
1419  // Get and add envelope (smoothed) data to line
1420  }
1421 
1422  // Now add X for envelopes and the Y's for each plot
1423  if ( jj < nenvvl )
1424  line += QString().sprintf( valfmx, xenvs[ jj ] ) + ",";
1425  else
1426  line += dummy_valu + ",";
1427 
1428  for ( int ii = 0; ii < nplots; ii++ )
1429  {
1430  if ( jj < nenvvl )
1431  line += QString().sprintf( valfmy, peyvals[ ii ][ jj ] );
1432  else
1433  line += dummy_valu;
1434 
1435  line += ( ii < lplot ) ? "," : "\n";
1436  }
1437 
1438  tsd << line; // Write data line
1439 //DbgLv(1) << "WrDa: jj" << jj << " line written";
1440  }
1441 
1442  dfile.close();
1443 
1444  // Write list-of-included file
1445  QFile lfile( listFile );
1446  if ( ! lfile.open( QIODevice::WriteOnly | QIODevice::Text ) )
1447  {
1448  qDebug() << "***Error opening output file" << listFile;
1449  return;
1450  }
1451  QTextStream tsl( &lfile );
1452 
1453  for ( int ii = 0; ii < nplots; ii++ )
1454  { // Build and write each long-description line
1455  line = pdlong[ ii ] + "\n";
1456  tsl << line;
1457  }
1458 
1459  lfile.close();
1460 
1461  return;
1462 }
1463 
1464 // Save report documents from files
1465 int US_DDistr_Combine::reportDocsFromFiles( QString& runID, QString& fdir,
1466  QStringList& files, US_DB2* db, int& idEdit, QString& trdesc )
1467 {
1468  DbgLv(1) << "rDFF: runID fdir files0" << runID << fdir << files[0];
1469  DbgLv(1) << "rDFF: idEdit trdesc" << idEdit << trdesc;
1470  int ostat = 0;
1471  US_Report freport;
1472  freport.runID = runID;
1473 
1474  for ( int ii = 0; ii < files.size(); ii++ )
1475  {
1476  QString fname = files[ ii ];
1477  int st = freport.saveDocumentFromFile( fdir, fname, db, idEdit, trdesc );
1478 
1479  ostat = ( st == US_Report::REPORT_OK ) ? ostat : st;
1480  }
1481 
1482 //*DEBUG*
1483  if ( dbg_level > 0 )
1484  {
1485  int status = freport.readDB( runID, db );
1486  DbgLv(1) << "DFF:report readDB status" << status << "ID" << freport.ID;
1487  DbgLv(1) << "DFF: report triples size" << freport.triples.size();
1488  for ( int ii = 0; ii < freport.triples.size(); ii++ )
1489  {
1490  int ndoc = freport.triples[ii].docs.size();
1491  DbgLv(1) << "DFF: triple" << ii << "docssize" << ndoc
1492  << "ID" << freport.triples[ii].tripleID
1493  << "triple" << freport.triples[ii].triple;
1494  int jj = ndoc - 1;
1495  if ( ndoc > 0 )
1496  {
1497  DbgLv(1) << "DFF: doc" << 0
1498  << "ID" << freport.triples[ii].docs[0].documentID
1499  << "label" << freport.triples[ii].docs[0].label;
1500  DbgLv(1) << "DFF: doc" << jj
1501  << "ID" << freport.triples[ii].docs[jj].documentID
1502  << "label" << freport.triples[ii].docs[jj].label;
1503  }
1504  }
1505  QString fname = files[0];
1506  QString tripl( "0/Z/9999" );
1507  int ndx = freport.findTriple( tripl );
1508  DbgLv(1) << "DFF:triple" << tripl << "ndx" << ndx;
1509  if ( ndx >= 0 )
1510  {
1511  int ndoc = freport.triples[ndx].docs.size();
1512  DbgLv(1) << "DFF: triple" << ndx << "docs size" << ndoc
1513  << "ID" << freport.triples[ndx].tripleID
1514  << "triple" << freport.triples[ndx].triple;
1515  if ( ndoc > 0 )
1516  {
1517  DbgLv(1) << "DFF: doc" << 0
1518  << "ID" << freport.triples[ndx].docs[0].documentID
1519  << "label" << freport.triples[ndx].docs[0].label;
1520  int jj = ndoc - 1;
1521  DbgLv(1) << "DFF: doc" << jj
1522  << "ID" << freport.triples[ndx].docs[jj].documentID
1523  << "label" << freport.triples[ndx].docs[jj].label;
1524  }
1525  }
1526  }
1527 //*DEBUG*
1528 
1529  return ostat;
1530 }
1531 
1532 // Get the index to a distro using the model description
1534 {
1535  int index = -1;
1536 
1537  for ( int ii = 0; ii < distros.count(); ii++ )
1538  {
1539  if ( mdesc
1540  == distribID( distros[ ii ].mdescr, distros[ ii ].ddescr ) )
1541  {
1542  index = ii;
1543  break;
1544  }
1545  }
1546 
1547  return index;
1548 }
1549 
1550 // Get the index to a distro using the model GUID
1552 {
1553  int index = -1;
1554 
1555  for ( int ii = 0; ii < distros.count(); ii++ )
1556  {
1557  if ( mguid == distros[ ii ].mGUID )
1558  {
1559  index = ii;
1560  break;
1561  }
1562  }
1563 
1564  return index;
1565 }
1566 
1567 // Get the next index to a distro that has a matching run ID
1568 int US_DDistr_Combine::distro_by_runid( QString& runid, int first )
1569 {
1570  int index = -1;
1571 
1572  for ( int ii = first; ii < distros.count(); ii++ )
1573  {
1574  if ( runid == distros[ ii ].runID )
1575  {
1576  index = ii;
1577  break;
1578  }
1579  }
1580 
1581  return index;
1582 }
1583 
1584 // Update distributions list objects from new run models
1586 {
1587  distros.clear();
1588 
1589  for ( int ii = 0; ii < aDescrs.count(); ii++ )
1590  {
1591  QString mrun = aDescrs[ii].section( "\t", 0, 0 );
1592  QString mgid = aDescrs[ii].section( "\t", 1, 1 );
1593  QString mdes = aDescrs[ii].section( "\t", 2, 2 );
1594  QString ddes = aDescrs[ii].section( "\t", 3, 3 );
1595 
1596  DistrDesc dd;
1597  dd.runID = mrun;
1598  dd.mGUID = mgid;
1599  dd.mdescr = mdes;
1600  dd.ddescr = ddes;
1601  dd.iters = mdes.contains( "-MC_" ) ? 1 : 0;
1602  if ( dd.iters != 0 && ! mdes.contains( "_mcN" ) ) continue;
1603  if ( distro_by_mguid( mgid ) >= 0 ) continue;
1604 
1605  dd.xvals.clear();
1606  dd.yvals.clear();
1607 
1608  distros << dd;
1609  }
1610 
1611  qSort( distros );
1612 
1613  return;
1614 }
1615 
1616 // Update Distributions list when a method check box is changed
1618 {
1619  if ( state == Qt::Unchecked )
1620  ck_dtall->setChecked( false );
1621 
1623 }
1624 
1625 // Update Distributions list when the All method check box is changed
1627 {
1628  if ( state == Qt::Checked )
1629  {
1630  ck_2dsa ->setChecked( ck_2dsa ->isEnabled() );
1631  ck_2dsamc ->setChecked( ck_2dsamc ->isEnabled() );
1632  ck_2dsamw ->setChecked( ck_2dsamw ->isEnabled() );
1633  ck_2dsamcmw->setChecked( ck_2dsamcmw->isEnabled() );
1634  ck_2dsagl ->setChecked( ck_2dsagl ->isEnabled() );
1635  ck_2dsaglmc->setChecked( ck_2dsaglmc->isEnabled() );
1636  ck_2dsacg ->setChecked( ck_2dsacg ->isEnabled() );
1637  ck_2dsacgmc->setChecked( ck_2dsacgmc->isEnabled() );
1638  ck_2dsafm ->setChecked( ck_2dsafm ->isEnabled() );
1639  ck_ga ->setChecked( ck_ga ->isEnabled() );
1640  ck_gamc ->setChecked( ck_gamc ->isEnabled() );
1641  ck_gamw ->setChecked( ck_gamw ->isEnabled() );
1642  ck_gamcmw ->setChecked( ck_gamcmw ->isEnabled() );
1643  ck_gagl ->setChecked( ck_gagl ->isEnabled() );
1644  ck_gaglmc ->setChecked( ck_gaglmc ->isEnabled() );
1645  ck_pcsais ->setChecked( ck_pcsais ->isEnabled() );
1646  ck_pcsasl ->setChecked( ck_pcsasl ->isEnabled() );
1647  ck_pcsads ->setChecked( ck_pcsads ->isEnabled() );
1648  ck_pcsahl ->setChecked( ck_pcsahl ->isEnabled() );
1649  ck_pcsaismc->setChecked( ck_pcsaismc->isEnabled() );
1650  ck_pcsaslmc->setChecked( ck_pcsaslmc->isEnabled() );
1651  ck_pcsadsmc->setChecked( ck_pcsadsmc->isEnabled() );
1652  ck_pcsahlmc->setChecked( ck_pcsahlmc->isEnabled() );
1653  ck_pcsaistr->setChecked( ck_pcsaistr->isEnabled() );
1654  ck_pcsasltr->setChecked( ck_pcsasltr->isEnabled() );
1655  ck_pcsadstr->setChecked( ck_pcsadstr->isEnabled() );
1656  ck_pcsahltr->setChecked( ck_pcsahltr->isEnabled() );
1657  ck_pcsa2o ->setChecked( ck_pcsa2o ->isEnabled() );
1658  ck_pcsa2omc->setChecked( ck_pcsa2omc->isEnabled() );
1659  ck_pcsa2otr->setChecked( ck_pcsa2otr->isEnabled() );
1660  ck_dmga ->setChecked( ck_dmga ->isEnabled() );
1661  ck_dmgamc ->setChecked( ck_dmgamc ->isEnabled() );
1662  ck_dmgara ->setChecked( ck_dmgara ->isEnabled() );
1663  ck_dmgaramc->setChecked( ck_dmgaramc->isEnabled() );
1664  ck_dmgagl ->setChecked( ck_dmgagl ->isEnabled() );
1665  ck_dmgaglmc->setChecked( ck_dmgaglmc->isEnabled() );
1666  }
1667 
1669 }
1670 
1671 // Change the contents of the distributions list based on method filtering
1673 {
1674  runid_select( lw_runids->currentRow() );
1675 }
1676 
1677 // React to a change in the X type of plots
1678 void US_DDistr_Combine::changedPlotX( bool on_state )
1679 {
1680  if ( ! on_state ) return;
1681 
1682 DbgLv(1) << "changedPlotX" << on_state;
1683  bool x_is_sw = rb_pltsw ->isChecked();
1684  bool x_is_MW = rb_pltMW ->isChecked();
1685  bool x_is_Dw = rb_pltDw ->isChecked();
1686  bool x_is_ff0 = rb_pltff0->isChecked();
1687  bool x_is_vb = rb_pltvb ->isChecked();
1688  bool x_is_MWl = rb_pltMWl->isChecked();
1689  xtype = 0;
1690 
1691  if ( x_is_sw )
1692  {
1693 DbgLv(1) << " PX=Sed.Coeff";
1694  xtype = 0;
1695  }
1696 
1697  else if ( x_is_MW )
1698  {
1699 DbgLv(1) << " PX=Molec.Wt.";
1700  xtype = 1;
1701  }
1702 
1703  else if ( x_is_Dw )
1704  {
1705 DbgLv(1) << " PX=Diff.Coeff";
1706  xtype = 2;
1707  }
1708 
1709  else if ( x_is_ff0 )
1710  {
1711 DbgLv(1) << " PX=f/f0";
1712  xtype = 3;
1713  }
1714 
1715  else if ( x_is_vb )
1716  {
1717 DbgLv(1) << " PX=Vbar";
1718  xtype = 4;
1719  }
1720 
1721  else if ( x_is_MWl )
1722  {
1723 DbgLv(1) << " PX=Molec.Wt.log";
1724  xtype = 5;
1725  }
1726 
1727  int npdis = pdistrs.size();
1728  if ( npdis > 0 )
1729  { // Re-do plot distros to account for X-type change
1730  QList< DistrDesc > wdistros;
1731  DistrDesc ddist;
1732  DistrDesc* pddist;
1733 
1734  for ( int ii = 0; ii < npdis; ii++ )
1735  { // Build rudimentary plot distros without value arrays
1736  pddist = &pdistrs[ ii ];
1737  ddist.runID = pddist->runID;
1738  ddist.mGUID = pddist->mGUID;
1739  ddist.mdescr = pddist->mdescr;
1740  ddist.iters = pddist->iters;
1741  ddist.xtype = xtype;
1742  ddist.model = pddist->model;
1743  ddist.ddescr = pddist->ddescr;
1744 
1745  wdistros << ddist;
1746  }
1747 
1748  pdistrs.clear();
1749  pdisIDs.clear();
1750 
1751  for ( int ii = 0; ii < npdis; ii++ )
1752  {
1753  pddist = &wdistros[ ii ];
1754  fill_in_desc( *pddist, ii );
1755 
1756  pdistrs << *pddist;
1757  pdisIDs << distribID( pddist->mdescr, pddist->ddescr );
1758  }
1759 
1760  le_plxmin->disconnect();
1761  le_plxmin->disconnect();
1762  le_plxmin->setText( "0" );
1763  le_plxmax->setText( "0" );
1764  connect( le_plxmin, SIGNAL( editingFinished( ) ),
1765  this, SLOT( envvalChange( ) ) );
1766  connect( le_plxmax, SIGNAL( editingFinished( ) ),
1767  this, SLOT( envvalChange( ) ) );
1768 
1769  plot_data();
1770  }
1771 }
1772 
1773 // Change the contents of the distributions list based on list type change
1775 {
1776  if ( lw_runids->count() > 0 && lw_models->count() > 0 )
1777  {
1779 
1780  reset_plot();
1781  }
1782 }
1783 
1784 // Determine if two values are functionally equivalent within a given epsilon
1785 bool US_DDistr_Combine::equivalent( double aa, double bb, double eps )
1786 {
1787  double dd = ( aa != 0.0 ) ? aa : ( bb != 0.0 ? bb : 1.0 );
1788  return ( ( qAbs( aa - bb ) / dd ) <= eps );
1789 }
1790 
1791 // Generate envelope data
1793  QVector< double >& xvals, QVector< double >& yvals,
1794  QVector< double >& xenvs, QVector< double >& yenvs )
1795 {
1796  int arrsize = 300;
1797  int vCount = xvals.size();
1798  double min_xval = 1.0e+50;
1799  double max_xval = -min_xval;
1800  double con_sum = 0.0;
1801  double env_sum = 0.0;
1802  double* xv = xvals.data();
1803  double* yv = yvals.data();
1804 
1805  for ( int jj = 0; jj < vCount; jj++ )
1806  { // Get min,max of x values (e.g., sedimentation coefficients)
1807  max_xval = qMax( max_xval, xv[ jj ] );
1808  min_xval = qMin( min_xval, xv[ jj ] );
1809  con_sum += yv[ jj ]; // Accumulate total concentration
1810  }
1811 
1812  // Calculate values based on range
1813  bool min_neg = ( min_xval < 0.0 );
1814  double rng_xval = max_xval - min_xval;
1815  double xval_pad = rng_xval * 0.1;
1816  min_xval = min_xval - xval_pad;
1817  min_xval = min_neg ? min_xval : qMax( 0.0, min_xval );
1818  //max_xval = min_xval + rng_xval;
1819  max_xval = max_xval + xval_pad;
1820  double minx = le_plxmin->text().toDouble();
1821  double maxx = le_plxmax->text().toDouble();
1822  min_xval = ( minx != 0.0 ) ? minx : min_xval;
1823  max_xval = ( maxx != 0.0 ) ? maxx : max_xval;
1824  rng_xval = max_xval - min_xval;
1825 
1826  // Initialize envelope arrays
1827  xenvs.fill( 0.0, arrsize );
1828  yenvs.fill( 0.0, arrsize );
1829  double* xe = xenvs.data();
1830  double* ye = yenvs.data();
1831  double xinc = rng_xval / (double)( arrsize - 1 );
1832 DbgLv(1) << "ED: rng_xval arrsize xinc" << rng_xval << arrsize << xinc;
1833 
1834  for ( int jj = 0; jj < arrsize; jj++ )
1835  { // Initialize envelope values
1836  xe[ jj ] = min_xval + xinc * (double)( jj );
1837  ye[ jj ] = 0.0;
1838  }
1839 
1840  // Populate envelope Ys with gaussian sums
1841  double pisqr = sqrt( M_PI * 2.0 );
1842  double sigma = ct_sigma->value();
1843  sigma = qMax( 0.0001, sigma );
1844  double xterm = 1.0 / ( sigma * rng_xval );
1845  double zterm = 1.0 / ( sigma * pisqr );
1846 
1847  for ( int kk = 0; kk < arrsize; kk++ )
1848  { // Loop to compute envelope grid Y values
1849  double xval_env = xe[ kk ]; // Envelope X value
1850  double yval_env = 0.0; // Initial envelope Y value
1851 
1852  for ( int jj = 0; jj < vCount; jj++ )
1853  { // Accumulate Gaussian Y's from each solute
1854  double xval_sol = xv[ jj ]; // Solute X value
1855  double yval_sol = yv[ jj ]; // Solute Y value
1856 
1857  double xdiff = sq( ( xval_sol - xval_env ) * xterm );
1858  double yfac = exp( -0.5 * xdiff ) * zterm;
1859  yval_env += ( yfac * yval_sol ); // Sum envelope Y value
1860  }
1861 
1862  ye[ kk ] = yval_env; // Store envelope Y value
1863  env_sum += ye[ kk ]; // Build envelope sum
1864  }
1865 
1866  double scale = con_sum / env_sum; // Normalizing scale factor
1867 DbgLv(1) << "ED: csum esum scale " << con_sum << env_sum << scale;
1868 
1869 env_sum=0.0;
1870 double yemx=-1e+30;
1871 double xemx=-1e+30;
1872  for ( int kk = 0; kk < arrsize; kk++ )
1873  { // Normalize Y values so integral is equal to total concentration
1874  ye[ kk ] *= scale;
1875 if(ye[kk]>yemx) { yemx=ye[kk]; xemx=xe[kk]; }
1876 env_sum+=ye[kk];
1877  }
1878 DbgLv(1) << "ED: Final esum" << env_sum << "csum" << con_sum
1879  << "xemx yemx" << xemx << yemx
1880  << "sigma vcount" << sigma << vCount;
1881 
1882  return arrsize; // Return size of arrays
1883 }
1884 
1885 // Slot for change in sigma value or plot min,max
1887 {
1888  QString pmintxt = le_plxmin->text();
1889  QString pmaxtxt = le_plxmax->text();
1890 
1891  // Plot data with changed sigma
1892  plot_data();
1893 
1894  le_plxmin->disconnect();
1895  le_plxmax->disconnect();
1896  le_plxmin->setText( pmintxt );
1897  le_plxmax->setText( pmaxtxt );
1898  connect( le_plxmin, SIGNAL( editingFinished( ) ),
1899  this, SLOT( envvalChange( ) ) );
1900  connect( le_plxmax, SIGNAL( editingFinished( ) ),
1901  this, SLOT( envvalChange( ) ) );
1902 }
1903