iam-git / WellMet (public) (License: MIT) (since 2021-08-31) (hash sha1)
WellMet is pure Python framework for spatial structural reliability analysis. Or, more specifically, for "failure probability estimation and detection of failure surfaces by adaptive sequential decomposition of the design domain".
List of commits:
Subject Hash Author Date (UTC)
qt_gui.qt_pairwise: prepare Contact widget bfa78d7493f5eb04b6bd3a4ad26dd1a92d17a895 I am 2022-11-09 03:36:05
qt_gui.qt_pairwise: prepare more mouse event signals c60e613508480c68483b3d0d6ad6c876b27f539c I am 2022-11-08 01:55:14
qt_gui: introduce reworked matrix view window e28b95c5f418a7a3cea0cb84ca82b40275a71061 I am 2022-11-07 02:20:45
introduce wireframe module for the contacts finding functionality b6068dd92663699859ea7cbf3aac00178d120e0f I am 2022-10-25 14:24:37
voronoi.TwoPoints: atleast_2d() one line fix 9f8bd9e5370ccf30887b6218331ee664788a3b91 I am 2022-10-25 07:09:57
voronoi: implement faster TwoPoints class. c0af78f64bc78a6b8cf06e3ea244339549318b66 I am 2022-10-24 13:03:26
voronoi: implement TwoHorses class. Třída je, bohužel, bezcenná :( 4f6fe186f3f344fa7ee9e518798499099615b466 I am 2022-10-23 10:00:43
voronoi: WIP 23c63ede5bc2ec51d25aed850dc59299db438e34 I am 2022-10-21 12:27:01
IS_stat.sample_alike: use any possible fallback options to sample 80fb6d086e9f17350a1725a319e40bf29591869e I am 2022-10-20 08:56:42
voronoi: WIP ba912d406de12142f2e15a73090118184a0166a4 I am 2022-10-20 02:43:12
IS_stat: add sample_alike() function 2e5394d264b7aaaf5f2486c736ed8cc37afbd030 I am 2022-10-19 13:00:17
voronoi: WIP c3bfa60b6db2042df11528fe95a51d7cc88d3c6b I am 2022-10-19 11:18:13
voronoi: WIP baff3c5ccaf857f60194917fe5d6e33c40b01265 I am 2022-10-19 09:28:33
voronoi.ConvexSpline: little fix of np.sign() for better sleep 968f649e54d97abd596cd60749872fa3ef788c06 I am 2022-10-19 06:28:46
implement even more optimized Convex.. now ConvexSpline class c08511aecb32b880e73c9f10d07feff4dc588e8b I am 2022-10-19 04:11:13
voronoi: WIP cbb61d4544367a67c9a5c3fe6d64a9dc284eb364 I am 2022-10-18 05:05:44
voronoi: WIP e9c247fef30cfb678bad9b955d6f6a94a0ff61e7 I am 2022-10-18 01:02:30
candynodex: hotfix to support numpy masking indexing f359123b72a3d998d5eed4b9e611a5e402a18c8d I am 2022-10-17 09:02:33
add new lightweight candynodes module to replace old heavy ugly candybox ca97509f47c100df90e1e06d82ed7c759627bfd0 I am 2022-10-17 06:31:33
qt_gui: move CandyBox creating to the individual DiceBox widgets 29253625129219b5e550f82cae3da0e53ef5bd47 I am 2022-10-16 03:17:55
Commit bfa78d7493f5eb04b6bd3a4ad26dd1a92d17a895 - qt_gui.qt_pairwise: prepare Contact widget
Author: I am
Author date (UTC): 2022-11-09 03:36
Committer name: I am
Committer date (UTC): 2022-11-09 03:36
Parent(s): c60e613508480c68483b3d0d6ad6c876b27f539c
Signer:
Signing key:
Signing status: N
Tree: fe1ea7e9e63e6d537e19acd387f5a63af52f9c24
File Lines added Lines deleted
wellmet/qt_gui/qt_pairwise.py 307 13
File wellmet/qt_gui/qt_pairwise.py changed (mode: 100644) (index 3678c21..39ccfc0)
1 1 #!/usr/bin/env python #!/usr/bin/env python
2 2 # coding: utf-8 # coding: utf-8
3 3
4 import gc
4 5 import pyqtgraph as pg import pyqtgraph as pg
5 6 from pyqtgraph.Qt import QtGui, QtWidgets from pyqtgraph.Qt import QtGui, QtWidgets
6 7 from pyqtgraph.Qt import QtCore from pyqtgraph.Qt import QtCore
7 8
8 9 import numpy as np import numpy as np
9 10 from scipy import spatial # for distance matrix from scipy import spatial # for distance matrix
10 #from ..wireframe import ConvexSpline
11 from ..wireframe import ConvexSpline
11 12 from .. import reader from .. import reader
12 13
13 14
 
... ... class MatrixWindow(QtWidgets.QMainWindow):
200 201 self.dockables = [] self.dockables = []
201 202
202 203
203 #self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
204 204
205 205
206 dock = QtWidgets.QDockWidget("Contacts", self)
207 dock.setWidget(ContactWidget(self, dock))
208 self.dockables.append(dock)
209 self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
206 210
207 211
208 212
209 213 for dock in self.dockables: for dock in self.dockables:
210 214 self.view.addAction(dock.toggleViewAction()) self.view.addAction(dock.toggleViewAction())
211 215 #dock.setFloating(True) #dock.setFloating(True)
212
213 #self.w.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.items)
214
215
216
216
217
217 218 csv_filter = "CSV files (*.csv)" csv_filter = "CSV files (*.csv)"
218 219 npy_filter = "NumPy binary files (*.npy)" npy_filter = "NumPy binary files (*.npy)"
219 220 txt_filter = "Text files (*.txt)" txt_filter = "Text files (*.txt)"
 
... ... class MView(pg.ImageView):
463 464
464 465 def __getattr__(self, attr): def __getattr__(self, attr):
465 466 if attr == 'red': if attr == 'red':
466 return data[0]
467 return self.data[0]
467 468 if attr == 'green': if attr == 'green':
468 return data[1]
469 return self.data[1]
469 470 if attr == 'blue': if attr == 'blue':
470 return data[2]
471 return self.data[2]
471 472 raise AttributeError(attr) raise AttributeError(attr)
472 473
473 474
474 475 def on_slice_changed(self, nsim): def on_slice_changed(self, nsim):
475 #č resize nejde. Asi pyqtgraph drží referenci
476 #č resize nejde. Ani s gc. Asi pyqtgraph drží referenci
476 477 #č i když já pekně vím, že ta data kopíruje a pro Qt normalizuje #č i když já pekně vím, že ta data kopíruje a pro Qt normalizuje
477 478 self.data = np.empty((3, nsim, nsim)) self.data = np.empty((3, nsim, nsim))
478 479 #č zelené-červené barvy přepíše distance matrix #č zelené-červené barvy přepíše distance matrix
 
... ... class MView(pg.ImageView):
481 482 self.nsim = nsim self.nsim = nsim
482 483
483 484
484 def update(self):
485 self.setImage(self.data.T, levelMode='rgba')
485 def update(self, **kwargs):
486 self.setImage(self.data.T, levelMode='rgba', **kwargs)
486 487
487 488 def on_mouse_moved(self, evt): def on_mouse_moved(self, evt):
488 489 pos = evt[0] ## using signal proxy turns original arguments into a tuple pos = evt[0] ## using signal proxy turns original arguments into a tuple
 
... ... class DistanceMatrix:
578 579
579 580
580 581
582
583
584
585
586 class ContactWidget(pg.LayoutWidget):
587 def __init__(self, w, parent=None):
588 super().__init__(parent)
589 self.w = w
590
591 w.image_view.mouse_moved.connect(self.on_mouse_moved)
592 w.image_view.mouse_clicked.connect(self.on_mouse_dragged)
593 w.image_view.mouse_double_clicked.connect(self.on_double_click)
594 w.image_view.mouse_right_dragged.connect(self.on_mouse_dragged)
595
596 w.space_changed.connect(self.on_space_changed)
597 w.slice_changed.connect(self.on_nsim_changed)
598 #w.redraw_called.connect(self.hide)
599
600 n = w.slider.value()
601 size = n * (n - 1) // 2
602 self.condensed_contacts = np.zeros(size, dtype=np.int8)
603 self.mask = np.tri(n, k=-1, dtype=bool).T
604 self.nsim = n
605
606 self.setup()
607 self.kwargs = {}
608 self.setup_CS()
609
610 def on_nsim_changed(self, n):
611 try:
612 del self.condensed_qontacts
613 except AttributeError:
614 pass
615 size = n * (n - 1) // 2
616 gc.collect()
617 self.condensed_contacts.resize(size)
618 self.condensed_contacts[:] = 0
619 self.mask = np.tri(n, k=-1, dtype=bool).T
620 self.nsim = n
621
622 self.on_space_changed()
623
624 def on_space_changed(self, *args, **kwargs):
625 self.setup_CS()
626
627
628 def on_mouse_moved(self, x, y):
629 if (x == -1) or (x == y):
630 self.status_label.setText("")
631 return None
632
633 m = self.nsim
634 i, j = min(x, y), max(x, y)
635 entry = m * i + j - ((i + 2) * (i + 1)) // 2
636 try:
637 val = self.condensed_qontacts[entry]
638 except AttributeError:
639 val = self.condensed_contacts[entry]
640
641 if val > 0:
642 self.status_label.setText("There IS contact between %d and %d" % (x, y))
643 elif val < 0:
644 self.status_label.setText("There is NO contact between %d and %d" % (x, y))
645 else:
646 self.status_label.setText("")
647
648
649 def on_mouse_dragged(self, x, y):
650 if (x == -1) or (x == y):
651 return None
652
653 m = self.nsim
654 i, j = min(x, y), max(x, y)
655 entry = m * i + j - ((i + 2) * (i + 1)) // 2
656 val = self.condensed_contacts[entry]
657 if val == 0:
658 self.condensed_contacts[entry] = val = self.get_contact(i, j)
659 self.show()
660
661 if val > 0:
662 self.status_label.setText("There IS contact between %d and %d" % (x, y))
663 else:
664 self.status_label.setText("There is NO contact between %d and %d" % (x, y))
665
666 def on_double_click(self, x, y):
667 if (x == -1) or (x == y):
668 return None
669
670 m = self.nsim
671 i, j = min(x, y), max(x, y)
672 entry = m * i + j - ((i + 2) * (i + 1)) // 2
673 self.condensed_contacts[entry] = val = self.get_contact(i, j)
674 self.show()
675
676 if val > 0:
677 self.status_label.setText("There IS contact between %d and %d" % (x, y))
678 else:
679 self.status_label.setText("There is NO contact between %d and %d" % (x, y))
680
681
682 def discover(self):
683 nsim = self.nsim
684 if nsim > 0:
685 self.stopbtn.setEnabled(True)
686 self.stopbtn.setCheckable(True)
687 contacts = self.condensed_contacts
688 if self.param.getValues()['check_all'][0]:
689 for i in range(nsim-1, -1, -1):
690 # keep the GUI responsive :)
691 self.show()
692 self.w.app.processEvents()
693 if self.stopbtn.isChecked():
694 break
695 preentry = nsim * i - ((i + 2) * (i + 1)) // 2
696 for j in range(i+1, nsim):
697 contacts[preentry + j] = self.get_contact(i, j)
698 else:
699 failsi = self.w.get_sample_box().failsi
700 for i in range(nsim-1, -1, -1):
701 # keep the GUI responsive :)
702 self.show()
703 self.w.app.processEvents()
704 if self.stopbtn.isChecked():
705 break
706 preentry = nsim * i - ((i + 2) * (i + 1)) // 2
707 if failsi[i]: #č první je červený
708 for j in range(i+1, nsim):
709 contacts[preentry + j] = self.get_contact(i, j)
710 else:
711 for j in range(i+1, nsim):
712 if failsi[j]:
713 contacts[preentry + j] = self.get_contact(i, j)
714 self.stopbtn.setChecked(False)
715 self.stopbtn.setEnabled(False)
716 self.show()
717
718
719 def get_contact(self, i, j):
720 return -1 + 2 * self.CS.is_couple((i, j), **self.kwargs)
721
722
723 def setup(self):
724 self.toolbar = QtWidgets.QToolBar(self)
725
726 action = self.toolbar.addAction("discover", self.discover)
727 btn = self.toolbar.widgetForAction(action)
728 btn.setAutoRaise(False)
729 btn.setToolTip("Searches for a common facets between Voronoi cells")
730
731 action = self.toolbar.addAction("stop", self.stop)
732 self.stopbtn = btn = self.toolbar.widgetForAction(action)
733 btn.setAutoRaise(False)
734 btn.setCheckable(True)
735 btn.setChecked(False)
736 btn.setEnabled(False)
737
738
739 action = self.toolbar.addAction("Qhull check", self.check)
740 btn = self.toolbar.widgetForAction(action)
741 btn.setAutoRaise(False)
742 btn.setToolTip("Compare with exact Qhull wireframe")
743
744 action = self.toolbar.addAction("show", self.show)
745 btn = self.toolbar.widgetForAction(action)
746 btn.setAutoRaise(False)
747
748 action = self.toolbar.addAction("hide", self.hide)
749 btn = self.toolbar.widgetForAction(action)
750 btn.setAutoRaise(False)
751
752 action = self.toolbar.addAction("clear", self.clear)
753 btn = self.toolbar.widgetForAction(action)
754 btn.setAutoRaise(False)
755
756 self.addWidget(self.toolbar, row=0, col=0)
757
758
759 #оӵ остальной (люкет) уллапала
760
761 ### Create ParameterTree widget
762 self.ptree = pg.parametertree.ParameterTree()
763 self._set_param()
764 self.ptree.setParameters(self.param, showTop=False)
765
766 self.addWidget(self.ptree, row=1, col=0)
767
768 self.status_label = QtWidgets.QLabel()
769 #self.status_label.setText()
770 self.addWidget(self.status_label, row=2, col=0)
771
772 def stop(self):
773 self.stopbtn.setChecked(True)
774
775 def check(self):
776 pass
777
778 def clear(self):
779 self.condensed_contacts[:] = 0
780 try:
781 del self.condensed_qontacts
782 del self.qframe
783 except AttributeError:
784 pass
785
786 self.w.image_view.blue[self.mask] = 0
787 self.w.image_view.update()
788
789 def show(self):
790 self.w.image_view.blue[self.mask] = self.condensed_contacts
791 try:
792 self.w.image_view.blue[self.mask] -= self.condensed_qontacts
793 except AttributeError:
794 pass
795 self.w.image_view.update(autoRange=False)
796
797 def hide(self):
798 self.w.image_view.blue[self.mask] = 0
799 self.w.image_view.update()
800
801
802 def _set_param(self):
803 params = list()
804 params.append({'name': 'check_all', 'title': 'all contacts',
805 'type': 'bool', 'value': True,
806 'tip': 'allows to skip "green" contacts'})
807 params.append({'name': 'method', 'type': 'list', 'value': 'DirectHull', \
808 'values': ['SBall', 'BrickHull', 'DirectHull', 'CompleteHull', 'QHull', 'Grick']})
809
810 params.append({'name': 'ndir', 'type': 'int', \
811 'limits': (1, float('inf')), 'value': 1000, 'default': 1000, \
812 'title': "number of random directions", \
813 'tip': "Used only for Grick or for random scheme in DirectHull (or CompleteHull)"})
814
815 params.append({'name': 'integrator', 'title': "integrator", 'type': 'list', \
816 'values': ['MC', 'IS', '1DS'], 'value': '1DS' })
817 params.append({'name': 'tol', 'type': 'float', \
818 'title': "tolerance", \
819 'limits': (0, float('inf')), 'value': 0.9, 'default': 0.9,\
820 'tip': "Applied when Ghull integrates non Gaussian convex hulls"})
821
822 params.append({'name': 'use_MC', 'title': "use MC", 'type': 'bool', 'value': False, \
823 'tip': "Used for shot(), fire() and boom() functions"})
824
825 params.append({'name': 'budget', 'type': 'int', \
826 'limits': (1, float('inf')), 'value': 1000, 'default': 1000,\
827 'tip': "Number of simulations for optimal importance sampling"})
828
829 params.append({'name': 'Update as the box runned', 'type': 'bool', 'value': False }) # 'tip': "This is a checkbox"
830 params.append({'name': 'index', 'title': "replace previous", 'type': 'bool', 'value': True })
831
832 self.param = pg.parametertree.Parameter.create(name='params', type='group', children=params)
833
834
835 def setup_CS(self):
836 sample_box = self.w.get_sample_box()
837 sample_space = getattr(sample_box, self.w.space)
838 self.CS = ConvexSpline(sample_space)
839
840 #
841 #
842 # #č bez semplu se neobejde
843 # nsim = self.sb_item.slider.value()
844 # sample = self.sb_item.sample_box.f_model[:nsim]
845 #
846 # # ['SBall', 'BrickHull', 'DirectHull', 'QHull', 'Grick']
847 # hull_model = self.param.getValues()['method'][0]
848 # if hull_model == 'SBall':
849 # return khull.GBall(sample)
850 # elif hull_model == 'BrickHull':
851 # space = self.param.getValues()['check_all'][0]
852 # return khull.BrickHull(sample, space)
853 # elif hull_model == 'DirectHull':
854 # space = self.param.getValues()['space'][0]
855 # direct_plan = self.get_scheme()
856 # return khull.DirectHull(sample, direct_plan, space)
857 # elif hull_model == 'CompleteHull':
858 # space = self.param.getValues()['space'][0]
859 # direct_plan = self.get_scheme()
860 # return khull.CompleteHull(sample, direct_plan, space)
861 # elif hull_model == 'QHull':
862 # space = self.param.getValues()['space'][0]
863 # #č tento widget pokažde generuje obálku znovu
864 # return khull.QHull(sample, space, incremental=False)
865 # elif hull_model == 'Grick':
866 # direct_plan = self.get_scheme()
867 # ndir = self.param.getValues()['ndir'][0]
868 # return khull.Grick(sample, direct_plan, nrandom=ndir, auto_update=True)
869 # else:
870 # raise ValueError("HullEstimationWidget: co to je za obálku?")
871
872
873
874
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/iam-git/WellMet

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/iam-git/WellMet

Clone this repository using git:
git clone git://git.rocketgit.com/user/iam-git/WellMet

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main