Fixed text file permissions
[snark14.git] / tools / Display / chooseYVar.cpp
1 /** @file chooseYVar.cpp
2     @package snark14Display
3     @author Bruno M. Carvalho and Deniz Sarioz
4     licensed under (open-source) QPL v1.0
5     which accompanies this distribution in the file QPL
6  */
7
8 #include "chooseYVar.hpp"
9 #include "SnarkDisplay.hpp"
10 #include "displaylines.hpp"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14
15 #define EPSILON 0.00000001
16
17 /** 
18  *  Constructs a chooseYVarWindow which is a child of 'parent', with the 
19  *  name 'name' and widget flags set to 'fl', initial topleft position to (x,y)
20  *
21  *  The dialog will by default be modeless, unless you set 'modal' to
22  *  TRUE to construct a modal dialog.
23  */
24 chooseYVarWindow::chooseYVarWindow(QWidget* parent, const char* name, bool modal, WFlags fl, int x, int y)
25 : QDialog(parent, name, modal, fl) {
26     QPoint topleft;
27         static const int WINWIDTH = 300;
28         static const int WINHEIGHT = 280;
29     if (!name)
30         setName("selectEvalExecutionsWindow");
31         resize( WINWIDTH, WINHEIGHT );
32     // setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, sizePolicy().hasHeightForWidth() ) );
33         setMinimumSize( QSize( WINWIDTH, WINHEIGHT ) );
34 //        setMaximumSize( QSize( WINWIDTH, WINHEIGHT ) );
35     setCaption(tr("Select Y Var to plot from selected Evaluate Executions"));
36     topleft.setX(x);
37     topleft.setY(y);
38     this->move(topleft);
39
40     QBoxLayout *topLayout = new QVBoxLayout(this);
41 //    topLayout.setDirection(QBoxLayout::TopToBottom);
42     QBoxLayout *yaxisbuttonLayout = new QVBoxLayout(topLayout);
43     QBoxLayout *colorbuttonLayout = new QVBoxLayout(topLayout);
44
45     // ain't broke: don't fix it.
46     yaxisbuttongroup = new QButtonGroup(this, "yaxisbuttongroup");
47     yaxisbuttongroup->setTitle(tr("Y Axis"));
48     yaxisbuttongroup->setAlignment(int( QButtonGroup::AlignHCenter));
49     globalbutton = new QRadioButton(yaxisbuttongroup, "globalbutton");
50     globalbutton->setGeometry(QRect(10, 20, 140, 30));
51     globalbutton->setText(tr("Global"));
52     globalbutton->setChecked(false);
53     if (!myEES.selectionHasGlobal())
54         globalbutton->setEnabled(false); // can't click it
55     QObject::connect(globalbutton, SIGNAL(clicked()), this, SLOT(activateGlobalErrors()));
56
57     globalerrors = new QComboBox(yaxisbuttongroup, "globalerrors");
58     globalerrors->setGeometry(QRect(150, 20, 140, 30));
59     globalerrors->setEnabled(false);
60     // it seems a bit idiosyncratic to pass int as a parameter, but it seems the only way
61     QObject::connect(globalerrors, SIGNAL(activated(int)), this, SLOT(maybeGetCalculatedExtrema()));
62
63     pointbutton = new QRadioButton(yaxisbuttongroup, "pointbutton");
64     pointbutton->setGeometry(QRect(10, 50, 140, 30));
65     pointbutton->setText(tr("Point-by-point"));
66     pointbutton->setChecked(false);
67     if (!myEES.selectionHasPBP()) {
68         pointbutton->setEnabled(false); // can't click it
69     }
70     QObject::connect(pointbutton, SIGNAL(clicked()), this, SLOT(activatePointErrors()));
71     pointerrors = new QComboBox(yaxisbuttongroup, "pointerrors");
72     pointerrors->setGeometry(QRect(150, 55, 140, 30));
73     pointerrors->setEnabled(false);
74     QObject::connect(pointerrors, SIGNAL(activated(int)), this, SLOT(maybeGetCalculatedExtrema()));
75
76     yaxisbuttonLayout->addWidget(yaxisbuttongroup);
77
78
79     // jk 1/13/2009 adding grayScale option for graphs
80     // jklukowska 6/7/2009 modified to be radio button with option of either
81     // color or grayscale
82     colorbuttongroup = new QButtonGroup(this, "colorbuttongroup");
83     colorbuttongroup->setTitle(tr("Draw graphs in "));
84     colorbuttongroup->setAlignment(int( QButtonGroup::AlignHCenter));
85     grayScaleButton = new QRadioButton(colorbuttongroup, "grayScaleButton");
86     grayScaleButton->setGeometry(QRect(10, 15, 130, 20));
87     grayScaleButton->setText(tr(" grayscale"));
88     grayScaleButton->setEnabled(true);
89     grayScaleButton->setChecked(false);
90     colorButton = new QRadioButton(colorbuttongroup, "colorButton");
91     colorButton->setGeometry(QRect(160, 15, 130, 20));
92     colorButton->setText(tr(" color"));
93     colorButton->setEnabled(true);
94     colorButton->setChecked(true);
95     colorbuttonLayout->addWidget(colorbuttongroup);
96
97     QString* sameLabel = new QString("Use same extrema for all evaluate executions");
98     sameExtremaForAllCheckBox = new QCheckBox(*sameLabel, this, "sameExtrema");
99     sameExtremaForAllCheckBox->setTristate(false); // don't want a tristate button
100     sameExtremaForAllCheckBox->setEnabled(true);
101     sameExtremaForAllCheckBox->setChecked(true);
102     topLayout->addWidget(sameExtremaForAllCheckBox);
103     QObject::connect(sameExtremaForAllCheckBox, SIGNAL(clicked()), this, SLOT(sameExtremaClicked()));
104
105     minx = new QLineEdit(this, "minx");
106     maxx = new QLineEdit(this, "maxx");
107     miny = new QLineEdit(this, "miny");
108     maxy = new QLineEdit(this, "maxy");
109
110     deactivateExtremaFields();
111
112     QBoxLayout* x_extrema_layout = new QHBoxLayout(topLayout);
113     minxlabel = new QLabel(this, "minxlabel");
114     minxlabel->setText(tr("  Min Iter:"));
115     maxxlabel = new QLabel(this, "maxxlabel");
116     maxxlabel->setText(tr("  Max Iter:"));
117     x_extrema_layout->addWidget(minxlabel);
118     x_extrema_layout->addWidget(minx);
119     x_extrema_layout->addWidget(maxxlabel);
120     x_extrema_layout->addWidget(maxx);
121
122     QBoxLayout* y_extrema_layout = new QHBoxLayout(topLayout);
123     minylabel = new QLabel(this, "minxlabel");
124     minylabel->setText(tr("  Min Y:"));
125     maxylabel = new QLabel(this, "maxxlabel");
126     maxylabel->setText(tr("  Max Y:"));
127     y_extrema_layout->addWidget(minylabel);
128     y_extrema_layout->addWidget(miny);
129     y_extrema_layout->addWidget(maxylabel);
130     y_extrema_layout->addWidget(maxy);
131
132
133     proceedbutton = new QPushButton(this, "proceedbutton");
134     proceedbutton->setText(tr("Proceed"));
135     proceedbutton->setEnabled(false);
136     QObject::connect(proceedbutton, SIGNAL(clicked()), this, SLOT(proceed()));
137     topLayout->addWidget(proceedbutton);
138
139     closebutton = new QPushButton(this, "closebutton");
140     closebutton->setText(tr("Close Window"));
141     QObject::connect(closebutton, SIGNAL(clicked()), this, SLOT(closeWindow()));
142
143     topLayout->addWidget(closebutton);
144     topLayout->activate();
145 }
146
147 /**  
148  *  Destroys the object and frees any allocated resources
149  */
150 chooseYVarWindow::~chooseYVarWindow() {
151     // no need to delete child widgets, Qt does it all for us
152 }
153
154 void chooseYVarWindow::closeWindow() {
155     //  accept();
156     reject();
157 }
158
159 void chooseYVarWindow::closeEvent(QCloseEvent * e) {
160     e->accept();
161 }
162
163 /** 
164 @param void
165 @author Bruno M. Carvalho , Deniz Sarioz
166 @version 1.1 */
167 void chooseYVarWindow::activateGlobalErrors() {
168     pointerrors->setEnabled(false);
169     if (myEES.selectionHasGlobal()) {
170         proceedbutton->setEnabled(true);
171         globalerrors->clear();
172         globalerrors->insertItem("Average", -1);
173         globalerrors->insertItem("Distance", -1);
174         globalerrors->insertItem("Relative Error", -1);
175         globalerrors->insertItem("Variance", -1);
176         globalerrors->insertItem("Std. Deviation", -1);
177         if (myEES.selectionHasResidual()) {
178             globalerrors->insertItem("Residual", -1);
179         }
180         if (myEES.selectionHasKullback()) {
181             globalerrors->insertItem("KL Distance", -1);
182         }
183         globalerrors->setEnabled(true);
184         maybeGetCalculatedExtrema();
185     }
186 }
187
188 /** 
189 @param void
190 @author Bruno M. Carvalho , Deniz Sarioz
191 @version 1.1 */
192 void chooseYVarWindow::activatePointErrors() {
193     globalerrors->setEnabled(false);
194     if (myEES.selectionHasPBP()) {
195         proceedbutton->setEnabled(true);
196         pointerrors->clear();
197         for (unsigned idx = 0; idx < myEES.get_num_Es(); idx++) {
198             QString elabel(tr("e(%1)").arg(idx));
199             // amazingly enough, this is parsed correctly.
200             pointerrors->insertItem(elabel, -1);
201         }
202         pointerrors->setEnabled(true);
203         maybeGetCalculatedExtrema();
204     }
205 }
206
207 void chooseYVarWindow::maybeGetCalculatedExtrema() {
208     if (sameExtremaForAllCheckBox->isChecked())
209         getCalculatedExtrema();
210 }
211
212 //  int chooseYVarWindow::getYAxis() { return 1; }
213 //  int chooseYVarWindow::getMinX() { return 1; }
214 //  int chooseYVarWindow::getMaxX() { return 1; }
215 //  double chooseYVarWindow::getMinY() { return 1.0; }
216 //  double chooseYVarWindow::getMaxY() { return 1.0; }
217
218 void chooseYVarWindow::sameExtremaClicked() {
219     if (sameExtremaForAllCheckBox->isChecked()) {
220         //   std::cout << "sameExtrema CheckBox is checked." << std::endl;
221         getCalculatedExtrema();
222     } else {
223         deactivateExtremaFields();
224         //  std::cout << "sameExtrema CheckBox is unchecked." << std::endl;
225     }
226 }
227
228 void chooseYVarWindow::activateExtremaFields() {
229     minx->setEnabled(true);
230     maxx->setEnabled(true);
231     miny->setEnabled(true);
232     maxy->setEnabled(true);
233 }
234
235 void chooseYVarWindow::deactivateExtremaFields() {
236     minx->clear();
237     maxx->clear();
238     miny->clear();
239     maxy->clear();
240     minx->setEnabled(false);
241     maxx->setEnabled(false);
242     miny->setEnabled(false);
243     maxy->setEnabled(false);
244 }
245
246 /** getCalculatedExtrema fetches from myEES the extrema of iteration and y-var
247     over entire evaluate executions selection
248     also reads in selection...
249  */
250 void chooseYVarWindow::getCalculatedExtrema() {
251     if (globalerrors->isEnabled()) {
252         /// std::cout << "getting Calculated Extrema for some global Yvar" << std::endl;
253         activateExtremaFields();
254         minx->setText(tr("%1") . arg(myEES.getMinIterViaGlobal()));
255         maxx->setText(tr("%1") . arg(myEES.getMaxIterViaGlobal()));
256         int idx = globalerrors->currentItem();
257         this->globY = static_cast<globalYVar_t> (idx);
258         miny->setText(tr("%1") . arg(myEES.getMinYGlobal(this->globY)));
259         maxy->setText(tr("%1") . arg(myEES.getMaxYGlobal(this->globY)));
260     } else if (pointerrors->isEnabled()) {
261         /// std::cout << "getting Calculated Extrema for some PBP Yvar" << std::endl;
262         activateExtremaFields();
263         minx->setText(tr("%1") . arg(myEES.getMinIterViaPBP()));
264         maxx->setText(tr("%1") . arg(myEES.getMaxIterViaPBP()));
265         int idx = pointerrors->currentItem();
266         // a minor hack
267         this->PBPY = static_cast<unsigned> (idx);
268         miny->setText(tr("%1") . arg(myEES.getMinYPBP(this->PBPY)));
269         maxy->setText(tr("%1") . arg(myEES.getMaxYPBP(this->PBPY)));
270     } else {
271         //  std::cout << "need to check either global or PBP" << std::endl;
272     }
273 }
274
275 /** Called when proceedbutton "Proceed" is clicked:
276     based on the sameExtremaForAllCheckBox state,
277     either spawns plots or new dialog boxes.
278     Does some checks before sending params to plots (no garbage out).
279 @param void
280 @author Bruno M. Carvalho
281 @version 1.0 */
282 void chooseYVarWindow::proceed() {
283     //  std::cout << "in chooseYVarWindow::proceed()" << std::endl;
284     bool complain = false;
285     if (sameExtremaForAllCheckBox->isChecked()) {
286         // attempt to call plot windows after error checking
287         bool ok = true;
288         int minXVal = minx->text().toInt(&ok);
289         if ((!ok) || (minXVal < 0)) complain = true; // allow minXVal to be 0
290         int maxXVal = maxx->text().toInt(&ok);
291         if (!ok) complain = true;
292         if (maxXVal <= 0) complain = true;
293         if (minXVal >= maxXVal) complain = true;
294         double minYVal = miny->text().toDouble(&ok);
295         if (!ok) complain = true;
296         double maxYVal = maxy->text().toDouble(&ok);
297         if (!ok) complain = true;
298         // allow negative values for minYVal, even though there are no negative ones in data
299         if (maxYVal <= 0) complain = true;
300         if (minYVal >= maxYVal) complain = true;
301         if (complain) {
302             std::cerr << "Invalid combination of X and Y parameters." << std::endl;
303         } else { // passed error checks
304             if (std::verbose >= 2) {
305                 std::cout << "Proceeding to plot with iter: [" << minXVal
306                         << "," << maxXVal << "]; y: [" << minYVal << ","
307                         << maxYVal << "], ";
308             }
309             if (pointerrors->isEnabled()) {
310                 if (std::verbose >= 2) {
311                     std::cout << "YVar PBP e " << (this->PBPY) << std::endl;
312                 }
313                 spawnPlots(true, minXVal, maxXVal, minYVal, maxYVal);
314             } else if (globalerrors->isEnabled()) {
315                 if (std::verbose >= 2) {
316                     std::cout << "YVar global " << (this->globY) << std::endl;
317                 }
318                 spawnPlots(false, minXVal, maxXVal, minYVal, maxYVal);
319             }
320         }
321     } else { // spawn individual dialog boxes for each evaluate execution
322         if (std::verbose >= 3) {
323             std::cout << "Spawning individual query boxes for parameters; ";
324         }
325         if (pointerrors->isEnabled()) {
326             (this->PBPY) = static_cast<unsigned> (pointerrors->currentItem());
327             if (std::verbose >= 2) {
328                 std::cout << "YVar is PBP e " << (this->PBPY) << std::endl;
329             }
330             spawnDialogs(true);
331         } else if (globalerrors->isEnabled()) {
332             (this->globY) = static_cast<globalYVar_t> (globalerrors->currentItem());
333             if (std::verbose >= 2) {
334                 std::cout << "YVar is global " << (this->globY) << std::endl;
335             }
336             spawnDialogs(false);
337         } else {
338             std::cerr << "meaningless state in proceed()" << std::endl;
339         }
340     }
341 } // --chooseYVarWindow::proceed()
342
343 /** ask the EES to plot itself based on these params
344  * ONLY to be called from proceed()
345  */
346 void chooseYVarWindow::spawnPlots(bool plotPBP, int minXVal, int maxXVal, double minYVal, double maxYVal) {
347     // but ONLY the selected evaluate executions'.
348     // EES does the plotting including spawning of windows... *this* window becomes their parent.
349     if (plotPBP) {
350         myEES.spawnAllPlotsPBP(this, this->PBPY, minXVal, maxXVal, minYVal, maxYVal, grayScaleButton->isChecked());
351     } else {
352         myEES.spawnAllPlotsGlob(this, this->globY, minXVal, maxXVal, minYVal, maxYVal, grayScaleButton->isChecked());
353         // displaylineswindow( QWidget* parent,  const char* name, QPixmap* pixmap, bool modal, WFlags fl , int 20, int 20 );
354     }
355 } // --chooseYVarWindow::spawnPlots()
356
357 /** ask the EES to spawn plotting range dialogs based on YVar selection
358  * ONLY to be called from proceed()
359  */
360 void chooseYVarWindow::spawnDialogs(bool plotPBP) {
361     if (std::verbose >= 2) {
362         std::cout << "in chooseYVarWindow::spawnDialogs()" << std::endl;
363     }
364     if (plotPBP) {
365         myEES.spawnDialogsPBP(this, this->PBPY);
366     } else {
367         myEES.spawnDialogsGlob(this, this->globY);
368     }
369 } // --chooseYVarWindow::spawnDialogs()
370
371
372 /*
373  Joanna Klukowska (added 2/2/2009)
374 */
375 bool chooseYVarWindow::isGrayScaleChecked() {
376     return (grayScaleButton->isChecked());
377 }