PyFlex  1.0
Riser cross section analysis
main.py
Go to the documentation of this file.
1 """Copyright (C) 2016 Joakim A. Taby
2 
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 3 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program. If not, see <http://www.gnu.org/licenses/>."""
14 import sys
15 import os
16 # noinspection PyUnresolvedReferences
17 from PySide import QtGui, QtCore
18 import numpy as np
19 from ui_mainwindow import Ui_MainWindow, GenericTreeModel
20 import pyflex
21 import slenders
22 import re
23 import timehist
24 import errorhandling
25 # noinspection PyUnresolvedReferences
26 import h5py
27 import fnmatch
28 
29 
30 class Window(QtGui.QMainWindow, Ui_MainWindow):
31  """
32  Parent class for Pyflex. Data flow and Gui.
33  """
34  setupFullCalcResultsSignal = QtCore.Signal()
35 
36  def __init__(self, parent=None):
37  # noinspection PyArgumentList
38  super(Window, self).__init__(parent)
39  self.setupUi(self)
40  # Menu on left side.
41  # Showing the thing on right side
42  self.main_frame = QtGui.QWidget()
43  # a box to contain it all
44  mainbox = QtGui.QHBoxLayout()
45  # a big splitter to make it flow
46  self.mainsplitter = QtGui.QSplitter()
47  # making a widget for the box on the right
48  rightwidget = QtGui.QWidget()
49  # making a widget for the box on the left
50  leftwidget = QtGui.QWidget()
51  # making a box on the right to have the splitter in
52  rightlayout = QtGui.QVBoxLayout()
53  # making a box on the left to have the splitter in
54  leftlayout = QtGui.QVBoxLayout()
55  # making the right splitter
56  self.rightsplitter = QtGui.QSplitter()
57  # making the left splitter
58  self.leftsplitter = QtGui.QSplitter()
59  # making the windows tile vertically
60  self.rightsplitter.setOrientation(QtCore.Qt.Vertical)
61  # Making an upper tabbed widget for plotting and graphics
62  self.graphictab = QtGui.QTabWidget()
63  tmp = bool('true')
64  self.graphictab.setTabsClosable(tmp)
65  self.graphictab.tabCloseRequested.connect(self.close_graphictab)
66  self.graphictab.hide()
67  self.graphictab.hid = 'yes'
68  # making a lower tabbed widget for editing
69  self.edittab = QtGui.QTabWidget()
70  self.edittab.setTabsClosable(tmp)
71  self.edittab.tabCloseRequested.connect(self.close_edittab)
72  self.edittab.hide()
73  self.edittab.hid = 'yes'
74  # making the windows tile vertically
75  self.leftsplitter.setOrientation(QtCore.Qt.Vertical)
76  # Putting the pieces together
77  mainbox.addWidget(self.mainsplitter)
78  self.treemodel_setup()
79  # adding a textbrowser as status and error area
80  self.message_pane = QtGui.QTextBrowser()
81  self.leftsplitter.addWidget(self.message_pane)
82  self.rightsplitter.addWidget(self.graphictab)
83  self.rightsplitter.addWidget(self.edittab)
84  self.mainsplitter.addWidget(leftwidget)
85  self.mainsplitter.addWidget(rightwidget)
86  rightwidget.setLayout(rightlayout)
87  leftwidget.setLayout(leftlayout)
88  rightlayout.addWidget(self.rightsplitter)
89  leftlayout.addWidget(self.leftsplitter)
90  self.main_frame.setLayout(mainbox)
91  self.setCentralWidget(self.main_frame)
92  self.menuactions()
93  # noinspection PyUnresolvedReferences
94  self.view.customContextMenuRequested.connect(self.open_context_menu)
95  # user messages
96  sys.stdout = errorhandling.EmittingStream()
97  sys.stdout.textWritten.connect(self.messagehandling)
98  sys.stderr = errorhandling.EmittingStream()
99  sys.stderr.textWritten.connect(self.errorhandling)
100  # Initilizing variables that is set later depending on user
101  # Object holding the full stress calculation
102  self.fullstress = None
103  # Whether full calculations are shown
104  # self.fullstress.fullcalcShow = 'no'
105  # Layout for the left side of full result tab
107  # Tree view for full results
108  self.fullResultView = None
109  # Model for full results viewer
110  self.fullResultTree = None
111  # Widget containing the full results
112  self.fullResultWidget = None
113  # Container widget for left side of full results tab
115  # Button for export av full results
117  # Friction calculation object
118  self.friccalc = None
119  #connecting signal
120  self.view.itemDelegate().updateModelandDataSignal.connect(self.update_slenderdata)
121 
122  # creating a directory for working outputfiles
123  if not os.path.exists('tmp'):
124  os.makedirs('tmp')
125  else:
126  # list of things to clean up
127  for f in os.listdir('tmp'):
128  if fnmatch.fnmatch(f, 'fullresult*.h5'):
129  os.remove(os.path.join('tmp', f))
130 
131  def update_actions(self):
132  has_selection = not self.view.selectionModel().selection().isEmpty()
133  self.removeRowAction.setEnabled(has_selection)
134  self.removeColumnAction.setEnabled(has_selection)
135 
136  has_current = self.view.selectionModel().currentIndex().isValid()
137  self.insertRowAction.setEnabled(has_current)
138  self.insertColumnAction.setEnabled(has_current)
139 
140  if has_current:
141  self.view.closePersistentEditor(self.view.selectionModel().currentIndex())
142 
143  row = self.view.selectionModel().currentIndex().row()
144  column = self.view.selectionModel().currentIndex().column()
145  if self.view.selectionModel().currentIndex().parent().isValid():
146  self.statusBar().showMessage("Position: (%d,%d)" % (row, column))
147  else:
148  self.statusBar().showMessage("Position: (%d,%d) in top level" % (row, column))
149 
150  def open_context_menu(self, position):
151  """
152  Method for context menu. Should allow for inserting context based info.
153  Need to be rewritten when first item is working.
154  :param position: self. mainWindow class containing a treeview and a model
155  """
156  self.tree_model.layoutChanged.emit()
157  self.update_slenderdata()
158  indexes = self.view.selectedIndexes()
159  menu = QtGui.QMenu()
160  index = indexes[0]
161  item = self.tree_model.getItem(index)
162  if index.column() == 0:
163  if item.itemData[0] == 'Model data':
164  add_layer_action = menu.addAction(self.tr("Add layer"))
165  action = menu.exec_(self.view.viewport().mapToGlobal(position))
166  if action == add_layer_action:
167  self.update_slenderdata()
168  self.tree_model.addLayer()
169  self.tree_model.updateModel()
170  elif item.itemData[0] == 'Time history package':
171  plot_action = menu.addAction(self.tr("Plot the time histories"))
172  action = menu.exec_(self.view.viewport().mapToGlobal(position))
173  if action == plot_action:
174  item = self.tree_model.getItem(index)
175  for timehistInstance in self.tree_model.timehists:
176  if item.itemData[1] == timehistInstance.name:
177  if self.graphictab.hid == 'yes':
178  self.graphictab.show()
179  self.graphictab.hid = 'no'
180  timehistInstance.plot(self.graphictab)
181  elif item.itemData[0] == 'Time history file':
182  plot_action = menu.addAction(self.tr("Plot the time histories"))
183  action = menu.exec_(self.view.viewport().mapToGlobal(position))
184  if action == plot_action:
185  item = self.tree_model.getItem(index)
186  for timehistInstance in self.tree_model.timehists:
187  if item.itemData[1] == timehistInstance.name:
188  if self.graphictab.hid == 'yes':
189  self.graphictab.show()
190  timehistInstance.plot(self.graphictab)
191  elif item.itemData[0] == 'Calculations':
192  friction_action = menu.addAction(self.tr('Calculate friction importance'))
193  full_calc_action = menu.addAction(self.tr('Calculate stresses, including the friction effect'))
194  action = menu.exec_(self.view.viewport().mapToGlobal(position))
195  if action == friction_action:
196  self.add_frictioncalc()
197  if action == full_calc_action:
198  self.add_full_calc()
199 
200  elif item.itemData[0] == 'Friction calculation':
201  # initialising variables
202  view_action = None
203  plot_action = None
204  # finding whether the friction calculations are done
205  hasfric = 0
206  if hasattr(self.friccalc, 'bendMax'):
207  hasfric = 1
208  # adding actions
209  edit_action = menu.addAction(self.tr('Edit'))
210  if hasfric == 1:
211  view_action = menu.addAction(self.tr('View resulttable'))
212  plot_action = menu.addAction(self.tr('View plot'))
213  action = menu.exec_(self.view.viewport().mapToGlobal(position))
214  if action == edit_action:
215  self.frictionedit()
216  elif action == view_action:
217  self.show_friction_results()
218  elif action == plot_action:
219  self.fricplot()
220 
221  elif item.itemData[0] == 'Full stress calculation':
222  # finding whether the friction calculations are done
223  hasfull = 0
224  if self.fullResultWidget:
225  hasfull = 1
226  # adding actions
227  edit_action = menu.addAction(self.tr('Edit'))
228  if hasfull:
229  view_action = menu.addAction(self.tr('View results'))
230  # add actions for results and stuff here
231  action = menu.exec_(self.view.viewport().mapToGlobal(position))
232  # noinspection PyUnboundLocalVariable
233  if action == edit_action:
234  self.fulledit()
235  elif action == view_action:
236  self.show_full_results()
237 
238  def add_full_calc(self):
239  self.fulledit()
240  self.tree_model.addCalc(key='full')
241  # self.tree_model.addFullStressCalc()
242 
243  def fulledit(self):
244  self.update_slenderdata()
245  # Checking if we have an open tab for calculations
246  # If so, we open that tab
247  if not self.fullstress:
249  self.fullstress.setup_tab(self)
250  self.edittab.addTab(self.fullstress.mainwidget, 'Full stress calc')
251  open_tab(self.edittab, 'Full stress calc')
252 
253  def fullcalc(self):
254  self.update_slenderdata()
256  self.setupFullCalcResultsSignal.emit()
257  self.fullstress.removeFullCalcResultSignal.connect(self.remove_fullcalc_result)
258  self.fullstress.calculate(self.tree_model.slenderdata)
259  for i in self.fullstress.analyses:
260  i.addFullCalcSignal.connect(self.add_fullcalc_results)
261  self.fullstress.fullcalcShow = 'yes'
262 
264  self.show_graphictab()
265  tabs = self.graphictab.count()
266  found = 0
267  for index in range(tabs):
268  text = self.graphictab.tabText(index)
269  if text == 'Full calculation results':
270  self.close_graphictab(index)
271  self.show_graphictab()
272  found = 1
273  break
274  self.fullResultWidget = QtGui.QSplitter()
275  self.fullResultLeftLayout = QtGui.QVBoxLayout()
276  self.fullResultLeftWidget = QtGui.QWidget()
277  names = []
278  for i in self.fullstress.timehists:
279  names.append(i.name)
280  if self.fullstress.canvas:
281  self.fullstress.deleteplot()
282  # adding tree model for results exploration
283  self.fullResultTree = FullResultTreeModel(names)
284  self.fullResultView = QtGui.QTreeView()
286  self.fullResultProxy.setSourceModel(self.fullResultTree)
287  #self.fullResultView.setModel(self.fullResultProxy)
288  self.fullResultView.setModel(self.fullResultTree)
289  selection = self.fullResultView.selectionModel()
290  selection.selectionChanged.connect(self.update_fullplot)
291  self.fullResultLeftLayout.addWidget(self.fullResultView)
292  self.fullResultsExportButton = QtGui.QPushButton('Export all')
293  self.fullResultsExportButton.clicked.connect(self.fullstress.export_all_results)
294  self.fullResultLeftLayout.addWidget(self.fullResultsExportButton)
295  self.fullResultLeftWidget.setLayout(self.fullResultLeftLayout)
296  self.fullResultWidget.addWidget(self.fullResultLeftWidget)
297  if found == 0:
298  self.graphictab.addTab(self.fullResultWidget, 'Full calculation results')
299  self.graphictab.setCurrentIndex(tabs)
300  elif found == 1:
301  if tabs == 1:
302  self.graphictab.addTab(self.fullResultWidget, 'Full calculation results')
303  self.graphictab.setCurrentIndex(0)
304  else:
305  # noinspection PyUnboundLocalVariable
306  self.graphictab.insertTab(index, self.fullResultWidget, 'Full calculation results')
307  self.graphictab.setCurrentIndex(index)
308 
310  tabs = self.graphictab.count()
311  for index in range(tabs):
312  text = self.graphictab.tabText(index)
313  if text == 'Full calculation results':
314  self.close_graphictab(index)
315  break
316 
317  def update_fullplot(self, selected):
318  # assume only 1 index
319  index = selected.indexes()
320  self.fullResultTree.toggle(index[0])
321  self.fullstress.plot(self.fullResultTree.plotData, self.fullResultWidget)
322 
323  def add_fullcalc_results(self, number):
324  self.fullResultTree.add_result(number)
325 
326  def add_frictioncalc(self):
327  self.frictionedit()
328  self.tree_model.addCalc(key='friction')
329 
330  def frictionedit(self):
331  self.update_slenderdata()
332  # checking if we have an open friction tab
333  # if so, we open that tab
334  if not self.friccalc:
335  # Building up the window
337  self.friccalc.setup_tab(self)
338 
339  self.edittab.addTab(self.friccalc.mainwidget, 'Friction')
340  open_tab(self.edittab, 'Friction')
341 
343  self.update_slenderdata()
344  self.datacheck()
345  self.friccalc.calculate(self.tree_model.slenderdata)
346  self.show_friction_results()
347 
349  self.show_graphictab()
350  # finding if we already have one of these. if so, remove it and insert this there
351  tabs = self.graphictab.count()
352  found = 0
353  for index in range(tabs):
354  text = self.graphictab.tabText(index)
355  if text == 'Friction calcs':
356  self.close_graphictab(index)
357  self.show_graphictab()
358  found = 1
359  break
360 
361  main_widget = QtGui.QWidget()
362  main_layout = QtGui.QVBoxLayout()
363  main_widget.setLayout(main_layout)
364  title = QtGui.QLabel('<H1> Friction calculations </H1>')
365  main_layout.addWidget(title)
366  table = self.friccalc.table()
367  main_layout.addWidget(table)
368  plot_button = QtGui.QPushButton('Plot the stress components')
369  plot_button.clicked.connect(self.fricplot)
370  main_layout.addWidget(plot_button)
371  if found == 0:
372  self.graphictab.addTab(main_widget, 'Friction calcs')
373  self.graphictab.setCurrentIndex(tabs)
374  elif found == 1:
375  if tabs == 1:
376  self.graphictab.addTab(main_widget, 'Friction calcs')
377  self.graphictab.setCurrentIndex(0)
378  else:
379  # noinspection PyUnboundLocalVariable
380  self.graphictab.insertTab(index, main_widget, 'Friction calcs')
381  self.graphictab.setCurrentIndex(index)
382 
383  def show_full_results(self):
384  # searching if tab is already there
385  tabs = self.graphictab.count()
386  found = False
387  for index in range(tabs):
388  text = self.graphictab.tabText(index)
389  if text == 'Full calculation results':
390  found = True
391  break
392  # if it is, switch to it, if not, add it
393  # if the result is not existing, do nothing
394  if self.fullResultWidget:
395  if found:
396  # noinspection PyUnboundLocalVariable
397  self.graphictab.setCurrentIndex(index)
398  else:
399  self.graphictab.addTab(self.fullResultWidget, 'Full calculation results')
400  self.show_graphictab()
401 
402  def fricplot(self):
403  self.show_graphictab()
404  self.friccalc.plot(self.graphictab)
405 
406  # TODO: move it to slender
407  # noinspection PyUnresolvedReferences
408  def datacheck(self):
409  if hasattr(self.tree_model.slenderdata, 'lay_angle'):
410  count = 0
411  for i in self.tree_model.slenderdata.lay_angle:
412  count += 1
413  if i > np.pi / 2 or i < -np.pi / 2:
414  print('The lay angle of layer %d needs to be in the range '
415  '-pi/2<=layang <=pi/2' % count)
416  if hasattr(self.tree_model.slenderdata, 'layer_radii'):
417  for i in range(len(self.tree_model.slenderdata.layer_radii) - 1):
418  if self.tree_model.slenderdata.layer_radii[i + 1] >= self.tree_model.slenderdata.layer_radii[i]:
419  print('In Pyflex we model from the outside inwards')
420  for i in self.tree_model.slenderdata.layer_radii:
421  if i <= 0:
422  print('The radius of layer %d needs to be positive' % i)
423  if hasattr(self.tree_model.slenderdata, 'comp_number'):
424  count = 0
425  for i in self.tree_model.slenderdata.comp_number:
426  count += 1
427  if i <= 0:
428  print('The number of tendons in layer %d must be more then 0.'
429  % count)
430 
432  parentindex = self.tree_model.index(0, 0, QtCore.QModelIndex())
433  rows = self.tree_model.rowCount(parentindex)
434  for row in range(rows):
435  index = self.tree_model.index(row, 0, parentindex)
436  # find what it is, and if it has kids, go to right branch for putting further
437  itemtext = self.tree_model.data(index, QtCore.Qt.DisplayRole)
438  dataindex = self.tree_model.index(row, 1, parentindex)
439  itemdata = self.tree_model.data(dataindex, QtCore.Qt.DisplayRole)
440  if itemtext == 'Data for layer':
441  subindex = int(itemdata) - 1
442  self.update_layerdata(subindex, index)
443  if itemtext == 'Internal pressure layer':
444  self.tree_model.slenderdata.intpresslayer = int(float(itemdata))
445  if itemtext == 'External pressure layer':
446  self.tree_model.slenderdata.extpresslayer = int(float(itemdata))
447  self.update_scenariodata()
448  self.update_globaldata()
449  self.tree_model.updateModel()
450  self.tree_model.layoutChanged.emit()
451 
452  # noinspection PyUnresolvedReferences,PyUnresolvedReferences
453  def update_layerdata(self, subindex, parentindex):
454  rows = self.tree_model.rowCount(parentindex)
455  for row in range(rows):
456  index = self.tree_model.index(row, 0, parentindex)
457  itemtext = self.tree_model.data(index, QtCore.Qt.DisplayRole)
458  dataindex = self.tree_model.index(row, 1, parentindex)
459  itemdata = self.tree_model.data(dataindex, QtCore.Qt.DisplayRole)
460  if itemtext == 'Type':
461  if len(self.tree_model.slenderdata.layer_type) >= subindex + 1:
462  self.tree_model.slenderdata.layer_type[subindex] = itemdata
463  else:
464  self.tree_model.slenderdata.layer_type.append(itemdata)
465  if itemtext == 'Radius':
466  item = itemcheck(itemdata, 'Radius')
467  if item is None:
468  print('Only one radius allowed for a layer')
469  return
470 
471  elif hasattr(item, "__iter__"):
472  # error message
473  print("Only one radius allowed for a layer")
474  return
475  else:
476  if len(self.tree_model.slenderdata.layer_radii) >= subindex + 1:
477  self.tree_model.slenderdata.layer_radii[subindex] = float(item)
478  else:
479  self.tree_model.slenderdata.layer_radii.append(float(item))
480 
481  if itemtext == 'Thickness':
482  item = itemcheck(itemdata, 'Thickness')
483  if hasattr(item, "__iter__"):
484  # error message
485  print('Only one thickness allowed for a layer')
486  return
487  else:
488  if len(self.tree_model.slenderdata.thickness) >= subindex + 1:
489  self.tree_model.slenderdata.thickness[subindex] = float(item)
490  else:
491  self.tree_model.slenderdata.thickness.append(float(item))
492 
493  if itemtext == 'Initial gap':
494  item = itemcheck(itemdata, 'Initial gap')
495  if hasattr(item, "__iter__"):
496  # error message
497  print('Only one initial gap allowed for a layer')
498  return
499  else:
500  if len(self.tree_model.slenderdata.gap_ini) >= subindex + 1:
501  self.tree_model.slenderdata.gap_ini[subindex] = float(item)
502  else:
503  self.tree_model.slenderdata.gap_ini.append(float(item))
504 
505  if itemtext == 'Youngs modulus':
506  item = itemcheck(itemdata, 'Youngs Modulus')
507  if hasattr(item, "__iter__"):
508  # error message
509  print('Only one Youngs modulus allowed for a layer')
510  return
511  else:
512  if len(self.tree_model.slenderdata.youngs_modulus) >= subindex + 1:
513  self.tree_model.slenderdata.youngs_modulus[subindex] = float(item)
514  else:
515  self.tree_model.slenderdata.youngs_modulus.append(float(item))
516 
517  if itemtext == "Poisson's ratio":
518  item = itemcheck(itemdata, "Poisson's ratio")
519  if hasattr(item, "__iter__"):
520  # error message
521  print("Only one Poisson's ratio allowed for a layer")
522  return
523  else:
524  if len(self.tree_model.slenderdata.poisson) >= subindex + 1:
525  self.tree_model.slenderdata.poisson[subindex] = float(item)
526  else:
527  self.tree_model.slenderdata.poisson.append(float(item))
528 
529  if itemtext == 'Friction factor':
530  item = itemcheck(itemdata, 'Friction factor')
531  if hasattr(item, "__iter__"):
532  # error message
533  print('Only one friction factor allowed for a layer')
534  return
535  else:
536  if len(self.tree_model.slenderdata.fricfac) >= subindex + 1:
537  self.tree_model.slenderdata.fricfac[subindex] = float(item)
538  else:
539  self.tree_model.slenderdata.fricfac.append(float(item))
540 
541  if itemtext == 'Width':
542  item = itemcheck(itemdata, 'Width')
543  if hasattr(item, "__iter__"):
544  # error message
545  print('Only one width allowed for a layer')
546  return
547  else:
548  if len(self.tree_model.slenderdata.width) >= subindex + 1:
549  self.tree_model.slenderdata.width[subindex] = float(item)
550  else:
551  self.tree_model.slenderdata.width.append(float(item))
552 
553  if itemtext == 'Lay angle':
554  item = itemcheck(itemdata, 'Lay angle')
555  if hasattr(item, "__iter__"):
556  # error message
557  print('Only one lay angle allowed for a layer')
558  return
559  else:
560  if len(self.tree_model.slenderdata.lay_angle) >= subindex + 1:
561  self.tree_model.slenderdata.lay_angle[subindex] = float(item)
562  else:
563  self.tree_model.slenderdata.lay_angle.append(float(item))
564 
565  if itemtext == 'Number of tendons':
566  item = itemcheck(itemdata, 'Number of tendons')
567  if hasattr(item, "__iter__"):
568  # error message
569  print('Only one number of tendons allowed for a layer')
570  return
571  else:
572  if len(self.tree_model.slenderdata.comp_number) >= subindex + 1:
573  self.tree_model.slenderdata.comp_number[subindex] = float(item)
574  else:
575  self.tree_model.slenderdata.comp_number.append(float(item))
576 
578  parentindex = self.tree_model.index(1, 0, QtCore.QModelIndex())
579  rows = self.tree_model.rowCount(parentindex)
580  for row in range(rows):
581  index = self.tree_model.index(row, 0, parentindex)
582  itemtext = self.tree_model.data(index, QtCore.Qt.DisplayRole)
583  dataindex = self.tree_model.index(row, 1, parentindex)
584  itemdata = self.tree_model.data(dataindex, QtCore.Qt.DisplayRole)
585  if itemtext == 'Typical curvature':
586  item = itemcheck(itemdata, 'Typical curvature')
587  if hasattr(item, "__iter__"):
588  # error message
589  self.errorhandling('Only one typical curvature allowed')
590  return
591  else:
592  self.tree_model.slenderdata.typical_curvature = item
593  if itemtext == 'Typical tension':
594  item = itemcheck(itemdata, 'Typical tension')
595  if hasattr(item, "__iter__"):
596  # error message
597  self.errorhandling('Only one typical tension allowed')
598  else:
599  self.tree_model.slenderdata.typical_tension = item
600  if itemtext == 'Internal pressure':
601  item = itemcheck(itemdata, 'Internal pressure')
602  if hasattr(item, "__iter__"):
603  # error message
604  self.errorhandling('Only one internal pressure allowed')
605  else:
606  self.tree_model.slenderdata.internal_pressure = item
607 
608  def update_globaldata(self):
609  foundglobaldata = None
610  parentindex = QtCore.QModelIndex()
611  rows = self.tree_model.rowCount(parentindex)
612  for row in range(rows):
613  index = self.tree_model.index(row, 0, parentindex)
614  itemtext = self.tree_model.data(index, QtCore.Qt.DisplayRole)
615  if itemtext == 'Global results':
616  foundglobaldata = 1
617  break
618  if foundglobaldata:
619  # noinspection PyUnboundLocalVariable
620  rows = self.tree_model.rowCount(index)
621  count = 0
622  for row in range(rows):
623  textindex = self.tree_model.index(row, 0, index)
624  dataindex = self.tree_model.index(row, 1, index)
625  itemtext = self.tree_model.data(textindex, QtCore.Qt.DisplayRole)
626  itemdata = self.tree_model.data(dataindex, QtCore.Qt.DisplayRole)
627  if itemtext == 'Timehistories from directory':
628  subrows = self.tree_model.rowCount(textindex)
629  for subrow in range(subrows):
630  sub_data_index = self.tree_model.index(subrow, 1, textindex)
631  itemdata = self.tree_model.data(sub_data_index, QtCore.Qt.DisplayRole)
632  self.tree_model.timehists[count].name = itemdata
633  count += 1
634  else:
635  self.tree_model.timehists[count].name = itemdata
636  count += 1
637 
638  # noinspection PyUnresolvedReferences
639  def menuactions(self):
640  """
641  managing menu selection.
642  """
643  self.exitAction.triggered.connect(QtGui.qApp.quit)
644  self.openAction.triggered.connect(self.open)
645  self.newAction.triggered.connect(self.treemodel_setup)
646  self.importAction.triggered.connect(self.import_ts)
647  self.importFolderAction.triggered.connect(self.import_ts_folder)
648  self.aboutAction.triggered.connect(self.license)
649 
650  # noinspection PyAttributeOutsideInit
651  def treemodel_setup(self):
652  """
653  Setting up the left menu with its tree model.
654  Further items in left menu should be added here.
655  """
656  if hasattr(self, 'tree_model'):
657  del self.tree_model
659  self.view.setModel(self.tree_model)
660  self.leftsplitter.insertWidget(0, self.view)
661 
662  # noinspection PyAttributeOutsideInit
663  def open(self):
664  """Controls what is happening when opening a file. Reads it, parses it, and puts the data in a tree model"""
665  # noinspection PyArgumentList,PyCallByClass
666  tmp = QtGui.QFileDialog.getOpenFileName(self, caption='Open File',
667  filter="PyFlex input files (*.dat);; Any files (*)",
668  selectedFilter="PyFlex input files (*.dat)")
669  self.fileName = tmp[0]
670  if self.fileName:
671  self.delimiter = '\t'
672  self.commentchar = '#'
673  self.tree_model.slenderdata = pyflex.analytical_input(self.fileName,
674  self.delimiter, self.commentchar)
675  self.update_globaldata()
676  self.put_import()
677 
678  def license(self):
679  '''Popup a box with about message.'''
680  QtGui.QMessageBox.about(self, "About Pyflex v1.0",
681  """<p>Copyright &copy; 2016 Joakim A Taby.
682  All rights reserved in accordance with
683  GPL v3 - NO WARRANTIES!
684  For full license click <a href='../docs/License/license.md'>here</a>""")
685 
686  def put_import(self):
687  """Putting the input from input file into where it belongs"""
688  self.tree_model.updateModel()
689 
690  def import_ts(self):
691  """Controls what is happening when opening a file. Reads it, parses it, and puts the data in a tree model"""
692  # noinspection PyArgumentList,PyCallByClass
693  tmp = QtGui.QFileDialog.getOpenFileName(self, caption='Open File',
694  filter="PyFlex time series files (*.tim);; Any files (*)",
695  selectedFilter="PyFlex time series files (*.tim)")
696  time_file_name = tmp[0]
697  file_name = re.split('[/\\\\]', time_file_name)[-1]
698  if time_file_name:
699  if not hasattr(self.tree_model, 'timehists'):
700  self.tree_model.timehists = []
701  self.tree_model.timehists.append(timehist.TimeHist(time_file_name, file_name))
702  self.tree_model.addTimeHist(file_name)
703  self.tree_model.layoutChanged.emit()
704 
705  def import_ts_folder(self):
706  # getting directory and list of files
707  dialog = QtGui.QFileDialog()
708  dialog.setFileMode(QtGui.QFileDialog.Directory)
709  dialog.setOption(QtGui.QFileDialog.ShowDirsOnly)
710  directory = dialog.getExistingDirectory(self, 'Choose Directory', os.path.curdir)
711  if directory:
712  filelist = os.listdir(directory)
713  filelist.sort()
714  # making the list of time histories
715  if not hasattr(self.tree_model, 'timehists'):
716  self.tree_model.timehists = []
717  # adding Global result item in tree model if it doesn't exist
718  global_result_item = self.tree_model.addGlobalResults()
719  # adding the directory items
720  directory_parent = self.tree_model.addGlobalDirectory(global_result_item, directory)
721  for file in filelist:
722  if file.endswith(".tim"):
723  # making tree model for this
724  self.tree_model.timehists.append(timehist.TimeHist(file, file, directory=directory))
725  self.tree_model.addTimeHist(file, parent=directory_parent)
726  self.tree_model.layoutChanged.emit()
727 
728  def errorhandling(self, text):
729  """
730  Append red text to the QTextEdit.
731  :param text: text to write
732  """
733  text = text.replace("\r", "")
734  text = text.replace("\n", "")
735  text = text.strip()
736  if len(text) > 0:
737  self.message_pane.append(str('<font color="red">' + text + '</font>'))
738 
739  def messagehandling(self, text):
740  """
741  Append text to the QTextEdit.
742  :param text: text to add to QTextEdit
743  """
744  text = text.replace("\r", "")
745  text = text.replace("\n", "")
746  text = text.strip()
747  if len(text) > 0:
748  self.message_pane.append(self.message_pane.append(str('<font color="black">' + text + '</font>')))
749 
750  def show_graphictab(self):
751  # making sure the graphictab is shown
752  if self.graphictab.hid == 'yes':
753  self.graphictab.show()
754  self.graphictab.hid = 'no'
755 
756  def close_graphictab(self, index):
757  widget = self.graphictab.widget(index)
758  self.graphictab.removeTab(index)
759  text = self.graphictab.tabText(index)
760  if text in ('Friction calcs', 'Plot of stresses from friction calculations'):
761  widget.deleteLater()
762  # check if tabwidget is empty
763  widget = self.graphictab.widget(0)
764  if not widget:
765  self.graphictab.hide()
766  self.graphictab.hid = 'yes'
767 
768  def close_edittab(self, index):
769  widget = self.edittab.widget(index)
770  text = self.edittab.tabText(index)
771  if text == 'Friction':
772  self.edittab.removeTab(index)
773 
774  elif text == 'Full stress calc':
775  self.edittab.removeTab(index)
776  else:
777  self.edittab.removeTab(index)
778  widget.deleteLater()
779 
780  # check if tabwidget is empty
781  widget = self.edittab.widget(0)
782  if not widget:
783  self.edittab.hide()
784  self.edittab.hid = 'yes'
785 
786  # noinspection PyPep8Naming
787  def eventFilter(self, obj, event):
788  if self.fullstress:
789  if obj is self.fullstress.mainwidget:
790  if event.type() == QtCore.QEvent.DragEnter:
791  if event.mimeData().hasFormat('text/plain'):
792  text = event.mimeData().data('text/plain')
793  text = str(text)
794  text = text.split(',')
795  if text[0] in ('singlefile', 'directory', 'singlefilefromdirectory'):
796  event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!!
797  if event.type() == QtCore.QEvent.Drop:
798  if event.mimeData().hasFormat('text/plain'):
799  text = event.mimeData().data('text/plain')
800  text = text.split(',')
801  dragdrop = self.fullstress.mainwidget.findChild(QtGui.QLabel, 'dragdrop')
802  if text[0] in ('singlefile', 'directory'):
803  self.add_ts(text[0], text[1], None, ts_type='full')
804  dragdrop.hide()
805  elif text[0] == 'singlefilefromdirectory':
806  self.add_ts(text[0], text[1], text[2], ts_type='full')
807  dragdrop.hide()
808  return True
809  if self.friccalc:
810  if obj is self.friccalc.mainwidget:
811  if event.type() == QtCore.QEvent.DragEnter:
812  if event.mimeData().hasFormat('text/plain'):
813  text = event.mimeData().data('text/plain')
814  text = str(text)
815  text = text.split(',')
816  if text[0] in ('singlefile', 'singlefilefromdirectory'):
817  event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!!
818  if event.type() == QtCore.QEvent.Drop:
819  if event.mimeData().hasFormat('text/plain'):
820  text = event.mimeData().data('text/plain')
821  text = text.split(',')
822  dragdrop = self.friccalc.mainwidget.findChild(QtGui.QLabel, 'dragdrop')
823  if text[0] == 'singlefilefromdirectory':
824  self.add_ts(text[0], text[1], text[2], ts_type='friction')
825  dragdrop.hide()
826  elif text[0] == 'singlefile':
827  self.add_ts(text[0], text[1], None, ts_type='friction')
828  dragdrop.hide()
829  return True # lets the event continue to the edit
830  return False
831 
832  def add_ts(self, import_type, info, directory, ts_type='full'):
833  self.update_slenderdata()
834  info = str(info)
835  import_type = str(import_type)
836  if import_type == 'singlefile':
837  self.append_ts(info, None, ts_type)
838  if import_type == 'directory':
839  for i in self.tree_model.timehists:
840  if hasattr(i, 'directory'):
841  if i.directory == info:
842  self.append_ts(i.name, i.directory, ts_type)
843 
844  if import_type == 'singlefilefromdirectory':
845  self.append_ts(info, directory, ts_type)
846  if ts_type == 'full':
847  self.fullstress.setup_ts_edit()
848  if ts_type == 'friction':
849  self.friccalc.setup_ts_edit()
850 
851  def append_ts(self, name, directory, ts_type='full'):
852 
853  # finding the timehistory and adding it to the timehist in the
854  # fullstress calculations. Adding the info into lists
855  found = 0
856  for i in self.tree_model.timehists:
857  if i.name == name:
858  if ts_type == 'full':
859  if not directory:
860  self.fullstress.add_ts(i)
861  found = 1
862  break
863  elif hasattr(i, 'directory'):
864  if directory == i.directory:
865  self.fullstress.add_ts(i)
866  found = 1
867  break
868  elif ts_type == 'friction':
869  self.friccalc.add_ts(i)
870  found = 1
871  if found == 0:
872  print('Could not transfer data. Try again.')
873  return
874 
875 # noinspection PyPep8Naming
876 class TreeItem(object):
877  """ class for making the items that constitutes the tree model. The items carries the data"""
878 
879  def __init__(self, data, parent=None, finalRow=None, color=None):
880  self.parentItem = parent
881  self.itemData = data
882  self.childItems = []
883  self.finalRow = finalRow
884  self.color = color
885 
886  def setColor(self, color):
887  self.color = color
888 
889  def Color(self):
890  return self.color
891 
892  def insertChildren(self, position, count, columns, finalRow=None):
893  if position < 0 or position > len(self.childItems):
894  return False
895 
896  for row in range(count):
897  # noinspection PyUnusedLocal
898  data = [None for v in range(columns)]
899  if finalRow:
900  item = TreeItem(data, self, finalRow=finalRow + row - range(count)[0])
901  else:
902  item = TreeItem(data, self)
903  self.childItems.insert(position, item)
904 
905  return True
906 
907  def appendChild(self, item):
908  self.childItems.append(item)
909 
910  def child(self, row):
911  return self.childItems[row]
912 
913  def childCount(self):
914  return len(self.childItems)
915 
916  def columnCount(self):
917  return len(self.itemData)
918 
919  def data(self, column):
920  try:
921  return self.itemData[column]
922  except IndexError:
923  return None
924 
925  def parent(self):
926  return self.parentItem
927 
928  def removeChildren(self, position, count):
929  if position < 0 or position + count > len(self.childItems):
930  return False
931 
932  for row in range(count):
933  self.childItems.pop(position)
934 
935  return True
936 
937  def row(self):
938  if self.parentItem:
939  return self.parentItem.childItems.index(self)
940  return 0
941 
942  def setData(self, column, value):
943  """
944  Method for setting data into given column. Should be used when setting data in model.
945  :param value: The value of the data to be written
946  :param column: Which column the data is to be written to
947  """
948  if column < 0 or column >= len(self.itemData):
949  return False
950 
951  self.itemData[column] = value
952  # writing this to background data as well. I have the feeling we have one layer to much here
953  return True
954 
956  """ Special items for model data"""
957  def __init__(self, data, parent=None, finalRow=None, color=None,type=None,nopt=None):
958  super(ModelTreeItem, self).__init__(data,parent=parent,finalRow=finalRow,color=color)
959  if type=='combo':
960  self.type=type
961  self.options=['sheath','wires']
962  if type=='presslayer':
963  self.type=type
964  self.options=list(map(str, list(range(1,nopt+1))))
965 
966  def updateitemoptions(self,options):
967  self.options=options
968 
969 def itemcheck(item, inputstring):
970  """Function for checking an item. returning something
971  Returning float of the input if one input. Returning a list if more inputs
972  :param item:The data to be checked
973  :param inputstring: The type of data to be checked. For output to user.
974  """
975  # noinspection PyPep8,PyPep8
976  if isinstance(item, float):
977  return item
978  elif (not hasattr(item, "strip") and
979  hasattr(item, "__getitem__") or
980  hasattr(item, "__iter__")):
981  # listlike
982  if len(item) > 1:
983  for i in range(len(item)):
984  if item[i] is None:
985  return item[i]
986  else:
987  try:
988  return float(item)
989  except (TypeError, ValueError):
990  # error message
991  # if a string of numbers
992  l = []
993  for t in re.split(',| ', item):
994  try:
995  l.append(float(t))
996  except ValueError:
997  pass
998  except TypeError:
999  print('Cannot parse the ', inputstring, ' given')
1000  return l
1001 
1002  else:
1003  if not item:
1004  # empty string
1005  return None
1006  elif item[0] is None:
1007  return item[0]
1008  else:
1009  try:
1010  return float(item[0])
1011  except TypeError:
1012  # error message
1013  print('Cannot parse the ', inputstring, ' given')
1014  else:
1015  # Stringlike
1016  if item is None:
1017  return item
1018  try:
1019  return float(item)
1020  except TypeError:
1021  # error message
1022  print('Cannot parse the ', inputstring, ' given')
1023 
1024 def open_tab(tab_widget, intext):
1025  if tab_widget.hid == 'yes':
1026  tab_widget.hid = 'no'
1027  tab_widget.show()
1028  tabs = tab_widget.count()
1029  for index in range(tabs):
1030  text = tab_widget.tabText(index)
1031  if text == intext:
1032  tab_widget.setCurrentIndex(index)
1033  return 'True'
1034  return 'False'
1035 
1036 # noinspection PyPep8Naming
1038  """The model holding the connection between the items."""
1039 
1040  def __init__(self, parent=None):
1041  super(TreeModel, self).__init__(parent)
1042  self.rootItem = TreeItem(("Item", "Summary/Value"))
1044  self.setupModelData(self.rootItem)
1045 
1046  def flags(self, index):
1047  """
1048  Used to select the way each cell works
1049  :param index: the index of the item queried
1050  :return: view get info on items "Type"
1051  """
1052  if not index.isValid():
1053  return 0
1054  if index.column() > 0:
1055  item = self.getItem(index)
1056  itemtext = item.itemData[0]
1057  tsItem = self.recParentValidate(index, 'Global results')
1058  if itemtext in ('Calculations', 'Data for layer', 'Model data', 'Scenario definition'):
1059  return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
1060  elif tsItem:
1061  return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
1062  else:
1063  calcItem = self.recParentValidate(index, 'Calculations')
1064  if calcItem:
1065  return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
1066  else:
1067  return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
1068  else:
1069  tsItem = self.recParentValidate(index, 'Global results')
1070  if tsItem:
1071  return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled
1072  else:
1073  return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
1074 
1075  # drag and drop stuff
1076  @staticmethod
1077  def mimeTypes():
1078  return ['text/plain']
1079 
1080  def mimeData(self, indexes):
1081  item = self.getItem(indexes[0])
1082  if item.itemData[0] == 'Time history package':
1083  mimedata = QtCore.QMimeData()
1084  mimedata.setData('text/plain', 'singlefile,%s' % item.itemData[1])
1085  elif item.itemData[0] == 'Timehistories from directory':
1086  mimedata = QtCore.QMimeData()
1087  mimedata.setData('text/plain', 'directory,%s' % item.itemData[1])
1088  elif item.itemData[0] == 'Time history file':
1089  mimedata = QtCore.QMimeData()
1090  mimedata.setData('text/plain', 'singlefilefromdirectory,%s,%s'
1091  % (item.itemData[1], item.parent().itemData[1]))
1092  else:
1093  return None
1094 
1095  return mimedata
1096 
1097  def updateModel(self):
1098  """Model for updating the model with new slenderdata"""
1099  parentindex = self.index(0, 0, QtCore.QModelIndex())
1100  #Updating slenderdata that is not on a layer level
1101  if hasattr(self.slenderdata, 'intpresslayer'):
1102 # rows = self.rowCount(parentindex)
1103 # parentItem = self.getItem(parentindex)
1104 # for row in range(rows-1,-1,-1):
1105 # item = parentItem.child(row)
1106 # if item.itemData[0] == 'Internal pressure layer':
1107 # self.removeRows(row, 1, parentindex)
1108  self.setSlenderData(self.slenderdata.intpresslayer, parentindex, 'Internal pressure layer')
1109  if hasattr(self.slenderdata, 'extpresslayer'):
1110 # rows = self.rowCount(parentindex)
1111 # parentItem = self.getItem(parentindex)
1112 # for row in range(rows-1,-1,-1):
1113 # item = parentItem.child(row)
1114 # if item.itemData[0] == 'External pressure layer':
1115 # self.removeRows(row, 1, parentindex)
1116  self.setSlenderData(self.slenderdata.extpresslayer, parentindex, 'External pressure layer')
1117  self.updateLayermodel(parentindex)
1118  # update the scenario data
1119  self.updateScenarioModel()
1120  if hasattr(self, 'timehists'):
1121  self.updateTimehistoryModel()
1122  self.layoutChanged.emit()
1123 
1124  # noinspection PyUnresolvedReferences
1125  def updateLayermodel(self, parentindex):
1126 
1127  rows = self.rowCount(parentindex)
1128  layers = self.slenderdata.num_layers()
1129  parentItem = self.getItem(parentindex)
1130  layerrows = []
1131  # finding rows with layerdata
1132  for row in range(rows):
1133  item = parentItem.child(row)
1134 
1135  if item.itemData[0] == 'Data for layer':
1136  layerrows.append(row)
1137 
1138  if len(layerrows) > layers:
1139  # remove extra layers
1140  for i in range(len(layerrows) - 1, layers - 1, -1):
1141  self.removeRows(layerrows[i], 1, parentindex)
1142  elif len(layerrows) < layers:
1143  # insert extra for layers
1144  row = layerrows[-1] + 1
1145  self.insertRows(row, layers - len(layerrows), parentindex)
1146  row-=1
1147  for i in range(layers - len(layerrows)):
1148  row += 1
1149  item = parentItem.child(row)
1150  item.setData(0, 'Data for layer')
1151  item.setData(1, len(layerrows) + i + 1)
1152 
1153  count=0
1154  for i in range(layers):
1155  layerparent = self.index(layerrows[0] + i, 0, parentindex)
1156 
1157  if len(self.slenderdata.layer_type) >= i + 1:
1158  self.setSlenderData(self.slenderdata.layer_type[i], layerparent, 'Type')
1159  else:
1160  self.setSlenderData('wires', layerparent, 'Type')
1161 
1162  if len(self.slenderdata.layer_radii) >= i + 1:
1163  self.setSlenderData(self.slenderdata.layer_radii[i], layerparent, 'Radius')
1164  else:
1165  self.setSlenderData([None], layerparent, 'Radius')
1166 
1167  if len(self.slenderdata.layer_radii) >= i + 1:
1168  self.setSlenderData(self.slenderdata.thickness[i], layerparent, 'Thickness')
1169  else:
1170  self.setSlenderData([None], layerparent, 'Thickness')
1171 
1172  if count>0:
1173  if len(self.slenderdata.gap_ini) >= i + 1:
1174  self.setSlenderData(self.slenderdata.gap_ini[i], layerparent, 'Initial gap')
1175  else:
1176  self.setSlenderData([None], layerparent, 'Initial gap')
1177 
1178  if len(self.slenderdata.youngs_modulus) >= i + 1:
1179  self.setSlenderData(self.slenderdata.youngs_modulus[i], layerparent, 'Youngs modulus')
1180  else:
1181  self.setSlenderData([None], layerparent, 'Youngs modulus')
1182 
1183  if len(self.slenderdata.poisson) >= i + 1:
1184  self.setSlenderData(self.slenderdata.poisson[i], layerparent, "Poisson's ratio")
1185  else:
1186  self.setSlenderData([None], layerparent, "Poisson's ratio")
1187 
1188  if count>0:
1189  if len(self.slenderdata.fricfac) >= i + 1:
1190  self.setSlenderData(self.slenderdata.fricfac[i], layerparent, 'Friction factor')
1191  else:
1192  self.setSlenderData([None], layerparent, 'Friction factor')
1193 
1194  if self.slenderdata.layer_type[i]=='wires':
1195  if len(self.slenderdata.lay_angle) >= i + 1:
1196  self.setSlenderData(self.slenderdata.lay_angle[i], layerparent, 'Lay angle')
1197  else:
1198  self.setSlenderData([None], layerparent, 'Lay angle')
1199  elif self.slenderdata.layer_type[i]=='sheath':
1200  self.removeSlenderData(layerparent, 'Lay angle')
1201 
1202  if self.slenderdata.layer_type[i]=='wires':
1203  if len(self.slenderdata.comp_number) >= i + 1:
1204  self.setSlenderData(self.slenderdata.comp_number[i], layerparent, 'Number of tendons')
1205  else:
1206  self.setSlenderData([None], layerparent, 'Number of tendons')
1207  elif self.slenderdata.layer_type[i]=='sheath':
1208  self.removeSlenderData(layerparent, 'Number of tendons')
1209 
1210  if self.slenderdata.layer_type[i]=='wires':
1211  if len(self.slenderdata.lay_angle) >= i + 1:
1212  self.setSlenderData(self.slenderdata.width[i], layerparent, 'Width')
1213  else:
1214  self.setSlenderData([None], layerparent, 'Width')
1215  elif self.slenderdata.layer_type[i]=='sheath':
1216  self.removeSlenderData(layerparent, 'Width')
1217  count+=1
1218 
1219  # noinspection PyUnresolvedReferences
1221  parentindex = self.index(1, 0, QtCore.QModelIndex())
1222  if hasattr(self.slenderdata, 'typical_curvature'):
1223  self.setSlenderData(self.slenderdata.typical_curvature, parentindex, 'Typical curvature')
1224  if hasattr(self.slenderdata, 'typical_tension'):
1225  self.setSlenderData(self.slenderdata.typical_tension, parentindex, 'Typical tension')
1226  if hasattr(self.slenderdata, 'internal_pressure'):
1227  self.setSlenderData(self.slenderdata.internal_pressure, parentindex, 'Internal pressure')
1228 
1230  parentindex = QtCore.QModelIndex()
1231  rows = self.rowCount(parentindex)
1232  for i in range(rows):
1233  index = self.index(i, 0, parentindex)
1234  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1235  if itemtext == 'Global results':
1236  subindex = index
1237  subParentItem = self.getItem(subindex)
1238  break
1239  try:
1240  # noinspection PyUnboundLocalVariable
1241  subindex
1242  except UnboundLocalError:
1243  parentItem = self.getItem(parentindex)
1244  parentItem.appendChild(TreeItem(['Global results', ''
1245  ], parentItem))
1246  nchildren = parentItem.childCount()
1247  subParentItem = parentItem.child(nchildren - 1)
1248  subindex = self.index(nchildren + 1, 0, parentindex)
1249  # noinspection PyUnboundLocalVariable
1250  nchildren = subParentItem.childCount()
1251  # checking that all time histories are there
1252  for timehistory in self.timehists:
1253  if hasattr(timehistory, 'directory'):
1254  nchildren = subParentItem.childCount()
1255  for i in range(nchildren):
1256  tmp = subParentItem.child(i)
1257  if timehistory.directory == tmp.data(1):
1258  subSubParentItem = subParentItem.child(i)
1259  try:
1260  subSubParentItem
1261  except UnboundLocalError:
1262  subParentItem.appendChild(
1263  TreeItem(['Timehistories from directory', timehistory.directory], subParentItem))
1264  nchildren = subParentItem.childCount()
1265  subSubParentItem = subParentItem.child(nchildren - 1)
1266  found=0
1267  for i in range(subSubParentItem.childCount()):
1268  if timehistory.name == subSubParentItem.child(i).data(1):
1269  found=1
1270  if found==0:
1271  subSubParentItem.appendChild(TreeItem(['Time history file', timehistory.name], subSubParentItem))
1272 
1273  else:
1274 
1275  found=0
1276  for i in range(subParentItem.childCount()):
1277  if timehistory.name == subParentItem.child(i).data(1):
1278  found=1
1279  if found == 0:
1280  subParentItem.appendChild(TreeItem(['Time history package', timehistory.name]
1281  , subParentItem))
1282  # todo add removal of time series that are no longer present
1283 
1284  def setSlenderData(self, data, parentindex, tag):
1285  """
1286  :param data: the data to be inserted in the model
1287  :param parentindex: The index of the parent under which the data is to be put
1288  :param tag: The text that belongs to the data
1289  :return: nothing
1290  """
1291  rows = self.rowCount(parentindex)
1292  for row in range(rows):
1293  index = self.index(row, 0, parentindex)
1294  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1295  if itemtext == tag:
1296  dataindex = self.index(row, 1, parentindex)
1297  if not data:
1298  self.setData(dataindex, str(data))
1299  elif isinstance(data, float):
1300  self.setData(dataindex, str(data))
1301  elif isinstance(data, int):
1302  self.setData(dataindex, str(data))
1303  elif isinstance(data, str):
1304  self.setData(dataindex, data)
1305  else:
1306  for i in range(len(data)):
1307  if i == 0:
1308  datastr = str(data[i])
1309  else:
1310  # noinspection PyUnboundLocalVariable
1311  datastr = datastr + ',' + str(data[i])
1312  # noinspection PyUnboundLocalVariable
1313  self.setData(dataindex, datastr)
1314  if tag == "Internal pressure layer" or tag =="External pressure layer":
1315  item=self.getItem(index)
1316  item.updateitemoptions(list(map(str, list(range(1,len(self.slenderdata.layer_radii)+1)))))
1317 
1318 
1319  return
1320 
1321  parentItem = self.getItem(parentindex)
1322  if data is None or data == 'None':
1323  dataindex = self.index(rows + 1, 1, parentindex)
1324  self.setData(dataindex, data)
1325  return
1326  elif isinstance(data, float):
1327  datastr = str(data)
1328  elif isinstance(data, str):
1329  datastr = str(data)
1330  elif isinstance(data, int):
1331  datastr = str(data)
1332  else:
1333  for i in range(len(data)):
1334  if i == 0:
1335  datastr = str(data[i])
1336  else:
1337  # noinspection PyUnboundLocalVariable
1338  datastr = datastr + ',' + str(data[i])
1339  # noinspection PyUnboundLocalVariable
1340 
1341  if tag =='Type':
1342  parentItem.appendChild(ModelTreeItem([tag, datastr], parentItem,type='combo'))
1343  elif tag == "Internal pressure layer":
1344  parentItem.appendChild(ModelTreeItem([tag, datastr], parentItem,type='presslayer',
1345  nopt=len(self.slenderdata.layer_radii)))
1346  elif tag == "External pressure layer":
1347  parentItem.appendChild(ModelTreeItem([tag, datastr], parentItem,type='presslayer',
1348  nopt=len(self.slenderdata.layer_radii)))
1349  else:
1350  parentItem.appendChild(ModelTreeItem([tag, datastr], parentItem))
1351 
1352  dataindex = self.index(rows + 1, 1, parentindex)
1353  self.setData(dataindex, data)
1354 
1355  def removeSlenderData(self, parentindex, tag):
1356  rows = self.rowCount(parentindex)
1357  for row in range(rows):
1358  index = self.index(row, 0, parentindex)
1359  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1360  if itemtext == tag:
1361  self.getItem(parentindex).removeChildren(row,1)
1362 
1363  # noinspection PyUnresolvedReferences
1364  def addLayer(self):
1365  # TODO add all stuff the layer can have.
1366  self.slenderdata.layer_type.append('wires')
1367  self.slenderdata.layer_radii.append(0.0)
1368  self.slenderdata.thickness.append([0.0])
1369  self.slenderdata.gap_ini.append([0.0])
1370  self.slenderdata.youngs_modulus.append(0.0)
1371  self.slenderdata.poisson.append(0.0)
1372  self.slenderdata.fricfac.append(0.0)
1373  self.slenderdata.lay_angle.append(0.0)
1374  self.slenderdata.comp_number.append(0.0)
1375  self.slenderdata.width.append(0.0)
1376 
1377  def addTimeHist(self, name, parent=None):
1378  if not parent:
1379  subParentItem = self.addGlobalResults()
1380  subParentItem.appendChild(TreeItem(['Time history package', name]
1381  , subParentItem))
1382  else:
1383  parent.appendChild(TreeItem(['Time history file', name]
1384  , parent))
1385 
1386  def addGlobalResults(self):
1387  parentindex = QtCore.QModelIndex()
1388  rows = self.rowCount(parentindex)
1389  # finding out whether we already have time histories
1390  for row in range(rows):
1391  index = self.index(row, 0, parentindex)
1392  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1393  if itemtext == 'Global results':
1394  subindex = index
1395  subParentItem = self.getItem(subindex)
1396  break
1397  try:
1398  # noinspection PyUnboundLocalVariable
1399  subindex
1400  except UnboundLocalError:
1401  parentItem = self.getItem(parentindex)
1402  parentItem.appendChild(TreeItem(['Global results', ''
1403  ], parentItem))
1404  nchildren = parentItem.childCount()
1405  subParentItem = parentItem.child(nchildren - 1)
1406  # noinspection PyUnboundLocalVariable
1407  return subParentItem
1408 
1409  def findTimehist(self, name):
1410  """
1411  :param name: Nema of the timehist
1412  :return: the index in which has the same name, None is returned if not found
1413  """
1414  for i in range(len(self.timehists)):
1415  if self.timehists[i].name == name:
1416  return i
1417  return None
1418 
1419  @staticmethod
1420  def addGlobalDirectory(parentItem, directory):
1421  parentItem.appendChild(TreeItem(['Timehistories from directory', directory
1422  ], parentItem))
1423  nchildren = parentItem.childCount()
1424  return parentItem.child(nchildren - 1)
1425 
1426  def addCalc(self, key='friction'):
1427  if key == 'friction':
1428  text = "Friction calculation"
1429  data = "To check importance of friction"
1430  elif key == 'full':
1431  text = 'Full stress calculation'
1432  data = ''
1433  else:
1434  print('Error adding calculation to tree model')
1435  parentindex = QtCore.QModelIndex()
1436  rows = self.rowCount(parentindex)
1437  found = 0
1438  for row in range(rows):
1439  index = self.index(row, 0, parentindex)
1440  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1441  if itemtext == 'Calculations':
1442  parentindex = index
1443  subrows = self.rowCount(parentindex)
1444  for subrow in range(subrows):
1445  index = self.index(subrow, 0, parentindex)
1446  itemtext = self.data(index, QtCore.Qt.DisplayRole)
1447  # noinspection PyUnboundLocalVariable
1448  if itemtext == text:
1449  found = 1
1450  break
1451  if found == 0:
1452  parentItem = self.getItem(parentindex)
1453  # noinspection PyUnboundLocalVariable
1454  parentItem.appendChild(TreeItem([text, data]
1455  , parentItem))
1456  self.layoutChanged.emit()
1457 
1458  def recParentValidate(self, index, parenttext):
1459  """ method that find out is any forefather has the given text in its first column
1460  :param index: The index of the item in question.
1461  :param parenttext: the text to be searched for in forefathers"""
1462 
1463  parentIndex = self.parent(index)
1464  if parentIndex == QtCore.QModelIndex():
1465  return False
1466  item = self.getItem(parentIndex)
1467  itemtext = item.itemData[0]
1468  if itemtext == parenttext:
1469  return True
1470  else:
1471  answer = self.recParentValidate(parentIndex, parenttext)
1472  return answer
1473 
1474  # noinspection PyUnresolvedReferences
1475  def setupModelData(self, parent):
1476  """ used to set up the model. should be rewritten to use data or setdata to avoid duplication.
1477  :param parent: The root item in all cases
1478  :return: nothing
1479  """
1480  parents = [parent]
1481  # Cross sectional data
1482  parents[0].appendChild(TreeItem(['Model data', 'Containing the model'], parents[0]))
1483  parents.append(parents[-1].child(parents[-1].childCount() - 1))
1484 
1485  # Data for a given layer
1486  for i in range(len(self.slenderdata.layer_radii)):
1487  if i > 0:
1488  parents.pop()
1489  parents[1].appendChild(TreeItem(['Data for layer', i + 1], parents[1]))
1490  parents.append(parents[-1].child(parents[-1].childCount() - 1))
1491  if hasattr(self.slenderdata, 'layer_type'):
1492  parents[2].appendChild(ModelTreeItem(['Type', str(self.slenderdata.layer_type[i])], parents[2],type='combo'))
1493 
1494  if hasattr(self.slenderdata, 'layer_radii'):
1495  parents[2].appendChild(TreeItem(['Radius', str(self.slenderdata.layer_radii[i])], parents[2]))
1496 
1497  if hasattr(self.slenderdata, 'thickness'):
1498  parents[2].appendChild(TreeItem(['Thickness', str(self.slenderdata.thickness[i])], parents[2]))
1499  if i>0:
1500  if hasattr(self.slenderdata, 'gap_ini'):
1501  parents[2].appendChild(TreeItem(['Initial gap', str(self.slenderdata.thickness[i])], parents[2]))
1502 
1503  if hasattr(self.slenderdata, 'youngs_modulus'):
1504  parents[2].appendChild(
1505  TreeItem(['Youngs modulus', str(self.slenderdata.youngs_modulus[i])], parents[2]))
1506 
1507  if hasattr(self.slenderdata, "poisson"):
1508  parents[2].appendChild(
1509  TreeItem(["Poisson's ratio", str(self.slenderdata.poisson[i])], parents[2]))
1510 
1511  if hasattr(self.slenderdata, 'fricfac'):
1512  parents[2].appendChild(TreeItem(['Friction factor', str(self.slenderdata.fricfac[i])], parents[2]))
1513 
1514  #specific for wire layers
1515  if self.slenderdata.layer_type[i]=='wires':
1516 
1517  if hasattr(self.slenderdata, 'lay_angle'):
1518  parents[2].appendChild(TreeItem(['Lay angle', str(self.slenderdata.lay_angle[i])], parents[2]))
1519 
1520  if hasattr(self.slenderdata, 'comp_number'):
1521  parents[2].appendChild(
1522  TreeItem(['Number of tendons', str(self.slenderdata.comp_number[i])], parents[2]))
1523 
1524  if hasattr(self.slenderdata, 'width'):
1525  parents[2].appendChild(TreeItem(['Width', str(self.slenderdata.thickness[i])], parents[2]))
1526 
1527 
1528  # Layers for internal and external pressure
1529  parents.pop()
1530  parents[1].appendChild(ModelTreeItem(['Internal pressure layer', str(self.slenderdata.intpresslayer)],
1531  parents[1],type='presslayer',nopt=len(self.slenderdata.layer_radii)))
1532  parents[1].appendChild(ModelTreeItem(['External pressure layer', str(self.slenderdata.extpresslayer)],
1533  parents[1],type='presslayer',nopt=len(self.slenderdata.layer_radii)))
1534  parents.pop()
1535  # Data for analysis scenario
1536  parents[0].appendChild(TreeItem(['Scenario definition', 'Used for checking assumptions'], parents[0]))
1537  parents.append(parents[0].child(parents[0].childCount() - 1))
1538  if hasattr(self.slenderdata, 'typical_tension'):
1539  parents[1].appendChild(TreeItem(['Typical tension', str(self.slenderdata.typical_tension)], parents[1]))
1540  if hasattr(self.slenderdata, 'typical_curvature'):
1541  parents[1].appendChild(TreeItem(['Typical curvature', str(self.slenderdata.typical_curvature)], parents[1]))
1542  if hasattr(self.slenderdata, 'internal_pressure'):
1543  parents[1].appendChild(TreeItem(['Internal pressure', str(self.slenderdata.internal_pressure)], parents[1]))
1544  parents[0].appendChild(TreeItem(['Calculations', ''], parents[0]))
1545 
1547  def __init__(self, names, parent=None):
1548  super(FullResultTreeModel, self).__init__(parent)
1549  self.rootItem = TreeItem(("Active?", "Item"))
1550  for i in names:
1551  self.rootItem.appendChild(TreeItem(['No', i], self.rootItem))
1552  self.activePlots = []
1553  self.names = names
1555  self.plotData = []
1556 
1557  def add_result(self, number):
1558  item = self.rootItem.child(number)
1559  fname = 'tmp/fullresult_' + str(number) + '.h5'
1560  f = h5py.File(fname, 'r')
1561  layer_groups = f[self.names[number] + '/AxialStress']
1562  layers = len(layer_groups)
1563 
1564  for i in range(layers):
1565  item.appendChild(TreeItem(['No', 'Layer number %d' % (i + 1)], item))
1566  subitem = item.child(i)
1567  subitem.appendChild(TreeItem(['No', 'Axial stress'], subitem))
1568 
1569  subitem.appendChild(TreeItem(['No', 'Local bending stress'], subitem))
1570  subsubitem = subitem.child(-1)
1571  ntheta = f[self.names[number] + '/LocalBendingStress'][str(i)].shape[1]
1572  for j in range(ntheta):
1573  # assumption: uniform thetas
1574  subsubitem.appendChild(TreeItem(['No', 'Theta = %f' % float(float(j) * 2 * np.pi /
1575  float(ntheta))], subsubitem))
1576  if f[self.names[number] + '/LocalBendingStress'][str(i)].ndim==3:
1577  subsubsubitem = subsubitem.child(j)
1578  nphi = f[self.names[number] + '/LocalBendingStress'][str(i)].shape[2]
1579  for k in range(nphi):
1580  if nphi == 4:
1581  # assumption: corners of a square chosen
1582  subsubsubitem.appendChild(TreeItem(['No', 'Corner number = %d' % (k + 1)], subsubsubitem))
1583 
1584  else:
1585  # assumption: uniform phi chosen
1586  subsubsubitem.appendChild(TreeItem(['No', 'Phi = %f' % float(float(k) * 2 * np.pi /
1587  float(nphi))], subsubsubitem))
1588 
1589  if f[self.names[number] + '/LocalBendingStress'][str(i)].ndim==3:
1590  subitem.appendChild(TreeItem(['No', 'Friction stress'], subitem))
1591  subsubitem = subitem.child(-1)
1592 
1593  for j in range(ntheta):
1594  subsubitem.appendChild(TreeItem(['No', 'Theta = %f' % float(float(j) * 2 * np.pi /
1595  float(ntheta))], subsubitem))
1596 
1597  subitem.appendChild(TreeItem(['No', 'Stress resultant'], subitem))
1598  # Stress resultant
1599  subsubitem = subitem.child(-1)
1600  ntheta = f[self.names[number] + '/StressResultant'][str(i)].shape[1]
1601  for j in range(ntheta):
1602  # assumption: uniform thetas
1603  subsubitem.appendChild(TreeItem(['No', 'Theta2 = %f' % float(float(j) * 2 * np.pi /
1604  float(ntheta))], subsubitem))
1605  if f[self.names[number] + '/LocalBendingStress'][str(i)].ndim==3:
1606  subsubsubitem = subsubitem.child(j)
1607  nphi = f[self.names[number] + '/StressResultant'][str(i)].shape[2]
1608  for k in range(nphi):
1609  if nphi == 4:
1610  # assumption: corners of a square chosen
1611  subsubsubitem.appendChild(TreeItem(['No', 'Corner number = %d' % (k + 1)], subsubsubitem))
1612 
1613  else:
1614  # assumption: uniform phi chosen
1615  subsubsubitem.appendChild(TreeItem(['No', 'Phi = %f' % float(float(k) * 2 * np.pi /
1616  float(nphi))], subsubsubitem))
1617  # fill inn here
1618  if f[self.names[number] + '/LocalBendingStress'][str(i)].ndim==3:
1619  subitem.appendChild(TreeItem(['No', 'Critical curvature'], subitem))
1620  subitem.appendChild(TreeItem(['No', 'Stick stress'], subitem))
1621  f.close()
1622  self.layoutChanged.emit()
1623 
1624  # noinspection PyMethodMayBeStatic
1625  def flags(self, index):
1626  """
1627  Used to select the way each cell works
1628  :param index: the index of the item queried
1629  :return: view get info on items "Type"
1630  """
1631  if not index.isValid():
1632  return 0
1633  if index.column() == 0:
1634  return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
1635  else:
1636  return 0
1637 
1638  def toggle(self, index):
1639  """method for toggling, changing color of the recursive selection and reporting back which lines that are,
1640  added removed and the color of the added lines
1641  :param index: the index of the item being toggled
1642  """
1643 
1644  # list of colors for distuishible plotting
1645  colorlist = self.colorlist()
1646 
1647  item = self.getItem(index) #Funker ikke!
1648  if item.itemData[0] == 'No':
1649  finalstate = 'Yes'
1650  elif item.itemData[0] == 'Yes':
1651  finalstate = 'No'
1652  elif item.itemData[0] == 'Partly':
1653  finalstate = 'No'
1654  else:
1655  print('Internal error, unknown toggle state in result tree.')
1656  return
1657  if not self.colorIndexTaken:
1658  for i in range(len(colorlist)):
1659  self.colorIndexTaken.append(0)
1660 
1661  self.toggler(index, finalstate, colorlist)
1662 
1663  def toggler(self, index, finalstate, colorlist):
1664  """toggles index including children, and build info for plotting
1665  :param colorlist: list of colors applied in plot and tree_model
1666  :param finalstate: The selected items final state (Yes or No)
1667  :param index: the index of the item selected
1668  """
1669 
1670  # we need to go up to find the parents on the way first.
1671  # To collate the information we need to retrive data.
1672  # also we use this walk to change column 0
1673  item = self.getItem(index)
1674  item.setData(0, finalstate)
1675  siblingnumber = [item.row()]
1676  keep_item = item
1677  item = item.parent()
1678  if hasattr(self, 'plotData'):
1679  del self.plotData
1680  self.plotData = []
1681 
1682  while item.parent():
1683  keep_item = item
1684  siblingnumber.append(item.row())
1685  nos = False
1686  yeses = False
1687  for i in range(item.childCount()):
1688  if item.child(i).itemData[0] == 'No':
1689  nos = True
1690  elif item.child(i).itemData[0] == 'Yes':
1691  yeses = True
1692  elif item.child(i).itemData[0] == 'Partly':
1693  yeses = True
1694  nos = True
1695 
1696  if yeses and nos:
1697  item.setData(0, 'Partly')
1698  elif yeses:
1699  item.setData(0, 'Yes')
1700  elif nos:
1701  item.setData(0, 'No')
1702  item = item.parent()
1703 
1704  item = keep_item
1705 
1706  treedata = [item.itemData[1]]
1707  for i in range(len(siblingnumber) - 1):
1708  item = item.child(siblingnumber[-(i + 2)])
1709  treedata.append(item.itemData[1])
1710 
1711  level = len(treedata)
1712  print('children', item.childCount())
1713  if item.childCount() > 0:
1714  self.recursiveplot(item, colorlist, treedata, level, finalstate)
1715  else:
1716  self.singleplot(treedata, colorlist, finalstate, item)
1717 
1718  self.layoutChanged.emit()
1719 
1720  def singleplot(self, treedata, colorlist, finalstate, item):
1721  print('len(treeData', len(treedata))
1722  if len(treedata) == 3:
1723  if finalstate == 'Yes':
1724  self.plotData.append(timehist.PlotData(treedata, colorlist, self.colorIndexTaken, 'Add'))
1725  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1726  elif finalstate == 'No':
1727  self.plotData.append(timehist.PlotData(treedata, colorlist, self.colorIndexTaken, 'Remove'))
1728  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1729  if len(treedata) == 4:
1730  if finalstate == 'Yes':
1731  self.plotData.append(timehist.FourLevelPlotData(treedata, colorlist, self.colorIndexTaken, 'Add'))
1732  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1733  elif finalstate == 'No':
1734  self.plotData.append(timehist.FourLevelPlotData(treedata, colorlist, self.colorIndexTaken, 'Remove'))
1735  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1736  if len(treedata) == 5:
1737  if finalstate == 'Yes':
1738  self.plotData.append(timehist.FiveLevelPlotData(treedata, colorlist, self.colorIndexTaken, 'Add'))
1739  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1740 
1741  elif finalstate == 'No':
1742  self.plotData.append(timehist.FiveLevelPlotData(treedata, colorlist, self.colorIndexTaken, 'Remove'))
1743  self.plotData[-1].update(self.activePlots, self.colorIndexTaken)
1744  if finalstate == 'Yes':
1745  item.setColor(self.plotData[-1].color)
1746  elif finalstate == 'No':
1747  item.setColor(None)
1748 
1749  def recursiveplot(self, item, colorlist, treedata, level, finalstate):
1750 
1751  level += 1
1752  children = item.childCount()
1753  for i in range(children):
1754  if level > 0:
1755  data = treedata[0:level]
1756  else:
1757  data = treedata
1758  subitem = item.child(i)
1759  data.append(subitem.itemData[1])
1760  subitem.setData(0, finalstate)
1761  if subitem.childCount() > 0:
1762  self.recursiveplot(subitem, colorlist, data, level, finalstate)
1763  else:
1764  self.singleplot(data, colorlist, finalstate, subitem)
1765 
1766  @staticmethod
1767  def colorlist():
1768  return [(103, 0, 13), (63, 0, 125), (127, 39, 4), (0, 68, 27), (8, 48, 107), (165, 15, 21), (84, 39, 143),
1769  (166, 54, 3), (0, 109, 44), (8, 81, 156), (203, 24, 29), (106, 81, 163), (217, 72, 1),
1770  (35, 139, 69), (33, 113, 181), (239, 59, 44), (128, 125, 186), (241, 105, 19), (65, 171, 93),
1771  (66, 146, 198), (251, 106, 74), (158, 154, 200), (253, 141, 60), (116, 196, 118), (107, 174, 214),
1772  (252, 146, 114), (188, 189, 220), (253, 174, 107), (161, 217, 155), (158, 202, 225)]
1773 
1774  def data(self, index, role):
1775  """ Do not know. called by the view to get hold of the data I believe
1776  :param index: the index
1777  :param role: the role
1778  :return:the data in display friendly mode
1779  """
1780  if not index.isValid():
1781  return None
1782  if role == QtCore.Qt.DisplayRole:
1783  item = index.internalPointer()
1784  return item.data(index.column())
1785 
1786  if role == QtCore.Qt.ForegroundRole:
1787  item = index.internalPointer()
1788  if item.Color():
1789  color = item.Color()
1790  # return QtGui.QColor.fromRgb(int(color[0]),int(color[1]),int(color[2]))
1791  return QtGui.QColor.fromRgb(int(color[0]), int(color[1]), int(color[2]))
1792  # return QtGui.QColor.fromRgb(color)
1793 
1794  if role == QtCore.Qt.TextColorRole:
1795  return QtCore.Qt.blue
1796  return None
1797 
1798 def main():
1799  """ runs the shit.
1800  :return:nothing
1801  """
1802  app = QtGui.QApplication(sys.argv)
1803  mainwindow = Window()
1804  mainwindow.show()
1805  sys.exit(app.exec_())
1806 
1807 if __name__ == '__main__':
1808  main()
def setupUi(self, MainWindow)
def flags(self, index)
Definition: main.py:1046
def row(self)
Definition: main.py:937
def close_edittab(self, index)
Definition: main.py:768
def recParentValidate(self, index, parenttext)
Definition: main.py:1458
fullResultWidget
Definition: main.py:112
def addLayer(self)
Definition: main.py:1364
def data(self, index, role)
Definition: main.py:1774
fullResultsExportButton
Definition: main.py:116
def setData(self, column, value)
Definition: main.py:942
main_frame
Definition: main.py:42
def eventFilter(self, obj, event)
Definition: main.py:787
def toggle(self, index)
Definition: main.py:1638
fullstress
Definition: main.py:102
def __init__(self, parent=None)
Definition: main.py:1040
def treemodel_setup(self)
Definition: main.py:651
def analytical_input(inputfile, delimiter, commentchar)
Definition: pyflex.py:18
message_pane
Definition: main.py:80
def add_frictioncalc(self)
Definition: main.py:326
def toggler(self, index, finalstate, colorlist)
Definition: main.py:1663
def license(self)
Definition: main.py:678
def calculate_friction(self)
Definition: main.py:342
fullResultLeftWidget
Definition: main.py:114
def remove_fullcalc_result(self)
Definition: main.py:309
fullResultView
Definition: main.py:108
def findTimehist(self, name)
Definition: main.py:1409
def __init__(self, parent=None)
Definition: main.py:36
def datacheck(self)
Definition: main.py:408
def errorhandling(self, text)
Definition: main.py:728
def removeRows(self, position, rows, parent=QtCore.QModelIndex())
def messagehandling(self, text)
Definition: main.py:739
def setup_fullcalc_results(self)
Definition: main.py:263
def updateTimehistoryModel(self)
Definition: main.py:1229
def removeChildren(self, position, count)
Definition: main.py:928
def add_result(self, number)
Definition: main.py:1557
def update_globaldata(self)
Definition: main.py:608
def mimeData(self, indexes)
Definition: main.py:1080
def singleplot(self, treedata, colorlist, finalstate, item)
Definition: main.py:1720
def setupModelData(self, parent)
Definition: main.py:1475
def __init__(self, data, parent=None, finalRow=None, color=None)
Definition: main.py:879
def setColor(self, color)
Definition: main.py:886
def addCalc(self, key='friction')
Definition: main.py:1426
def main()
Definition: main.py:1798
def itemcheck(item, inputstring)
Definition: main.py:969
def update_actions(self)
Definition: main.py:131
def import_ts_folder(self)
Definition: main.py:705
def close_graphictab(self, index)
Definition: main.py:756
def add_ts(self, import_type, info, directory, ts_type='full')
Definition: main.py:832
def setSlenderData(self, data, parentindex, tag)
Definition: main.py:1284
fullResultProxy
Definition: main.py:285
def update_scenariodata(self)
Definition: main.py:577
def updateitemoptions(self, options)
Definition: main.py:966
fullResultTree
Definition: main.py:110
rightsplitter
Definition: main.py:56
def open_context_menu(self, position)
Definition: main.py:150
def data(self, index, role)
def append_ts(self, name, directory, ts_type='full')
Definition: main.py:851
def show_graphictab(self)
Definition: main.py:750
def addGlobalDirectory(parentItem, directory)
Definition: main.py:1420
def addGlobalResults(self)
Definition: main.py:1386
def setData(self, index, value, role=QtCore.Qt.EditRole)
def fricplot(self)
Definition: main.py:402
def add_fullcalc_results(self, number)
Definition: main.py:323
def index(self, row, column, parent)
def recursiveplot(self, item, colorlist, treedata, level, finalstate)
Definition: main.py:1749
def put_import(self)
Definition: main.py:686
def addTimeHist(self, name, parent=None)
Definition: main.py:1377
def removeSlenderData(self, parentindex, tag)
Definition: main.py:1355
def update_slenderdata(self)
Definition: main.py:431
mainsplitter
Definition: main.py:46
leftsplitter
Definition: main.py:58
def import_ts(self)
Definition: main.py:690
def insertRows(self, position, rows, parent=QtCore.QModelIndex())
def data(self, column)
Definition: main.py:919
def insertChildren(self, position, count, columns, finalRow=None)
Definition: main.py:892
def flags(self, index)
Definition: main.py:1625
def mimeTypes()
Definition: main.py:1077
fullResultLeftLayout
Definition: main.py:106
def add_full_calc(self)
Definition: main.py:238
def update_layerdata(self, subindex, parentindex)
Definition: main.py:453
def show_full_results(self)
Definition: main.py:383
def columnCount(self)
Definition: main.py:916
Definition: main.py:1
def child(self, row)
Definition: main.py:910
def parent(self)
Definition: main.py:925
def update_fullplot(self, selected)
Definition: main.py:317
def frictionedit(self)
Definition: main.py:330
commentchar
Definition: main.py:672
def __init__(self, names, parent=None)
Definition: main.py:1547
def updateLayermodel(self, parentindex)
Definition: main.py:1125
def __init__(self, data, parent=None, finalRow=None, color=None, type=None, nopt=None)
Definition: main.py:957
def childCount(self)
Definition: main.py:913
tree_model
Definition: main.py:658
def open(self)
Definition: main.py:663
def appendChild(self, item)
Definition: main.py:907
def open_tab(tab_widget, intext)
Definition: main.py:1024
def menuactions(self)
Definition: main.py:639
def fullcalc(self)
Definition: main.py:253
def updateModel(self)
Definition: main.py:1097
graphictab
Definition: main.py:62
def updateScenarioModel(self)
Definition: main.py:1220
def Color(self)
Definition: main.py:889
def show_friction_results(self)
Definition: main.py:348
def fulledit(self)
Definition: main.py:243