UltraScan III
us_noise_loader.cpp
Go to the documentation of this file.
1 
3 #include "us_noise_loader.h"
4 #include "us_editor_gui.h"
5 #include "us_settings.h"
6 #include "us_gui_settings.h"
7 
8 #include <qwt_legend.h>
9 
10 // constructor: load loader dialog
11 US_NoiseLoader::US_NoiseLoader( US_DB2* db, QStringList& mieGUIDs,
12  QStringList& nieGUIDs, US_Noise& ti_noise, US_Noise& ri_noise,
13  US_DataIO::EditedData* edata )
14  : US_WidgetsDialog( 0, 0 ), db( db ), mieGUIDs( mieGUIDs ),
15  nieGUIDs( nieGUIDs ), ti_noise( ti_noise ), ri_noise( ri_noise )
16 {
17  setWindowTitle( ( db == (US_DB2*) 0 ?
18  tr( "Noise Vector Local Disk Load" ) :
19  tr( "Noise Vector Database Load" ) ) );
20  setPalette( US_GuiSettings::frameColor() );
21 
22  mainLayout = new QVBoxLayout( this );
23  btnsLayout = new QHBoxLayout();
24  mainLayout->setSpacing ( 2 );
25  mainLayout->setContentsMargins( 2, 2, 2, 2 );
26 
27  QString hmsg = tr( "You may select multiple noise records.\n\n" )
28  + tr( "Click on a tree noise entry to add it\n" )
29  + tr( " to the list below of selected noise records.\n" )
30  + tr( "Click on a top-level entry to add all\n" )
31  + tr( " of its children to the selected list.\n" )
32  + tr( "Ctrl-click on multiple noise entries\n" )
33  + tr( " to add them to the selected list.\n\n" )
34  + tr( "Click the \"Load\" button to load selected noise\n" )
35  + tr( " or the \"Cancel\" button to select no noise.\n" )
36  + tr( "Click \"Details\" for noise entry details." );
37 
38  QLabel* lb_noises = us_banner( hmsg );
39  lb_noises->setAlignment( Qt::AlignVCenter | Qt::AlignLeft );
40 
41  QLabel* lb_selects = us_banner( "Selected Noise Vectors" );
42  lb_selects->setAlignment( Qt::AlignVCenter | Qt::AlignHCenter );
43 
45  QFontMetrics fm( font );
46  int fontHeight = fm.lineSpacing();
47 
48  tw_noises = new QTreeWidget( this );
49  tw_noises->setFrameStyle( QFrame::NoFrame );
50  tw_noises->setPalette( US_GuiSettings::editColor() );
51  tw_noises->setFont( font );
52  tw_noises->setSelectionMode( QAbstractItemView::ExtendedSelection );
53 
55  lw_selects->setMaximumHeight( fontHeight * 3 + 12 );
56 
57  mainLayout->addWidget( lb_noises );
58  mainLayout->addWidget( tw_noises );
59  mainLayout->addWidget( lb_selects );
60  mainLayout->addWidget( lw_selects );
61 
62  QPushButton* pb_detail = us_pushbutton( tr( "Details" ) );
63  QPushButton* pb_cancel = us_pushbutton( tr( "Cancel" ) );
64  QPushButton* pb_load = us_pushbutton( tr( "Load" ) );
65  btnsLayout->addWidget( pb_detail );
66  btnsLayout->addWidget( pb_cancel );
67  btnsLayout->addWidget( pb_load );
68  mainLayout->addLayout( btnsLayout );
69 
70  ti_noise.count = 0;
71  ri_noise.count = 0;
72 
73  // populate the tree widget
74  QTreeWidgetItem* twi_null = (QTreeWidgetItem*)0;
75  QString twtitle = QString( "Models-in-Edit / Noises-in-Model" );
76  QString mititle = QString( "Latest/Loaded Model" );
77  QList< QTreeWidgetItem* > items;
78  tw_noises->setColumnCount( 1 );
79  tw_noises->setHeaderLabel( twtitle );
80 
81  QTreeWidgetItem* twi_curr =
82  new QTreeWidgetItem( twi_null, QStringList( mititle ) );
83  items.append( twi_curr ); // first top-level item in tree
84 
85  for ( int ii = 1; ii < mieGUIDs.size(); ii++ )
86  { // complete models list for top level
87  mititle = QString().sprintf( "Model Sibling %4.4d", ii );
88  twi_curr = new QTreeWidgetItem( twi_null, QStringList( mititle ) );
89  items.append( twi_curr ); // other top-level items are model siblings
90  }
91 
92  tw_noises->addTopLevelItems( items ); // put the top level in tree GUI
93 
94  for ( int ii = 0; ii < nieGUIDs.size(); ii++ )
95  { // review noises-in-edit, adding children
96  QString nie = nieGUIDs.at( ii ); // noiseGUID:type:index in edit
97  QString typ = nie.section( ":", 1, 1 ); // type part ("ti" or "ri")
98  QString mdx = nie.section( ":", 2, 2 ); // model index part ("0001")
99  nie = typ + "_noise " + mdx; // list name ("ti_noise 0003")
100  int ndx = mdx.toInt(); // integral model index
101 
102  twi_curr = new QTreeWidgetItem( QStringList( nie ) );
103  items.at( ndx )->addChild( twi_curr ); // add as child of model "ndx"
104  }
105 
106  if ( nieGUIDs.at( 0 ).section( ":", 2, 2 ).toInt() == 0 )
107  { // expand the loaded model tree if present
108  tw_noises->expandItem( items.at( 0 ) );
109  }
110 
111  connect( tw_noises, SIGNAL( itemSelectionChanged() ),
112  this, SLOT( itemsSelected() ) );
113  connect( pb_detail, SIGNAL( clicked() ),
114  this, SLOT( view_details() ) );
115  connect( pb_cancel, SIGNAL( clicked() ),
116  this, SLOT( cancelled() ) );
117  connect( pb_load, SIGNAL( clicked() ),
118  this, SLOT( selected() ) );
119 
120  // Compute the OD range of the edited data
121  if ( edata != NULL )
122  {
123  int nscans = edata->scanCount();
124  int npoints = edata->pointCount();
125  double datmin = edata->value( 0, 0 );
126  double datmax = datmin;
127 
128  for ( int ii = 0; ii < nscans; ii++ )
129  {
130  for ( int jj = 0; jj < npoints; jj++ )
131  {
132  double datval = edata->value( ii, jj );
133  datmin = qMin( datmin, datval );
134  datmax = qMax( datmax, datval );
135  }
136  }
137 
138  darange = datmax - datmin;
139  }
140 
141  else
142  darange = 0.0;
143 }
144 
146 {
147  QList< QTreeWidgetItem* > selitems = tw_noises->selectedItems();
148  int nsels = selitems.size();
149  lw_selects->clear();
150 
151  if ( nsels == 0 )
152  return;
153 
154  for ( int ii = 0; ii < nsels; ii++ )
155  {
156  QTreeWidgetItem* item = selitems[ ii ];
157  QString itemtext = item->text( 0 );
158 
159  if ( itemtext.contains( "_noise" ) )
160  { // Select an individual noise
161  lw_selects->addItem( itemtext );
162  }
163 
164  else if ( itemtext.contains( "Model" ) )
165  { // Select all the noises associated with a model
166  for ( int jj = 0; jj < item->childCount(); jj++ )
167  {
168  lw_selects->addItem( item->child( jj )->text( 0 ) );
169  }
170  }
171  }
172 }
173 
174 // close with check of need to clear noises
176 {
177  if ( tw_noises )
178  {
179  tw_noises->clear();
180  }
181 
182  tw_noises = (QTreeWidget*)0;
183 
184  this->close();
185 }
186 
187 // close out after Cancel clicked
189 {
190  close_all();
191 }
192 
193 // close out after Load clicked: load noise(s)
195 {
196  bool isDB = ( db != (US_DB2*)0 ); // flag DB or Local
197  int nti = 0;
198  int nri = 0;
199  US_Noise t2_noise;
200 
201  for ( int ii = 0; ii < lw_selects->count(); ii++ )
202  { // browse select list
203  QString selntext = lw_selects->item( ii )->text();
204  QString snumtext = selntext.section( " ", 1, 1 );
205  QString styptext = selntext.left( 2 );
206  QString noisGUID = "";
207 
208  for ( int jj = 0; jj < nieGUIDs.size(); jj++ )
209  { // examine noises-in-edit list
210  QString nie = nieGUIDs.at( jj );
211  QString typ = nie.section( ":", 1, 1 );
212  QString mdx = nie.section( ":", 2, 2 );
213 
214  if ( typ == styptext && mdx == snumtext )
215  { // found the selected noise: break with its GUID
216  noisGUID = nie.section( ":", 0, 0 );
217  break;
218  }
219  }
220 
221  if ( styptext == "ti" )
222  {
223  if ( nti == 0 )
224  ti_noise.load( isDB, noisGUID, db ); // load ti noise
225 
226  else
227  {
228  t2_noise.load( isDB, noisGUID, db );
229  ti_noise.sum_noise( t2_noise, true ); // sum multiple ti noises
230  }
231 
232  nti++;
233  }
234 
235  else
236  {
237  if ( nri == 0 )
238  ri_noise.load( isDB, noisGUID, db ); // load ri noise
239 
240  else
241  {
242  t2_noise.load( isDB, noisGUID, db );
243  ri_noise.sum_noise( t2_noise, true ); // sum multiple ri noises
244  }
245 
246  nri++;
247  }
248  }
249 
250  // Verify that noise(s) values not beyond reasonable data range
251  if ( darange > 0.0 )
252  {
253  int nurnois = 0;
254 
255  if ( nti > 0 )
256  {
257  double noimin = ti_noise.values[ 0 ];
258  double noimax = noimin;
259 
260  for ( int ii = 0; ii < ti_noise.values.size(); ii++ )
261  {
262  double noival = ti_noise.values[ ii ];
263  noimin = qMin( noimin, noival );
264  noimax = qMax( noimax, noival );
265  }
266 
267  if ( ( noimax - noimin ) > darange ) nurnois++;
268  }
269 
270  if ( nri > 0 )
271  {
272  double noimin = ri_noise.values[ 0 ];
273  double noimax = noimin;
274 
275  for ( int ii = 0; ii < ri_noise.values.size(); ii++ )
276  {
277  double noival = ri_noise.values[ ii ];
278  noimin = qMin( noimin, noival );
279  noimax = qMax( noimax, noival );
280  }
281 
282  if ( ( noimax - noimin ) > darange ) nurnois++;
283  }
284 
285  if ( nurnois > 0 )
286  {
287  QString msg = tr(
288  "Noise values exceed the range of experimental data.<br/>"
289  "Do you still want to honor the current noise selection(s)?<br/>"
290  "<ul><li><b>Yes</b> to proceed, anyway, with selected noise;</li>"
291  "<li><b>No </b> to retry with a new noise selection></li></ul>" );
292  QMessageBox msgBox ( this );
293  msgBox.setWindowTitle ( tr( "Noise Value Problems" ) );
294  msgBox.setTextFormat ( Qt::RichText );
295  msgBox.setText ( msg );
296  msgBox.addButton ( QMessageBox::No );
297  msgBox.addButton ( QMessageBox::Yes );
298  msgBox.setDefaultButton( QMessageBox::Yes );
299 
300  if ( msgBox.exec() == QMessageBox::No )
301  {
302  ti_noise.values.clear();
303  ri_noise.values.clear();
304  return;
305  }
306  }
307  }
308 
309  close_all();
310 }
311 
312 // top up editor dialog with current noise details
314 {
315  US_Noise noise;
316  bool isDB = ( db != (US_DB2*)0 );
317  QString mtxt;
318 
319  // build noise details text
320  mtxt = tr( "All models derive from the common loaded Edit.\n"
321  "All noise vector records derive from the latest/loaded model\n"
322  " or from common-edit siblings of that model " )
323  + ( isDB ? tr( "in the database.\n" ) : tr( "on local disk.\n" ) )
324  + tr( "Details for noise vector records follow.\n" );
325 
326  for ( int ii = 0; ii < nieGUIDs.size(); ii++ )
327  { // add text for each noise vector entry
328  QString nie = nieGUIDs.at( ii );
329  QString typ = nie.section( ":", 1, 1 );
330  QString mdx = nie.section( ":", 2, 2 );
331  QString noisGUID = nie.section( ":", 0, 0 );
332  QString typedesc;
333 
334  if ( typ == "ti" )
335  typedesc = tr( "Time-Invariant" );
336 
337  else
338  typedesc = tr( "Radially-Invariant" );
339 
340  noise.load( isDB, noisGUID, db ); // load noise to get details
341 
342  mtxt += tr( "\nNoise record \"" ) + typ + "_noise " + mdx + "\"";
343 
344  if ( mdx.toInt() == 0 )
345  mtxt += tr( " (from Latest/Loaded Model):\n" );
346 
347  else
348  mtxt += tr( " (from Model Sibling):\n" );
349 
350  mtxt += tr( " Type: " ) + typedesc + "\n";
351  mtxt += tr( " Description: " ) + noise.description + "\n";
352  mtxt += tr( " Noise GUID: " ) + noise.noiseGUID + "\n";
353  mtxt += tr( " Model GUID: " ) + noise.modelGUID + "\n";
354  mtxt += tr( " Values Count: " )
355  + QString::number( noise.count ) + "\n";
356 
357  if ( typ == "ti" )
358  {
359  mtxt += tr( " Minimum Radius: " )
360  + QString::number( noise.minradius ) + "\n";
361  mtxt += tr( " Maximum Radius: " )
362  + QString::number( noise.maxradius ) + "\n";
363  }
364 
365  }
366 
367  // display details text
368  US_EditorGui* detaild = new US_EditorGui();
369  detaild->setWindowTitle( tr( "Noise Vector Details" ) );
370  detaild->move( this->pos() + QPoint( 200, 200 ) );
371  detaild->resize( 720, 560 );
372  detaild->editor->e->setFont( QFont("monospace",US_GuiSettings::fontSize()) );
373  detaild->editor->e->setText( mtxt );
374  detaild->exec();
375  qApp->processEvents();
376 }
377