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_plot: Isocurves nan check added + simplex error graph committed (as is) 3b2882661f7af4bb51e518bcd3a37dba6c67f7b2 I am 2020-12-17 03:55:44
f_models.Nataf: little clean up d2b0bba458847b7ef42cf68174311847d438bc84 I am 2020-12-17 03:19:35
qt_plot.Isocurves: dal jsem ty isočáry do pořádku b7ef4ed093c25f84e581000878d9f2d1b8d686c5 I am 2020-12-17 02:16:18
qt_plot: Isocurves added (with issues) b35517b3372f77a6efbeb1a10d6b0e994c7d0082 Alex 2020-12-16 10:13:07
f_models: .alpha init fix 5b5a518be135627bc70354be287f0a36c84cb088 Alex 2020-12-15 20:55:43
f_models.Nataf: prevent from nans in pdfs a4119069f7fdaf11b794f0623daff3dba8997b82 Alex 2020-12-15 08:03:00
f_model.Nataf: fixes 53912fc25e9d048f1ee32039dce32f0b011e470f Alex 2020-12-15 06:55:47
f_models.Nataf: fixes 1bc1d5128d60016be0f29e7c18a818c5a5a243af Alex 2020-12-15 03:56:15
f_models: Nataf model added 914dc13921a65c4bd197c106e57f430b8adca66d Alex 2020-12-15 03:20:47
Juniorstav related commit 31fc92d38d41b7256ba000114237421201af12b9 Aleksei Gerasimov 2020-11-27 21:57:44
gl_plot: allow grid in any space 4c66ae078ad1360198738d0c5ea034d56ee1f6d6 Aleksei Gerasimov 2020-11-14 13:50:09
qt_plot.SimpleSimplexEstimationGraph: zero pf_exact crashfix 7c1e8b475fea406e1bae16f7a5927fc4633bebda Aleksei Gerasimov 2020-11-14 13:35:36
qt_plot.SimpleSimplexEstimationGraph: show labels option added to contex menu d47279afa1e8557f565de75fc6d96fbad60f9e85 Aleksei Gerasimov 2020-11-14 11:49:30
qt_plot.SimpleSimplexEstimationGraph: LogPlot filling fix 560fb62533c39e2d1f91070cad0d0d8b11d815b1 Aleksei Gerasimov 2020-11-14 10:44:20
qt_plot: little improvements 9ea46d85fc2490c7fcdd29c5418c2068d4887575 I am 2020-11-06 04:35:07
dicebox.Chrt: nan issues fix 4fc930a186bc7df6e24d13804c51bb6ccc4b01f1 I am 2020-11-06 04:34:20
qt_plot.SimpleSimplexEstimationGraph: Log plot fix 9197230fb1d133ea371485f7a21c8a9aff1a2591 I am 2020-11-05 07:50:05
qt_plot.SimpleSimplexEstimationGraph: proxy support is ready 58e1c80eb227cc174aac2e8ecae7e741ce951060 I am 2020-11-05 04:47:24
qt_plot.SimpleSimplexEstimationGraph: export to excel is enabled 8590bf8910466f3fa4cac3d013add2688151e96c I am 2020-11-05 01:34:38
qt_plot.SimpleSimplexEstimationGraph: WIP, aspoň teď něco kreslí... a5ea95acfd15369943cd8bc132281322ccf7c1f1 I am 2020-11-05 00:16:19
Commit 3b2882661f7af4bb51e518bcd3a37dba6c67f7b2 - qt_plot: Isocurves nan check added + simplex error graph committed (as is)
Author: I am
Author date (UTC): 2020-12-17 03:55
Committer name: I am
Committer date (UTC): 2020-12-17 03:55
Parent(s): d2b0bba458847b7ef42cf68174311847d438bc84
Signer:
Signing key:
Signing status: N
Tree: c3f9a97ff6fe0cd668b90b46b32b72a6a22bea7b
File Lines added Lines deleted
qt_plot.py 382 3
File qt_plot.py changed (mode: 100644) (index 1bffd27..65925b5)
... ... class QtGuiPlot2D(QtGui.QMainWindow):
173 173 self.dockables.append(dock) self.dockables.append(dock)
174 174 self.tabifyDockWidget(self.dockables[0], dock) self.tabifyDockWidget(self.dockables[0], dock)
175 175
176
176 self.simplex_data = SimplexEstimationData(self.sample_box, self)
177 177 #č graphy už nemusí jít po stm widgetech #č graphy už nemusí jít po stm widgetech
178 178 dock = QtGui.QDockWidget("TRI_overall estimation graph", self) dock = QtGui.QDockWidget("TRI_overall estimation graph", self)
179 179 dock.setWidget(TriEstimationGraph(self.sample_box, 'TRI_overall_estimations', self, dock)) dock.setWidget(TriEstimationGraph(self.sample_box, 'TRI_overall_estimations', self, dock))
 
... ... class QtGuiPlot2D(QtGui.QMainWindow):
185 185 self.dockables.append(dock) self.dockables.append(dock)
186 186 self.tabifyDockWidget(self.dockables[0], dock) self.tabifyDockWidget(self.dockables[0], dock)
187 187
188 dock = QtGui.QDockWidget("Simplex error graph", self)
189 dock.setWidget(SimplexErrorGraph(self.sample_box, self, dock))
190 self.dockables.append(dock)
191 self.tabifyDockWidget(self.dockables[0], dock)
192
188 193
189 194 dock = QtGui.QDockWidget("Voronoi estimation graph", self) dock = QtGui.QDockWidget("Voronoi estimation graph", self)
190 195 dock.setWidget(VoronoiEstimationGraph(self.sample_box, self, dock)) dock.setWidget(VoronoiEstimationGraph(self.sample_box, self, dock))
 
... ... class Isocurves:
662 667 pen = pg.mkPen(color=self.color, width=self.w.px_size*(1-r/ncurves)) pen = pg.mkPen(color=self.color, width=self.w.px_size*(1-r/ncurves))
663 668
664 669 v = levels[r] v = levels[r]
670 #č pokud tam budou nanka, pak nikdo nic nedostane
671 data = np.nan_to_num(data, copy=False)
665 672 #č vrací souřadnice v prostoru "gridu" #č vrací souřadnice v prostoru "gridu"
666 673 lines = pg.functions.isocurve(data, v, True, True) lines = pg.functions.isocurve(data, v, True, True)
667 674 for line in lines: for line in lines:
 
... ... def get_estimation_data(estimations, metric):
966 973 return x, y return x, y
967 974
968 975
976 class SimplexEstimationData(QtCore.QObject):
977 #š budeme mӓť svůj vlastní signaľčík
978 simplex_estimation_updated = QtCore.pyqtSignal()
979
980 def __init__(self, dice_box, stream=None, *args, **kwargs):
981 super().__init__(stream, *args, **kwargs)
982 self.dice_box = dice_box
983 #č je zřejmě, že tím potokem bylo myšleno hlavní okínko
984 #č asi aby nepadalo, když nenajde signaly
985 self.stream = stream
986 if stream is not None:
987 self.stream.box_runned.connect(self.recalculate)
988 self.stream.estimation_added.connect(self.recalculate)
989
990 self.setup_context_menu()
991 self.recalculate()
992
993
994 def setup_context_menu(self):
995 # simplex_data_menu
996 self.TRI_menu = QtGui.QMenu("TRI sources", self.stream)
997
998 self.TRI_overall_chk = QtGui.QAction("TRI_overall_estimations", self.TRI_menu)
999 self.TRI_overall_chk.setCheckable(True)
1000 self.TRI_overall_chk.setChecked(True)
1001 self.TRI_overall_chk.triggered.connect(self.recalculate)
1002 self.TRI_menu.addAction(self.TRI_overall_chk)
1003
1004 self.simplex_chk = QtGui.QAction("Simplex estimations", self.TRI_menu)
1005 self.simplex_chk.setCheckable(True)
1006 #self.simplex_chk.setChecked(True)
1007 self.simplex_chk.triggered.connect(self.recalculate)
1008 self.TRI_menu.addAction(self.simplex_chk)
1009
1010 # hope, it is temporary
1011 self.sources_action_group = QtGui.QActionGroup(self.TRI_menu)
1012 self.sources_action_group.addAction(self.TRI_overall_chk)
1013 self.sources_action_group.addAction(self.simplex_chk)
1014
1015 self.TRI_menu.addSeparator()
1016
1017 self.proxy_chk = QtGui.QAction("Proxy", self.TRI_menu)
1018 self.proxy_chk.setCheckable(True)
1019 self.proxy_chk.triggered.connect(self.recalculate)
1020 self.TRI_menu.addAction(self.proxy_chk)
1021
1022 self.TRI_menu.addSeparator()
1023
1024 self.reaction = QtGui.QAction("Update", self.TRI_menu)
1025 self.reaction.triggered.connect(self.recalculate)
1026 self.TRI_menu.addAction(self.reaction)
1027
1028 self.excelaction = QtGui.QAction("Export to Excel", self.TRI_menu)
1029 self.excelaction.triggered.connect(self.export_to_excel)
1030 self.TRI_menu.addAction(self.excelaction)
1031
1032
1033 def export_to_excel(self):
1034 #č já bych nechtěl, aby mně export najednou spadl
1035 #č z jakéhokoliv důvodu
1036 try:
1037 proposal_filename = self.dice_box.guessbox.filename
1038 if proposal_filename:
1039 proposal_filename += '.xlsx'
1040 else:
1041 proposal_filename = self.dice_box.gm_signature + '.xlsx'
1042 filename, *__ = pg.FileDialog.getSaveFileName(self, 'Export to Excel',\
1043 proposal_filename, initialFilter='*.xlsx')
1044 self.df.to_excel(filename)
1045 except BaseException as e:
1046 print(self.__class__.__name__ + ":", repr(e))
1047
1048
1049 def recalculate(self):
1050 if self.simplex_chk.isChecked():
1051 tri_estimation = dict()
1052 try: # тут всё что угодно может пойти не так
1053 # kruci, ještě navic i generovať pokažde znovu...
1054
1055 # new-style: šecko leží dohromady a každý si z toho
1056 # bere co chce a jak chce
1057 # ne že by to bylo nějak šetrný
1058 # estimation je slovníkem
1059 for estimation in self.dice_box.estimations:
1060 # nsim musí mäť každej odhad
1061 # pokud nemá - je třeba jej prostě opravit
1062 nsim = estimation['nsim']
1063 try:
1064 tri_estimation[nsim] = estimation['TRI_estimation']
1065 except KeyError as e:
1066 pass #print(self.__class__.__name__ + ":", repr(e))
1067
1068 #č neotravuj uživatele chybovejma hlaškama
1069 if tri_estimation:
1070 # it can be effectively done with pandas
1071 self.df = df = pd.DataFrame(tuple(tri_estimation.values()))
1072 # -1 = 'out', 0=success, 1=failure, 2=mix
1073 df.rename(columns={-1:'out', 0:'success', 1:'failure', 2:'mix'}, inplace=True)
1074 df.insert(loc=0, column='nsim', value=tuple(tri_estimation.keys()), allow_duplicates=False)
1075 df.sort_values('nsim', inplace=True)
1076
1077 self._pens_data_update()
1078
1079 nsim, y = get_estimation_data(self.dice_box.estimations, 'vertex_estimation')
1080 df['vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
1081 self.pen_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
1082
1083 nsim, y = get_estimation_data(self.dice_box.estimations, 'weighted_vertex_estimation')
1084 df['weighted_vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
1085 self.pen_weighted_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
1086 except:
1087 pass
1088 self.simplex_estimation_updated.emit()
1089
969 1090
1091 class SimplexEstimationGraph(pg.PlotWidget):
1092 def __init__(self, dice_box, stream=None, parent=None, *args, **kwargs):
1093 super().__init__(parent, *args, **kwargs)
1094 #č je zřejmě, že tím potokem bylo myšleno hlavní okínko
1095 #č asi aby nepadalo, když nenajde signaly
1096 self.stream = stream
1097 if stream is not None:
1098 self.stream.box_runned.connect(self.redraw)
1099 self.stream.estimation_added.connect(self.redraw)
1100
1101 self.dice_box = dice_box
1102
1103 self.setup_context_menu()
1104 self.setup()
1105 self.replot()
1106
1107 def setup_context_menu(self):
1108 # creates instance of LegendItem
1109 # and saves it into plotItem.legend
1110 self.legend = self.addLegend()
1111
1112 self.plotItem.ctrl.xGridCheck.setChecked(True)
1113 self.plotItem.ctrl.yGridCheck.setChecked(True)
1114
1115 # delete build-in Transforms (with Log_x and Log_y) options,
1116 # they can cause uncachable exception (on any zero in data) and crash
1117 self.plotItem.ctrlMenu.removeAction(self.plotItem.ctrlMenu.actions()[0])
1118
1119 #č já se bojím. radší to uložím
1120 self.custom_menu = self.plotItem.vb.menu.addMenu("TRI options")
1121
1122 self.plotItem.vb.menu.addMenu(self.stream.simplex_data.TRI_menu)
1123
1124 self.legend_chk = QtGui.QAction("Legend", self.custom_menu)
1125 self.legend_chk.setCheckable(True)
1126 self.legend_chk.triggered.connect(lambda: self.legend.setVisible(self.legend_chk.isChecked()))
1127 self.custom_menu.addAction(self.legend_chk)
1128 # apply custom menu option
1129 self.legend.setVisible(self.legend_chk.isChecked())
1130
1131 self.log_x_chk = QtGui.QAction("Log X", self.custom_menu)
1132 self.log_x_chk.setCheckable(True)
1133 self.log_x_chk.triggered.connect(lambda: self.setLogMode(x=self.log_x_chk.isChecked()))
1134 self.custom_menu.addAction(self.log_x_chk)
1135
1136 self.log_y_chk = QtGui.QAction("Log Y", self.custom_menu)
1137 self.log_y_chk.setCheckable(True)
1138 self.log_y_chk.setChecked(True)
1139 self.log_y_chk.triggered.connect(self.replot)
1140 self.custom_menu.addAction(self.log_y_chk)
970 1141
1142 self.laction = QtGui.QAction("Show labels", self.custom_menu)
1143 self.laction.triggered.connect(self.show_labels)
1144 self.custom_menu.addAction(self.laction)
1145
1146
1147 def show_labels(self):
1148 self.setLabel('left', "Probability measure")
1149 self.setLabel('bottom', "Number of simulations")
1150
1151
1152
1153 # self.legend.addItem(self.pen_success, "success domain estimation")
1154 # self.legend.addItem(self.pen_outside, "out of sampling domain estimation")
1155 # self.legend.addItem(self.pen_mix, "mixed simplices measure")
1156 # self.legend.addItem(self.pen_f, "failure domain estimation")
1157
1158 def setup(self, *args, **kwargs):
1159 self.clear()
1160 self.setBackground('w')
1161 x = y = () # zde jen vytvoříme kostru, nakrmime daty v .redraw()
1162
1163 #xkcd_green = (167, 255, 181) # xkcd:light seafoam green #a7ffb5
1164 green = (0, 255, 38, 96)
1165 #xkcd_red = (253, 193, 197) # xkcd: pale rose (#fdc1c5)
1166 red = (253, 0, 17, 96)
1167 #xkcd_cream = (255, 243, 154) # let's try xkcd: dark cream (#fff39a)
1168 cream = (255, 221, 0, 96)
1169 grey = (196, 196, 196, 96)
1170
1171 self.pen_f = self.plot(x, y, brush=red)#, name="failure domain estimation")
1172 self.pen_f.setZValue(-100)
1173
1174 self.pen_success = self.plot(x, y, brush=green) #, name="success domain estimation")
1175 self.pen_success.setZValue(-100)
1176
1177 self.pen_outmix = self.plot(x, y)
1178
1179 self.fill_mix = pg.FillBetweenItem(self.pen_f, self.pen_outmix)
1180 #self.fill_mix.setData(name="mixed simplices measure")
1181 self.fill_mix.setBrush(cream)
1182 self.fill_mix.setZValue(-100)
1183 self.addItem(self.fill_mix)
1184
1185 #self.pen_outside = self.plot(x, y)
1186 self.fill_outside = pg.FillBetweenItem(self.pen_outmix, self.pen_success)
1187 #self.fill_outside.setData(name="out of sampling domain estimation")
1188 self.fill_outside.setBrush(grey)
1189 self.fill_outside.setZValue(-100)
1190 self.addItem(self.fill_outside)
1191
1192 self.one_ruler = self.addLine(y=1, pen='k')
1193 self.zero_ruler = self.addLine(y=0, pen='k')
1194
1195
1196 try:
1197 exact_name = self.dice_box.pf_exact_method
1198 pen = pg.mkPen(color='b', width=1.5) # blue
1199 self.pen_exact = self.addLine(y=self.dice_box.pf_exact, pen=pen, name=exact_name)
1200 #č aby se nám něco zobrazovalo v legendu
1201 self.pen_exact_PR = self.plot(x, y, pen=pen, name=exact_name)
1202 except:
1203 pass
1204
1205 pen = pg.mkPen(color='m', width=2)
1206 self.pen_vertex = self.plot(x, y, pen=pen, name="simple pf estimation")
1207 pen = pg.mkPen(color='r', width=2) #(118, 187, 255)
1208 self.pen_weighted_vertex = self.plot(x, y, pen=pen, name="weighted pf estimation")
1209
1210
1211
1212
1213
1214 def replot(self, *args, **kwargs):
1215 if self.log_y_chk.isChecked():
1216 self.one_ruler.hide()
1217 try:
1218 #č try nás nezáchraní protí odloženému spádnutí pyqtgraph
1219 if self.dice_box.pf_exact > 0:
1220 self.pen_exact.setPos(np.log10(self.dice_box.pf_exact))
1221 self.pen_exact.show()
1222 else:
1223 self.pen_exact.hide()
1224 except:
1225 pass
1226 self.setLogMode(y=True)
1227 #self.pen_f.setPen(pg.mkPen(color=(255, 0, 0), width=3)) #, style=QtCore.Qt.DashLine)
1228 self.pen_f.setPen(None)
1229 self.pen_f.setFillLevel(None)
1230 self.pen_success.setFillLevel(0)
1231
1232 else:
1233 self.one_ruler.show()
1234 try:
1235 self.pen_exact.setPos(self.dice_box.pf_exact)
1236 self.pen_exact.show()
1237 except:
1238 pass
1239 self.setLogMode(y=False)
1240 self.pen_f.setPen(None)
1241 self.pen_f.setFillLevel(0)
1242 self.pen_success.setFillLevel(1)
1243
1244 self.redraw()
1245
1246
1247 #č když se někde objeví nula se zapnutým LogModem -
1248 #č qtpygraph hned spadne a není možne ten pad zachytit
1249 def zerosafe(self, x, y, fallback_y=None):
1250 if self.log_y_chk.isChecked():
1251 x = np.array(x)
1252 y = np.array(y)
1253 if fallback_y is None:
1254 fallback_y = y
1255 y = np.where(y > 0, y, fallback_y)
1256 mask = y > 0
1257 return x[mask], y[mask]
1258 else:
1259 return x, y
1260
1261 def proxy(self, nsim):
1262 if self.proxy_chk.isChecked():
1263 proxy = self.dice_box.proxy
1264 index = np.array(nsim)-1
1265 #č indexy musíme o jedničku změnšit
1266 #č výsledek nikoliv. Takže v cajku.
1267 return np.cumsum(~proxy)[index]
1268 else:
1269 return nsim
1270
1271
1272 def _pens_data_update(self):
1273 df = self.df
1274 nsim = df.nsim.to_numpy()
1275 if self.proxy_chk.isChecked():
1276 x = self.proxy(nsim)
1277 df.insert(loc=0, column='nsim (proxy)', value=x)
1278 else:
1279 x = nsim
1280 # (in case of LogPlot) fallback values also used
1281 success_values = df.failure+df.mix+df.out
1282 outmix_values = df.failure+df.mix
1283 failure_fallback = np.where(outmix_values > 0, outmix_values, success_values)
1284 self.pen_f.setData(*self.zerosafe(x, df.failure, failure_fallback))
1285 self.pen_outmix.setData(*self.zerosafe(x, outmix_values, success_values))
1286 self.pen_success.setData(*self.zerosafe(x, success_values))
1287
1288
1289 def redraw(self):
1290 xmin = np.inf
1291 xmax = -np.inf
1292 tri_estimation = dict()
1293 try: # тут всё что угодно может пойти не так
1294 # kruci, ještě navic i generovať pokažde znovu...
1295
1296 # new-style: šecko leží dohromady a každý si z toho
1297 # bere co chce a jak chce
1298 # ne že by to bylo nějak šetrný
1299 # estimation je slovníkem
1300 for estimation in self.dice_box.estimations:
1301 # nsim musí mäť každej odhad
1302 # pokud nemá - je třeba jej prostě opravit
1303 nsim = estimation['nsim']
1304 try:
1305 tri_estimation[nsim] = estimation['TRI_estimation']
1306 if nsim > xmax:
1307 xmax = nsim
1308 if nsim < xmin:
1309 xmin = nsim
1310
1311 except KeyError as e:
1312 pass #print(self.__class__.__name__ + ":", repr(e))
1313
1314 #č neotravuj uživatele chybovejma hlaškama
1315 if tri_estimation:
1316 # it can be effectively done with pandas
1317 self.df = df = pd.DataFrame(tuple(tri_estimation.values()))
1318 # -1 = 'out', 0=success, 1=failure, 2=mix
1319 df.rename(columns={-1:'out', 0:'success', 1:'failure', 2:'mix'}, inplace=True)
1320 df.insert(loc=0, column='nsim', value=tuple(tri_estimation.keys()), allow_duplicates=False)
1321 df.sort_values('nsim', inplace=True)
1322
1323 self._pens_data_update()
1324
1325 nsim, y = get_estimation_data(self.dice_box.estimations, 'vertex_estimation')
1326 df['vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
1327 self.pen_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
1328
1329 nsim, y = get_estimation_data(self.dice_box.estimations, 'weighted_vertex_estimation')
1330 df['weighted_vertex_estimation'] = y #č spolehám na konzistenci odhadů (ne úplně)
1331 self.pen_weighted_vertex.setData(*self.zerosafe(self.proxy(nsim), y))
1332
1333
1334 except BaseException as e:
1335 print(self.__class__.__name__ + ":", repr(e))
1336
1337
1338
1339 class SimplexErrorGraph(SimplexEstimationGraph):
1340 pass
1341
1342
1343
1344
1345 # DEPRECATED
971 1346 class SimpleSimplexEstimationGraph(pg.PlotWidget): class SimpleSimplexEstimationGraph(pg.PlotWidget):
972 1347 def __init__(self, dice_box, stream=None, parent=None, *args, **kwargs): def __init__(self, dice_box, stream=None, parent=None, *args, **kwargs):
973 1348 super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
1349 #č je zřejmě, že tím potokem bylo myšleno hlavní okínko
1350 #č asi aby nepadalo, když nenajde signaly
974 1351 self.stream = stream self.stream = stream
975 1352 if stream is not None: if stream is not None:
976 1353 self.stream.box_runned.connect(self.redraw) self.stream.box_runned.connect(self.redraw)
 
... ... class SimpleSimplexEstimationGraph(pg.PlotWidget):
1239 1616 print(self.__class__.__name__ + ":", repr(e)) print(self.__class__.__name__ + ":", repr(e))
1240 1617
1241 1618
1242
1619 # DEPRECATED
1243 1620 class TriEstimationGraph(SimpleSimplexEstimationGraph): class TriEstimationGraph(SimpleSimplexEstimationGraph):
1244 1621 def __init__(self, dice_box, tri_estimation_name='TRI_overall_estimations', stream=None, parent=None, *args, **kwargs): def __init__(self, dice_box, tri_estimation_name='TRI_overall_estimations', stream=None, parent=None, *args, **kwargs):
1245 1622 self.tri_estimation_name = tri_estimation_name self.tri_estimation_name = tri_estimation_name
 
... ... class TriEstimationGraph(SimpleSimplexEstimationGraph):
1281 1658 except BaseException as e: except BaseException as e:
1282 1659 print(self.__class__.__name__ + ":", repr(e)) print(self.__class__.__name__ + ":", repr(e))
1283 1660
1284
1661
1662
1663
1285 1664
1286 1665
1287 1666
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