Package client :: Package Dock :: Module Plotting
[hide private]
[frames] | no frames]

Source Code for Module client.Dock.Plotting

   1  import PyQt4.QtCore 
   2  import PyQt4.QtGui 
   3   
   4  import time 
   5   
   6  import Constants 
   7  import DataGuesser 
   8  import Widget 
   9  import Holders 
  10   
11 -class Gnuplot (Widget.DockWidget):
12 - def __init__ (self, layout, bridge):
13 self._type = "Plotting" 14 self._displayName = "Gnuplot" 15 self._displayIcon = PyQt4.QtGui.QIcon (Constants.ICON_DIR + "/plotting/plot.png") 16 self._description = "Simply fill one, or both, of the attribute holders. Clicking " + \ 17 "`Plot Data` will create a Gnuplot window on the cluster." 18 Widget.DockWidget.__init__ (self, layout, bridge)
19
20 - def _addDataSelection (self):
21 box = PyQt4.QtGui.QGroupBox ("Data Selection") 22 layout = PyQt4.QtGui.QVBoxLayout (box) 23 24 self._plotName = Constants.BTextField (layout, "Plot Title", "My Plot") 25 self._group = Holders.FreeHolderGroup (self._bridge, ["x", "y"]) 26 layout.addLayout (self._group.layout) 27 return box
28
29 - def _addCommands (self):
30 box = PyQt4.QtGui.QGroupBox ("Commands") 31 layout = PyQt4.QtGui.QHBoxLayout (box) 32 33 self.plotButton = Constants.BQPushButton ("Plot Data", layout) 34 self.plotButton.setDefault (True) 35 PyQt4.QtCore.QObject.connect (self.plotButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.plot) 36 37 self.clearButton = Constants.BQPushButton ("Clear", layout) 38 PyQt4.QtCore.QObject.connect (self.clearButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.clear) 39 40 return box
41
42 - def clear (self):
43 for holder in self._group._inList: 44 holder.clear () 45 self._plotName.setText ("My Plot")
46
47 - def guessDefaults (self):
48 guessList = [] 49 guessList.append (DataGuesser.GenerateRegExpFromName ("X")) 50 guessList.append (DataGuesser.GenerateRegExpFromName ("Y")) 51 DataGuesser.GuessAttributes (self, guessList)
52
53 - def DoubleClicked (self, attr = None):
54 if attr == None: 55 return 56 57 if attr.Type () == "ALIAS": 58 attr = attr._item 59 60 if attr.Type () == "ATTRIBUTE" or (attr.Type () == "VALUE" and \ 61 attr._type == "_basin.Attribute"): 62 for holder in self._group._inList: 63 if holder.SetItem (attr, clobber = False) == True: 64 return
65
66 - def plot (self):
67 if not ( self._bridge._connected == True and self._bridge._parallel == True): 68 self._bridge._statusBar.showTimed ("You need to be connected and in parallel mode!", STATUS_WAIT) 69 return False 70 71 accesses = self._group.getInAccesses (False) 72 if len (accesses) == 0: 73 self._bridge._statusBar.showTimed ("You must have at least one argument!", STATUS_WAIT) 74 return 75 76 attributes = "" 77 for attr in accesses: 78 attributes += attr + ", " 79 self._bridge._ipyShell.Command ("plot (" + attributes + "\"" + \ 80 str (self._plotName.displayText ()) + "\")") 81 self.clear ()
82 83
84 -class VisItPlot (Widget.DockWidget):
85 - def __init__ (self, layout, bridge):
86 self._visitModuleLoaded = bridge._importVisIt 87 88 self._type = "Plotting" 89 self._displayIcon = PyQt4.QtGui.QIcon (Constants.ICON_DIR + "/plotting/visit.png") 90 self._displayName = "VisIt" 91 92 if self._visitModuleLoaded: 93 self._description = "VisIt's python module has been loaded. Simply plot your data and the client will take care of connecting VisIt to the cluster and drawing the plot." 94 else: 95 self._description = "VisIt's python module was not found. You may expose your data here, but you will need to open VisIt connect to your cluster manually, and plot the data yourself." 96 97 self._visitStarted = False 98 Widget.DockWidget.__init__ (self, layout, bridge) 99 self.continuousButton.click () 100 101 self._exposesDiscrete = [[], []] 102 self._exposesContinuous = [[], []] 103 104 if self._visitModuleLoaded: 105 self._visit = VisItThread (bridge, self) 106 self._visitWindows = 0 107 self._visit.start ()
108
109 - def Update (self, discrete, discreteWindows, continuous, continuousWindows):
110 self._exposesDiscrete[0] = discrete 111 self._exposesDiscrete[1] = discreteWindows 112 self._exposesContinuous[0] = continuous 113 self._exposesContinuous[1] = continuousWindows
114
115 - def _addHeader (self):
116 layout = PyQt4.QtGui.QVBoxLayout () 117 headerLayout = Widget.DockWidget._addHeader (self) 118 layout.addLayout (headerLayout) 119 120 self._plotName = Constants.BTextField (layout, "Plot Title", "My Plot") 121 122 return layout
123
124 - def _addCommands (self):
125 box = PyQt4.QtGui.QGroupBox ("Commands") 126 layout = PyQt4.QtGui.QHBoxLayout (box) 127 128 if self._visitModuleLoaded: 129 self._commandExpose = Constants.BQPushButton ("Plot", layout) 130 else: 131 self._commandExpose = Constants.BQPushButton ("Expose", layout) 132 PyQt4.QtCore.QObject.connect (self._commandExpose, PyQt4.QtCore.SIGNAL ("clicked ()"), self.Expose) 133 134 if self._visitModuleLoaded: 135 #self._commandClose = Constants.BQPushButton ("Close VisIt", layout, False) 136 #PyQt4.QtCore.QObject.connect (self._commandClose, PyQt4.QtCore.SIGNAL ("clicked ()"), self.DeleteVisItThread) 137 138 self._commandManage = Constants.BQPushButton ("Manage Plots", layout, False) 139 PyQt4.QtCore.QObject.connect (self._commandManage, PyQt4.QtCore.SIGNAL ("clicked ()"), self.ManagePlots) 140 else: 141 commandLaunch = Constants.BQPushButton ("Launch", layout) 142 PyQt4.QtCore.QObject.connect (commandLaunch, PyQt4.QtCore.SIGNAL ("clicked ()"), self.LaunchVisIt) 143 144 commandClear = Constants.BQPushButton ("Clear", layout) 145 PyQt4.QtCore.QObject.connect (commandClear, PyQt4.QtCore.SIGNAL ("clicked ()"), self.clear) 146 147 return box
148
149 - def _addDataSelection (self):
150 self._continuousMode = self.createContinuousMode () 151 self._discreteMode = self.createDiscreteMode () 152 153 box = PyQt4.QtGui.QGroupBox ("Data Selection") 154 layout = PyQt4.QtGui.QHBoxLayout (box) 155 layout.addWidget (self._continuousMode) 156 layout.addWidget (self._discreteMode) 157 return box
158
159 - def _addModes (self):
160 box = PyQt4.QtGui.QGroupBox ("Modes") 161 layout = PyQt4.QtGui.QHBoxLayout (box) 162 163 self.continuousButton = PyQt4.QtGui.QRadioButton ("Continuous", self) 164 PyQt4.QtCore.QObject.connect (self.continuousButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.setContinuousMode) 165 layout.addWidget (self.continuousButton) 166 167 discreteButton = PyQt4.QtGui.QRadioButton ("Discrete", self) 168 PyQt4.QtCore.QObject.connect (discreteButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.setDiscreteMode) 169 layout.addWidget (discreteButton) 170 171 return box
172
173 - def _addOptions (self):
174 # No options needed if visit's python module isn't found 175 if self._visitModuleLoaded: 176 box = PyQt4.QtGui.QGroupBox ("Initial Options") 177 layout = PyQt4.QtGui.QHBoxLayout (box) 178 179 self.stereoCheck = PyQt4.QtGui.QCheckBox ("Stereo") 180 layout.addWidget (self.stereoCheck) 181 182 self.invertBgCheck = PyQt4.QtGui.QCheckBox ("Inverted BG") 183 layout.addWidget (self.invertBgCheck) 184 185 return box
186
187 - def guessDefaults (self):
188 guessList = [] 189 if self._continuousMode.isVisible () == True: 190 pass 191 elif self._discreteMode.isVisible () == True: 192 guessList.append (DataGuesser.GenerateRegExpFromName ("X")) 193 guessList.append (DataGuesser.GenerateRegExpFromName ("Y")) 194 guessList.append (DataGuesser.GenerateRegExpFromName ("Z")) 195 DataGuesser.GuessAttributes (self, guessList)
196
197 - def LaunchVisIt (self):
198 if self._bridge._connected and self._bridge._parallel: 199 self._bridge.makeLocal () 200 self._bridge._ipyShell.SilentCommand ("subprocess.Popen([\"visit\"])") 201 self._bridge.makeParallel ()
202
203 - def StartVisItThread (self):
204 # If this is the first expose, launch it (and check for stereo checkbox) 205 if not self._visit.launched (): 206 # launches it with the option of stereo viewing 207 stereo = False 208 if self.stereoCheck.checkState () == PyQt4.QtCore.Qt.Checked: 209 stereo = True 210 self.emit (PyQt4.QtCore.SIGNAL ("threadLaunch (PyQt_PyObject)"), stereo) 211 self._visitWindows = 1 212 213 if self.invertBgCheck.checkState () == PyQt4.QtCore.Qt.Checked: 214 self.emit (PyQt4.QtCore.SIGNAL ("threadInvertBackgroundColor ()")) 215 216 # meaningless to change this after launch, so don't let the user do it 217 self.stereoCheck.setEnabled (False) 218 self.invertBgCheck.setEnabled (False) 219 220 self._commandManage.setEnabled (True) 221 222 # connect to the host 223 self.emit (PyQt4.QtCore.SIGNAL ("threadOpenComputeEngine ()")) 224 225 self.emit (PyQt4.QtCore.SIGNAL ("threadOpenSimulation ()")) 226 return True 227 228 return False
229
230 - def DeleteVisItThread (self):
231 # No need to detroy the object if it hasn't been launched yet 232 if not self._visit.launched (): 233 self._bridge._statusBar.showTimed ("VisIt has not been started!", Constants.STATUS_WAIT) 234 return 235 236 self.emit (PyQt4.QtCore.SIGNAL ("threadClose ()")) 237 del (self._visit) 238 self._visit = VisItThread (self._bridge, self) 239 self._visitWindows = 0 240 self._visit.start () 241 242 self.stereoCheck.setEnabled (True) 243 self.invertBgCheck.setEnabled (True) 244 245 self._commandClose.setEnabled (False) 246 self._commandManage.setEnabled (False)
247
248 - def ManagePlots (self):
249 if not self._visit.launched (): 250 self._bridge._statusBar.showTimed ("VisIt has not been started!", Constants.STATUS_WAIT) 251 return 252 253 dialog = PyQt4.QtGui.QDialog () 254 dialog.setWindowIcon (self._displayIcon) 255 dialog.setWindowTitle ("VisIt Plot Manager") 256 mainLayout = PyQt4.QtGui.QVBoxLayout (dialog) 257 258 header = PyQt4.QtGui.QLabel ("<big><b>VisIt Plot Manager</b></big>") 259 header.setTextFormat (PyQt4.QtCore.Qt.RichText) 260 mainLayout.addWidget (header) 261 262 if len (self._exposesDiscrete[0]) > 0: 263 header = PyQt4.QtGui.QLabel ("<b>Discrete Plots</b>") 264 header.setTextFormat (PyQt4.QtCore.Qt.RichText) 265 mainLayout.addWidget (header) 266 267 for p in xrange (len (self._exposesDiscrete[0])): 268 layout = Constants.BQHBoxLayout (mainLayout) 269 label = PyQt4.QtGui.QLabel (self._exposesDiscrete[0][p]) 270 layout.addWidget (label) 271 combo = PyQt4.QtGui.QComboBox () 272 for i in xrange (16): 273 combo.addItem (str (i + 1)) 274 combo.setCurrentIndex (int (self._exposesDiscrete[1][p])) 275 layout.addWidget (combo) 276 277 if len (self._exposesContinuous[0]) > 0: 278 header = PyQt4.QtGui.QLabel ("<b>Continuous Plots</b>") 279 header.setTextFormat (PyQt4.QtCore.Qt.RichText) 280 mainLayout.addWidget (header) 281 282 for p in xrange (len (self._exposesContinuous[0])): 283 layout = Constants.BQHBoxLayout (mainLayout) 284 label = PyQt4.QtGui.QLabel (self._exposesContinuous[0][p]) 285 layout.addWidget (label) 286 combo = PyQt4.QtGui.QComboBox () 287 for i in xrange (16): 288 combo.addItem (str (i + 1)) 289 combo.setCurrentIndex (int (self._exposesContinuous[1][p])) 290 layout.addWidget (combo) 291 292 buttonLayout = Constants.BQHBoxLayout (mainLayout) 293 apply = Constants.BQPushButton ("Apply", buttonLayout) 294 close = Constants.BQPushButton ("Close", buttonLayout) 295 PyQt4.QtCore.QObject.connect (close, PyQt4.QtCore.SIGNAL ("clicked ()"), dialog.accept) 296 297 dialog.exec_ ()
298
299 - def StartVisIt (self):
300 if self._visitStarted == False: 301 self._visitStarted = True 302 result = self._bridge._ipyShell.Command ("visit_module_start ()") 303 if result.find ("rror") != -1: 304 self._bridge.Error ("BASIN_plotting.py", "VisitPlot", "StartVisIt")
305
306 - def CheckContext (self):
307 attribute = self._continuous._item._shellAccess 308 result = self._bridge._ipyShell.SilentCommand ("print \"\\n\" + str (type (" + attribute + \ 309 ".get_context ()))") 310 result = result.split ("\n")[3] 311 if result == "<class '_basin.Context'>": 312 return True 313 self._bridge._statusBar.showTimed ("This Attribute does not have a Context!", Constants.STATUS_WAIT) 314 return False
315
316 - def Expose (self):
317 if not ( self._bridge._connected == True and self._bridge._parallel == True): 318 return False 319 320 self.StartVisIt () 321 result = "" 322 323 # Continuous Mode Exposing 324 if self._continuousMode.isVisible () == True: 325 # Can't do this without a working context 326 if self.CheckContext (): 327 grid = self._continuous._item._shellAccess 328 context = grid + ".get_context ()" 329 nx = context + ".get_n_grid_points ()" 330 ll = context + ".get_LowerCorner ()" 331 ur = context + ".get_UpperCorner ()" 332 result = self._bridge._ipyShell.Command ("visit_expose_continuous (" + \ 333 ll + ", " + ur + ", " + nx + ", " + self._continuous._item._shellAccess + \ 334 ", \"" + str (self._plotName.text ()) + "\")") 335 336 # Discrete Mode Exposing 337 elif self._discreteMode.isVisible () == True: 338 attributes = self._discrete.getInAccesses (False) 339 weight = self._discreteWeight.getInAccesses (False) 340 341 weightCreated = False 342 # Use the weight supplied by the user 343 if len (weight) == 1: 344 weight = weight[0] 345 # No weight supplied, create a temporary one 346 else: 347 weightCreated = True 348 weight = "BASIN_TEMP_WEIGHT" 349 size = self._bridge._ipyShell.SilentCommand ("print \"\\n\" + str (" + attributes[0] + \ 350 ".size ())").split ("\n")[3] 351 self._bridge._ipyShell.Command ("BASIN_TEMP_WEIGHT = Attribute (" + size + ", 0.0)") 352 353 if len (attributes) == 3: 354 result = self._bridge._ipyShell.Command ("visit_expose_discrete (" + \ 355 attributes[0] + ", " + attributes[1] + ", " + attributes[2] + \ 356 ", " + weight + ", \"" + str (self._plotName.text ()) + "\")") 357 if len (attributes) == 2: 358 result = self._bridge._ipyShell.Command ("visit_expose_discrete (" + \ 359 attributes[0] + ", " + attributes[1] + \ 360 ", " + weight + ", \"" + str (self._plotName.text ()) + "\")") 361 # If you weren't given a weight, then you created one on the fly, so delete it 362 if weightCreated: 363 self._bridge._ipyShell.Command ("del (BASIN_TEMP_WEIGHT)") 364 365 if result.find ("rror") != -1: 366 self._bridge.Error ("BASIN_plotting.py", "VisItPlot", "Expose", result) 367 return
368
369 - def clearMode (self):
370 self._continuousMode.setVisible (False) 371 self._discreteMode.setVisible (False)
372
373 - def setContinuousMode (self):
374 self.clearMode () 375 self._continuousMode.setVisible (True) 376 self.guessDefaults ()
377
378 - def setDiscreteMode (self):
379 self.clearMode () 380 self._discreteMode.setVisible (True) 381 self.guessDefaults ()
382
383 - def createContinuousMode (self):
384 widget = PyQt4.QtGui.QWidget () 385 widget.setVisible (False) 386 layout = PyQt4.QtGui.QVBoxLayout (widget) 387 388 self._continuous = Holders.GenericInputHolder (self._bridge, layout, "Grid Attribute", \ 389 ["ATTRIBUTE"], ["_basin.Attribute"]) 390 PyQt4.QtCore.QObject.connect (self._continuous, PyQt4.QtCore.SIGNAL ("textChanged (const QString&)"), self.setPlotName) 391 392 return widget
393
394 - def createDiscreteMode (self):
395 widget = PyQt4.QtGui.QWidget () 396 widget.setVisible (False) 397 layout = PyQt4.QtGui.QVBoxLayout (widget) 398 399 self._discrete = Holders.FreeHolderGroup (self._bridge, ["x", "y", "z"]) 400 self._discreteWeight = Holders.FreeHolderGroup (self._bridge, ["weight"]) 401 PyQt4.QtCore.QObject.connect (self._discreteWeight._inList[0], PyQt4.QtCore.SIGNAL ("textChanged (const QString&)"), self.setPlotName) 402 403 layout.addLayout (self._discrete.layout) 404 layout.addLayout (self._discreteWeight.layout) 405 406 return widget
407
408 - def clear (self):
409 if self._continuousMode.isVisible () == True: 410 self._continuous.clear () 411 elif self._discreteMode.isVisible () == True: 412 self._discrete.clear () 413 for holder in self._discrete._inList: 414 holder.clear () 415 for holder in self._discreteWeight._inList: 416 holder.clear () 417 self._plotName.setText ("My Plot")
418
419 - def DoubleClicked (self, attr = None):
420 if attr == None: 421 return 422 423 if attr.Type () == "ALIAS": 424 attr = attr._item 425 426 if self._continuousMode.isVisible () == True: 427 if attr.Type () == "ATTRIBUTE" or (attr.Type () == "VALUE" and \ 428 attr._type == "_basin.Attribute"): 429 self._continuous.SetItem (attr, clobber = False) 430 elif self._discreteMode.isVisible () == True: 431 if attr.Type () == "ATTRIBUTE" or (attr.Type () == "VALUE" and \ 432 attr._type == "_basin.Attribute"): 433 for holder in self._discrete._inList: 434 if holder.SetItem (attr, clobber = False) == True: 435 return 436 for holder in self._discreteWeight._inList: 437 if holder.SetItem (attr, clobber = False) == True: 438 return
439
440 - def setPlotName (self, name):
441 self._plotName.setText (name)
442 443
444 -class PyLab (Widget.DockWidget):
445 - def __init__ (self, layout, bridge):
446 self._type = "Plotting" 447 self._displayName = "PyLab" 448 self._displayIcon = PyQt4.QtGui.QIcon (Constants.ICON_DEFAULT) 449 self._description = "To plot using pylab you simply have to fill in two pieces of data: " + \ 450 "The x and y components. They may either be a python list, or basin attribute, or " + \ 451 "any combination of the two. Please Note: by doing this plot you will completely " + \ 452 "stop any interaction with the client's interface until the plot is then closed." 453 Widget.DockWidget.__init__ (self, layout, bridge) 454 self.scatterButton.click ()
455
456 - def _addCommands (self):
457 box = PyQt4.QtGui.QGroupBox ("Commands") 458 layout = PyQt4.QtGui.QHBoxLayout (box) 459 460 self.plotButton = Constants.BQPushButton ("Plot Data", layout) 461 self.plotButton.setDefault (True) 462 PyQt4.QtCore.QObject.connect (self.plotButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.plot) 463 464 self.clearButton = Constants.BQPushButton ("Clear", layout) 465 PyQt4.QtCore.QObject.connect (self.clearButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.clear) 466 467 return box
468
469 - def _addModes (self):
470 box = PyQt4.QtGui.QGroupBox ("Modes") 471 layout = PyQt4.QtGui.QHBoxLayout (box) 472 473 self.scatterButton = PyQt4.QtGui.QRadioButton ("Scatter", self) 474 PyQt4.QtCore.QObject.connect (self.scatterButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.setScatterMode) 475 layout.addWidget (self.scatterButton) 476 477 contourButton = PyQt4.QtGui.QRadioButton ("Contour/Color", self) 478 PyQt4.QtCore.QObject.connect (contourButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.setContourMode) 479 layout.addWidget (contourButton) 480 481 histogramButton = PyQt4.QtGui.QRadioButton ("Histogram", self) 482 PyQt4.QtCore.QObject.connect (histogramButton, PyQt4.QtCore.SIGNAL ("clicked ()"), self.setHistogramMode) 483 layout.addWidget (histogramButton) 484 485 return box
486
487 - def _addOptions (self):
488 self._scatterOptions = self.createScatterOptions () 489 self._contourOptions = self.createContourOptions () 490 self._histogramOptions = self.createHistogramOptions () 491 492 box = PyQt4.QtGui.QGroupBox ("Options") 493 layout = PyQt4.QtGui.QHBoxLayout (box) 494 layout.addWidget (self._scatterOptions) 495 layout.addWidget (self._contourOptions) 496 layout.addWidget (self._histogramOptions) 497 return box
498
499 - def _addDataSelection (self):
500 self._scatterPlot = self.createScatterPlot () 501 self._contourPlot = self.createContourPlot () 502 self._histogramPlot = self.createHistogramPlot () 503 504 box = PyQt4.QtGui.QGroupBox ("Data Selection") 505 layout = PyQt4.QtGui.QHBoxLayout (box) 506 layout.addWidget (self._scatterPlot) 507 layout.addWidget (self._contourPlot) 508 layout.addWidget (self._histogramPlot) 509 return box
510
511 - def clearMode (self):
512 self._scatterPlot.setVisible (False) 513 self._scatterOptions.setVisible (False) 514 self._contourPlot.setVisible (False) 515 self._contourOptions.setVisible (False) 516 self._histogramPlot.setVisible (False) 517 self._histogramOptions.setVisible (False)
518
519 - def setScatterMode (self):
520 self.clearMode () 521 self._scatterPlot.setVisible (True) 522 self._scatterOptions.setVisible (True) 523 self.guessDefaults ()
524
525 - def setContourMode (self):
526 self.clearMode () 527 self._contourPlot.setVisible (True) 528 self._contourOptions.setVisible (True) 529 self.guessDefaults ()
530
531 - def setHistogramMode (self):
532 self.clearMode () 533 self._histogramPlot.setVisible (True) 534 self._histogramOptions.setVisible (True) 535 self.guessDefaults ()
536
537 - def createContourOptions (self):
538 box = PyQt4.QtGui.QWidget () 539 layout = PyQt4.QtGui.QVBoxLayout (box) 540 541 colorLayout = Constants.BQHBoxLayout (layout) 542 colorLabel = PyQt4.QtGui.QLabel ("Plot Colormap:") 543 colorLabel.setAlignment (PyQt4.QtCore.Qt.AlignVCenter | PyQt4.QtCore.Qt.AlignRight) 544 colorLayout.addWidget (colorLabel) 545 self.contourPlotColor = PyQt4.QtGui.QComboBox () 546 self.contourPlotColor.addItems (["gray", "autumn", "bone", "cool", "copper", "flag", "hot", "hsv", "jet", "pink", "prism", "spring", "summer", "winter", "spectral"]) 547 colorLayout.addWidget (self.contourPlotColor) 548 549 return box
550
551 - def createContourPlot (self):
552 box = PyQt4.QtGui.QWidget () 553 layout = PyQt4.QtGui.QVBoxLayout (box) 554 555 namesLayout = Constants.BQHBoxLayout (layout) 556 self._contourName = PyQt4.QtGui.QLineEdit ("My Contour Plot") 557 namesLayout.addWidget (PyQt4.QtGui.QLabel ("Plot Title:")) 558 namesLayout.addWidget (self._contourName) 559 560 dataLayout = Constants.BQVBoxLayout (layout) 561 562 self._zContour = Holders.GenericInputHolder (self._bridge, dataLayout, "z", \ 563 ["ATTRIBUTE"], ["_basin.Attribute", "pylab.array"]) 564 self._contourInputs = [self._zContour] 565 566 self._ContourSwitch = PyQt4.QtGui.QCheckBox("Show Contours") 567 self._ContourSwitch.setCheckState(PyQt4.QtCore.Qt.Checked); 568 self._ColorSwitch = PyQt4.QtGui.QCheckBox("Show Colorplot") 569 570 dataLayout.addWidget(self._ContourSwitch) 571 dataLayout.addWidget(self._ColorSwitch) 572 573 return box
574
575 - def createScatterOptions (self):
576 box = PyQt4.QtGui.QWidget () 577 layout = PyQt4.QtGui.QVBoxLayout (box) 578 579 colorLayout = Constants.BQHBoxLayout (layout) 580 colorLabel = PyQt4.QtGui.QLabel ("Plot Color:") 581 colorLabel.setAlignment (PyQt4.QtCore.Qt.AlignVCenter | PyQt4.QtCore.Qt.AlignRight) 582 colorLayout.addWidget (colorLabel) 583 self.scatterPlotColor = PyQt4.QtGui.QComboBox () 584 self.scatterPlotColor.addItem ("Cyan", PyQt4.QtCore.QVariant ("c")) 585 self.scatterPlotColor.addItem ("Magenta", PyQt4.QtCore.QVariant ("m")) 586 self.scatterPlotColor.addItem ("Yellow", PyQt4.QtCore.QVariant ("y")) 587 self.scatterPlotColor.addItem ("Black", PyQt4.QtCore.QVariant ("k")) 588 self.scatterPlotColor.addItem ("Red", PyQt4.QtCore.QVariant ("r")) 589 self.scatterPlotColor.addItem ("Green", PyQt4.QtCore.QVariant ("g")) 590 self.scatterPlotColor.addItem ("Blue", PyQt4.QtCore.QVariant ("b")) 591 colorLayout.addWidget (self.scatterPlotColor) 592 593 styleLayout = Constants.BQHBoxLayout (layout) 594 styleLabel = PyQt4.QtGui.QLabel ("Point Style:") 595 styleLabel.setAlignment (PyQt4.QtCore.Qt.AlignVCenter | PyQt4.QtCore.Qt.AlignRight) 596 styleLayout.addWidget (styleLabel) 597 self.scatterStyle = PyQt4.QtGui.QComboBox () 598 self.scatterStyle.addItem ("Plus", PyQt4.QtCore.QVariant ("+")) 599 self.scatterStyle.addItem ("Circle", PyQt4.QtCore.QVariant ("o")) 600 self.scatterStyle.addItem ("Dot", PyQt4.QtCore.QVariant (".")) 601 self.scatterStyle.addItem ("Square", PyQt4.QtCore.QVariant ("s")) 602 self.scatterStyle.addItem ("Cross", PyQt4.QtCore.QVariant ("x")) 603 self.scatterStyle.addItem ("Right-Triangle", PyQt4.QtCore.QVariant (">")) 604 self.scatterStyle.addItem ("Left-Triangle", PyQt4.QtCore.QVariant ("<")) 605 self.scatterStyle.addItem ("Up-Triangle", PyQt4.QtCore.QVariant ("^")) 606 self.scatterStyle.addItem ("Down-Triangle", PyQt4.QtCore.QVariant ("v")) 607 styleLayout.addWidget (self.scatterStyle) 608 609 return box
610
611 - def createHistogramOptions (self):
612 box = PyQt4.QtGui.QWidget () 613 layout = PyQt4.QtGui.QVBoxLayout (box) 614 return box
615
616 - def createHistogramPlot (self):
617 box = PyQt4.QtGui.QWidget () 618 layout = PyQt4.QtGui.QVBoxLayout (box) 619 620 namesLayout = Constants.BQHBoxLayout (layout) 621 self._histogramName = PyQt4.QtGui.QLineEdit ("My Histogram Plot") 622 namesLayout.addWidget (PyQt4.QtGui.QLabel ("Plot Title:")) 623 namesLayout.addWidget (self._histogramName) 624 625 dataLayout = Constants.BQVBoxLayout (layout) 626 self._dataHistogram = Holders.GenericInputHolder (self._bridge, dataLayout, "hist", \ 627 ["ATTRIBUTE"], ["_basin.Attribute", "list"]) 628 self._histogramInputs = [self._dataHistogram] 629 630 binsLayout = Constants.BQHBoxLayout (layout) 631 binsLabel = PyQt4.QtGui.QLabel ("Bins:") 632 binsLabel.setAlignment (PyQt4.QtCore.Qt.AlignVCenter | PyQt4.QtCore.Qt.AlignRight) 633 binsLayout.addWidget (binsLabel) 634 self._binsHistogram = PyQt4.QtGui.QSpinBox () 635 self._binsHistogram.setRange (1, 999999999) 636 binsLayout.addWidget (self._binsHistogram) 637 dataLayout.setAlignment (binsLayout, PyQt4.QtCore.Qt.AlignVCenter | PyQt4.QtCore.Qt.AlignLeft) 638 639 return box
640
641 - def createScatterPlot (self):
642 box = PyQt4.QtGui.QWidget () 643 layout = PyQt4.QtGui.QVBoxLayout (box) 644 645 namesLayout = Constants.BQHBoxLayout (layout) 646 self._scatterName = PyQt4.QtGui.QLineEdit ("My Scatter Plot") 647 namesLayout.addWidget (PyQt4.QtGui.QLabel ("Plot Title:")) 648 namesLayout.addWidget (self._scatterName) 649 650 dataLayout = Constants.BQVBoxLayout (layout) 651 self._xScatter = Holders.GenericInputHolder (self._bridge, dataLayout, "x", \ 652 ["ATTRIBUTE"], ["_basin.Attribute", "list"]) 653 self._yScatter = Holders.GenericInputHolder (self._bridge, dataLayout, "y", \ 654 ["ATTRIBUTE"], ["_basin.Attribute", "list"]) 655 self._scatterInputs = [self._xScatter, self._yScatter] 656 657 errorLayout = Constants.BQVBoxLayout (layout) 658 xerrorLayout = Constants.BQHBoxLayout (errorLayout) 659 xerrorSwitch = PyQt4.QtGui.QCheckBox ("x error:") 660 xerrorLayout.addWidget (xerrorSwitch) 661 self._xerror = PyQt4.QtGui.QDoubleSpinBox () 662 self._xerror.setEnabled (False) 663 self._xerror.setRange (0.0, 999999999.9) 664 xerrorLayout.addWidget (self._xerror) 665 PyQt4.QtCore.QObject.connect (xerrorSwitch, PyQt4.QtCore.SIGNAL ("stateChanged (int)"), self.toggleXError) 666 667 yerrorLayout = Constants.BQHBoxLayout (errorLayout) 668 yerrorSwitch = PyQt4.QtGui.QCheckBox ("y error:") 669 yerrorLayout.addWidget (yerrorSwitch) 670 self._yerror = PyQt4.QtGui.QDoubleSpinBox () 671 self._yerror.setEnabled (False) 672 self._yerror.setRange (0.0, 999999999.9) 673 yerrorLayout.addWidget (self._yerror) 674 PyQt4.QtCore.QObject.connect (yerrorSwitch, PyQt4.QtCore.SIGNAL ("stateChanged (int)"), self.toggleYError) 675 676 return box
677
678 - def toggleXError (self, val):
679 if val == 0: 680 self._xerror.setEnabled (False) 681 else: 682 self._xerror.setEnabled (True)
683
684 - def toggleYError (self, val):
685 if val == 0: 686 self._yerror.setEnabled (False) 687 else: 688 self._yerror.setEnabled (True)
689
690 - def DoubleClicked (self, attr = None):
691 if attr == None: 692 return 693 694 if attr.Type () == "ALIAS": 695 attr = attr._item 696 697 inputs = None 698 if self._scatterPlot.isVisible () == True: 699 inputs = self._scatterInputs 700 elif self._contourPlot.isVisible () == True: 701 inputs = self._contourInputs 702 elif self._histogramPlot.isVisible () == True: 703 inputs = self._histogramInputs 704 705 if attr.Type () == "ATTRIBUTE" or (attr.Type () == "VALUE" and \ 706 attr._type == "_basin.Attribute"): 707 for holder in inputs: 708 if holder.SetItem (attr, clobber = False) == True: 709 return 710 elif attr.Type () == "VALUE" and attr._type == "list": 711 for holder in inputs: 712 if holder.SetItem (attr, clobber = False) == True: 713 return
714
715 - def guessDefaults (self):
716 guessList = [] 717 718 if self._scatterPlot.isVisible () == True: 719 guessList.append (DataGuesser.GenerateRegExpFromName ("x")) 720 guessList.append (DataGuesser.GenerateRegExpFromName ("y")) 721 elif self._contourPlot.isVisible () == True: 722 guessList.append (DataGuesser.GenerateRegExpFromName ("x")) 723 guessList.append (DataGuesser.GenerateRegExpFromName ("y")) 724 guessList.append (DataGuesser.GenerateRegExpFromName ("z")) 725 elif self._histogramPlot.isVisible () == True: 726 guessList.append (DataGuesser.GenerateRegExpFromWord ("hist")) 727 DataGuesser.GuessAttributes (self, guessList)
728
729 - def plot (self):
730 """ 731 PyLab.plot (self) 732 733 This method will be called whenever the user clicks on the 734 button labeled 'Plot'. This method will only send a meta- 735 command to the ipython command line. Note that this command 736 isn't really a python command, but more of command that the 737 fake ipython shell is going to convert into a series of valid 738 python commands. 739 """ 740 if not ( self._bridge._connected == True and self._bridge._parallel == True): 741 self._bridge._statusBar.showTimed ("You need to be connected and in parallel mode!", STATUS_WAIT) 742 return False 743 if not self._bridge._importPylab: 744 self._bridge._statusBar.showTimed ("You need to install numpy and matplotlib!", STATUS_WAIT) 745 return False 746 747 inputs = None 748 if self._scatterPlot.isVisible () == True: 749 inputs = self._scatterInputs 750 elif self._contourPlot.isVisible () == True: 751 inputs = self._contourInputs 752 elif self._histogramPlot.isVisible () == True: 753 inputs = self._histogramInputs 754 755 names = [] 756 accesses = [] 757 for holder in inputs: 758 if holder._item: 759 names.append (holder._item._name) 760 accesses.append (holder._item._shellAccess) 761 762 if self._scatterPlot.isVisible () == True: 763 # Scatter Plot (optional errorbar) 764 if len (accesses) < 2: 765 self._bridge._statusBar.showTimed ("You must have at least two arguments!", STATUS_WAIT) 766 return 767 style = ", PLOT_STYLE=" + str (self.scatterPlotColor.itemData \ 768 (self.scatterPlotColor.currentIndex ()).toString ()) + \ 769 str (self.scatterStyle.itemData (self.scatterStyle.currentIndex ()).toString ()) 770 771 if self._xerror.isEnabled () or self._yerror.isEnabled (): 772 self._bridge._ipyShell.Command ("plot (" + accesses[0] + ", " + accesses[1] + \ 773 ", " + str (self._yerror.value ()) + ", " + str (self._xerror.value ()) + \ 774 style + ", \"pylab, errorbar, title=" + \ 775 self._scatterName.text () + "\")") 776 else: 777 self._bridge._ipyShell.Command ("plot (" + accesses[0] + ", " + accesses[1] + \ 778 style + ", \"pylab, scatter, title=" + \ 779 self._scatterName.text () + "\")") 780 elif self._contourPlot.isVisible () == True: 781 # Contour Plot 782 if len (accesses) == 1: 783 if (self._ContourSwitch.checkState() == PyQt4.QtCore.Qt.Checked): 784 self._bridge._ipyShell.Command ("plot (" + accesses[0] + \ 785 ", \"pylab, contour, title=" + self._contourName.text () + \ 786 ", " + str (self.contourPlotColor.currentText ()) + "\")") 787 if (self._ColorSwitch.checkState() == PyQt4.QtCore.Qt.Checked): 788 self._bridge._ipyShell.Command ("plot (" + accesses[0] + \ 789 ", \"pylab, pcolor, title=" + self._contourName.text () + \ 790 ", " + str (self.contourPlotColor.currentText ()) + "\")") 791 elif len (accesses) == 3: 792 self._bridge._ipyShell.Command ("plot (" + accesses[0] + ", " + accesses[1] + \ 793 ", " + accesses[2] + ", \"pylab, contour, title=" + self._contourName.text () + \ 794 ", " + str (self.contourPlotColor.currentText ()) + "\")") 795 else: 796 self._bridge._statusBar.showTimed ("Improper number of arguments (1 or 3)!", STATUS_WAIT) 797 return 798 elif self._histogramPlot.isVisible () == True: 799 # Histogram Plot 800 if len (accesses) < 1: 801 self._bridge._statusBar.showTimed ("You must have at least one argument!", STATUS_WAIT) 802 return 803 self._bridge._ipyShell.Command ("plot (" + accesses[0] + ", " + \ 804 str (self._binsHistogram.value ()) + ", \"pylab, hist, title=" + \ 805 self._histogramName.text () + "\")")
806
807 - def clear (self):
808 """ 809 PyLab.clear (self) 810 811 This method will empty the input holders as well as 812 reset the plot's name to "My Plot". This will get 813 called either explicity when the user clicks on the 814 `Clear` button, or on a successful transformation. 815 """ 816 if self._scatterPlot.isVisible () == True: 817 self._scatterName.setText ("My Scatter Plot") 818 for holder in self._scatterInputs: 819 holder.clear () 820 elif self._contourPlot.isVisible () == True: 821 self._contourName.setText ("My Contour Plot") 822 for holder in self._contourInputs: 823 holder.clear () 824 elif self._histogramPlot.isVisible () == True: 825 self._histogramName.setText ("My Histogram Plot") 826 for holder in self._histogramInputs: 827 holder.clear ()
828
829 -class VisItThread (PyQt4.QtCore.QThread):
830 - def __init__ (self, bridge, parent):
831 PyQt4.QtCore.QThread.__init__ (self) 832 833 self._bridge = bridge 834 self._visit = None 835 self._windowCount = 0 836 self._database = None 837 838 # Make this a setting later 839 self._plotTimeout = 10 840 841 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadLaunch (PyQt_PyObject)"), self.Launch, PyQt4.QtCore.Qt.QueuedConnection) 842 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadClose ()"), self.Close, PyQt4.QtCore.Qt.QueuedConnection) 843 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadAddWindow ()"), self.AddWindow, PyQt4.QtCore.Qt.QueuedConnection) 844 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadSetActiveWindow (PyQt_PyObject)"), self.SetActiveWindow, PyQt4.QtCore.Qt.QueuedConnection) 845 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadOpenComputeEngine ()"), self.OpenComputeEngine, PyQt4.QtCore.Qt.QueuedConnection) 846 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadOpenSimulation ()"), self.OpenSimulation, PyQt4.QtCore.Qt.QueuedConnection) 847 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadReOpenSimulation ()"), self.ReOpenSimulation, PyQt4.QtCore.Qt.QueuedConnection) 848 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadCloseSimulation ()"), self.CloseSimulation, PyQt4.QtCore.Qt.QueuedConnection) 849 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadAddPlotPseudocolor (PyQt_PyObject)"), self.AddPlotPseudocolor, PyQt4.QtCore.Qt.QueuedConnection) 850 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadAddPlotVolume (PyQt_PyObject)"), self.AddPlotVolume, PyQt4.QtCore.Qt.QueuedConnection) 851 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadInvertBackgroundColor ()"), self.InvertBackgroundColor, PyQt4.QtCore.Qt.QueuedConnection) 852 PyQt4.QtCore.QObject.connect (parent, PyQt4.QtCore.SIGNAL ("threadDrawPlots ()"), self.DrawPlots, PyQt4.QtCore.Qt.QueuedConnection)
853
854 - def getWindowCount (self):
855 return self._windowCount
856
857 - def getDatabase (self):
858 # if it doesn't exist yet, we gotta go bug the ipython shell for it... 859 # this is mildly costly, so once its found save it to self._database 860 if not self._database: 861 # Determine the path of the simulation file 862 path = self._bridge._ipyShell.ControllerCommand ("print \"\\\\n\" + filesystem.home ()").split ("\n")[-1] 863 path = path + "/.visit/simulations" 864 # Determine the name of the simulation file 865 simulations = self._bridge._ipyShell.ControllerCommand \ 866 ("print str (filesystem.lsFile (\"" + path + "\"))").split ("\n") 867 simulations.sort () 868 simulation = simulations[-5] 869 simulation = simulation[:simulation.find ("$")] 870 self._database = str (self._bridge._host) + ":" + path + "/" + simulation 871 872 # regardless of how you got the sim file database, return it 873 return self._database
874
875 - def run (self):
876 self.exec_ ()
877
878 - def launched (self):
879 if self._visit: 880 return True 881 return False
882
883 - def Launch (self, stereo):
884 if self.launched (): 885 return 886 887 print "VisIt Thread: Launching" 888 import visit 889 if stereo: 890 visit.AddArgument ("-stereo") 891 visit.Launch () 892 self._windowCount = 1 893 self._visit = visit 894 del (visit)
895
896 - def Close (self):
897 if self.launched (): 898 print "VisIt Thread: Closing" 899 self._visit.Close () 900 del (self._visit) 901 self._visit = None 902 return 903 904 print "VisIt Thread: Closing (Error, Not Launched)"
905
906 - def AddWindow (self):
907 if self.launched (): 908 self._windowCount += 1 909 print "VisIt Thread: Adding Window #" + str (self._windowCount) 910 self._visit.AddWindow () 911 return 912 913 print "VisIt Thread: Adding Window (Error, Not Launched)"
914
915 - def SetActiveWindow (self, index):
916 if index < 1 or index > self._windowCount: 917 print "VisIt Thread: Setting Active Window (Error, No Window #" + str (index) + ")" 918 return 919 920 if self.launched (): 921 print "VisIt Thread: Setting Active Window (" + str (index) + ")" 922 self._visit.SetActiveWindow (index) 923 return 924 925 print "VisIt Thread: Setting Active Window (Error, Not Launched)"
926
927 - def OpenComputeEngine (self):
928 if self.launched (): 929 print "VisIt Thread: Opening Computation Engine" 930 host = str (self._bridge._host) 931 args = ("-dir", str (self._bridge._ipyShell.VisItPath ())) 932 self._visit.OpenComputeEngine (host, args) 933 return 934 935 print "VisIt Thread: Opening Computation Engine (Error, Not Launched)"
936
937 - def OpenSimulation (self):
938 if self.launched (): 939 print "VisIt Thread: Opening Simulation" 940 self._visit.OpenDatabase (self.getDatabase ()) 941 return 942 943 print "VisIt Thread: Opening Simulation (Error, Not Launched)"
944
945 - def ReOpenSimulation (self):
946 if self.launched (): 947 print "VisIt Thread: Reopening Simulation" 948 self._visit.ReOpenDatabase (self.getDatabase ()) 949 return 950 951 print "VisIt Thread: Reopening Simulation (Error, Not Launched)"
952
953 - def CloseSimulation (self):
954 if self.launched (): 955 print "VisIt Thread: Closing Simulation" 956 self._visit.CloseDatabase (self.getDatabase ()) 957 return 958 959 print "VisIt Thread: Closing Simulation (Error, Not Launched)"
960
961 - def AddPlotPseudocolor (self, name):
962 if self.launched (): 963 print "VisIt Thread: Adding Pseudocolor Plot" 964 count = self._plotTimeout 965 while self._visit.AddPlot ("Pseudocolor", name) == 0 and count > 0: 966 count -= 1 967 print "VisIt Thread: Adding Pseudocolor Plot (Stalled)" 968 time.sleep (1) 969 970 if count == 0: 971 print "VisIt Thread: Adding Pseudocolor Plot (Failure)" 972 return 973 return 974 975 print "VisIt Thread: Adding Pseudocolor Plot (Error, Not Launched)"
976
977 - def AddPlotVolume (self, name):
978 if self.launched (): 979 print "VisIt Thread: Adding Volume Plot" 980 count = self._plotTimeout 981 while self._visit.AddPlot ("Volume", name) == 0 and count > 0: 982 count -= 1 983 print "VisIt Thread: Adding Volume Plot (Stalled:", count, ")" 984 time.sleep (1) 985 986 if count == 0: 987 print "VisIt Thread: Adding Volume Plot (Failure)" 988 return 989 return 990 991 print "VisIt Thread: Adding Volume Plot (Error, Not Launched)"
992
993 - def DrawPlots (self):
994 if self.launched (): 995 print "VisIt Thread: Drawing Plots" 996 self._visit.DrawPlots () 997 return 998 999 print "VisIt Thread: Drawing Plots (Error, Not Launched)"
1000
1001 - def InvertBackgroundColor (self):
1002 if self.launched (): 1003 print "VisIt Thread: Inverting Background Color" 1004 self._visit.InvertBackgroundColor () 1005 return 1006 1007 print "VisIt Thread: Inverting Background Color (Error, Not Launched)"
1008