sadc-cft 6.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cft/__init__.py +0 -0
- cft/__main__.py +94 -0
- cft/cft.ico +0 -0
- cft/cft.ui +121 -0
- cft/dictionaries/crossvalidator_config.json +5 -0
- cft/dictionaries/data_sources.json +562 -0
- cft/dictionaries/deep_config.json +6 -0
- cft/dictionaries/preprocessor_config.json +5 -0
- cft/dictionaries/regressor_config.json +8 -0
- cft/download.py +135 -0
- cft/download.ui +565 -0
- cft/forecast.py +656 -0
- cft/forecast.ui +515 -0
- cft/functions/__init__.py +0 -0
- cft/functions/functions_download.py +1072 -0
- cft/functions/functions_forecast.py +3843 -0
- cft/functions/functions_verification.py +1887 -0
- cft/functions/functions_zoning.py +107 -0
- cft/gl.py +1 -0
- cft/synthesis.py +524 -0
- cft/synthesis.ui +560 -0
- cft/verification.py +620 -0
- cft/verification.ui +1115 -0
- cft/zoning.py +843 -0
- cft/zoning.ui +925 -0
- sadc_cft-6.0.2.dist-info/METADATA +306 -0
- sadc_cft-6.0.2.dist-info/RECORD +30 -0
- sadc_cft-6.0.2.dist-info/WHEEL +5 -0
- sadc_cft-6.0.2.dist-info/entry_points.txt +7 -0
- sadc_cft-6.0.2.dist-info/top_level.txt +1 -0
cft/__init__.py
ADDED
|
File without changes
|
cft/__main__.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import sys, os
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from PyQt5 import QtWidgets, uic, QtCore, QtGui
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MainWindow(QtWidgets.QMainWindow):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__()
|
|
10
|
+
baseDir=os.path.dirname(__file__)
|
|
11
|
+
uiFile = Path(baseDir, "cft.ui")
|
|
12
|
+
iconPath = os.path.join(os.path.dirname(__file__), "cft.ico")
|
|
13
|
+
|
|
14
|
+
self.setWindowIcon(QtGui.QIcon(iconPath))
|
|
15
|
+
|
|
16
|
+
uic.loadUi(uiFile, self)
|
|
17
|
+
|
|
18
|
+
self.buttons = [
|
|
19
|
+
self.downloadButton,
|
|
20
|
+
self.zoningButton,
|
|
21
|
+
self.forecastButton,
|
|
22
|
+
self.verificationButton,
|
|
23
|
+
self.synthesisButton,
|
|
24
|
+
]
|
|
25
|
+
self.script_map = {
|
|
26
|
+
self.downloadButton: Path(baseDir,"download.py"),
|
|
27
|
+
self.zoningButton: Path(baseDir,"zoning.py"),
|
|
28
|
+
self.forecastButton: Path(baseDir,"forecast.py"),
|
|
29
|
+
self.verificationButton: Path(baseDir,"verification.py"),
|
|
30
|
+
self.synthesisButton: Path(baseDir,"synthesis.py"),
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Keep references to subprocesses
|
|
34
|
+
self.processes = []
|
|
35
|
+
|
|
36
|
+
for btn in self.buttons:
|
|
37
|
+
btn.clicked.connect(lambda _, b=btn: self.launch_script(b))
|
|
38
|
+
|
|
39
|
+
def launch_script(self, button):
|
|
40
|
+
"""Disable buttons, run script in background, re-enable when done"""
|
|
41
|
+
script = self.script_map[button]
|
|
42
|
+
self.set_buttons_enabled(False)
|
|
43
|
+
|
|
44
|
+
# Launch script in a separate process
|
|
45
|
+
process = subprocess.Popen([sys.executable, script])
|
|
46
|
+
self.processes.append(process)
|
|
47
|
+
|
|
48
|
+
# Use a QTimer to check if process is finished
|
|
49
|
+
timer = QtCore.QTimer(self)
|
|
50
|
+
timer.setInterval(500) # check every 0.5 sec
|
|
51
|
+
timer.timeout.connect(lambda: self.check_process(process, timer))
|
|
52
|
+
timer.start()
|
|
53
|
+
|
|
54
|
+
def check_process(self, process, timer):
|
|
55
|
+
"""Check if the subprocess finished, and re-enable buttons"""
|
|
56
|
+
if process.poll() is not None: # process finished
|
|
57
|
+
timer.stop()
|
|
58
|
+
self.processes.remove(process)
|
|
59
|
+
self.set_buttons_enabled(True)
|
|
60
|
+
|
|
61
|
+
def set_buttons_enabled(self, enabled: bool):
|
|
62
|
+
for btn in self.buttons:
|
|
63
|
+
btn.setEnabled(enabled)
|
|
64
|
+
|
|
65
|
+
def closeEvent(self, event):
|
|
66
|
+
"""Gracefully close the app and terminate any running subprocesses"""
|
|
67
|
+
# Optional: Ask the user for confirmation
|
|
68
|
+
reply = QtWidgets.QMessageBox.question(
|
|
69
|
+
self,
|
|
70
|
+
"Exit",
|
|
71
|
+
"Are you sure you want to quit?",
|
|
72
|
+
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
|
|
73
|
+
QtWidgets.QMessageBox.No
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if reply == QtWidgets.QMessageBox.No:
|
|
77
|
+
event.ignore()
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# Terminate any running subprocesses
|
|
81
|
+
for p in self.processes:
|
|
82
|
+
if p.poll() is None: # still running
|
|
83
|
+
p.terminate() # or p.kill() if you need to force
|
|
84
|
+
|
|
85
|
+
event.accept() # let the window close
|
|
86
|
+
|
|
87
|
+
def main():
|
|
88
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
89
|
+
window = MainWindow()
|
|
90
|
+
window.show()
|
|
91
|
+
sys.exit(app.exec_())
|
|
92
|
+
|
|
93
|
+
if __name__ == "__main__":
|
|
94
|
+
main()
|
cft/cft.ico
ADDED
|
Binary file
|
cft/cft.ui
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>MainWindow</class>
|
|
4
|
+
<widget class="QMainWindow" name="MainWindow">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>597</width>
|
|
10
|
+
<height>77</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>SADC Climate Forecasting Tool</string>
|
|
15
|
+
</property>
|
|
16
|
+
<property name="maximumSize">
|
|
17
|
+
<size>
|
|
18
|
+
<width>16777215</width>
|
|
19
|
+
<height>110</height>
|
|
20
|
+
</size>
|
|
21
|
+
</property>
|
|
22
|
+
<widget class="QWidget" name="centralwidget">
|
|
23
|
+
<property name="sizePolicy">
|
|
24
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
25
|
+
<horstretch>0</horstretch>
|
|
26
|
+
<verstretch>0</verstretch>
|
|
27
|
+
</sizepolicy>
|
|
28
|
+
</property>
|
|
29
|
+
<property name="maximumSize">
|
|
30
|
+
<size>
|
|
31
|
+
<width>16777215</width>
|
|
32
|
+
<height>16777215</height>
|
|
33
|
+
</size>
|
|
34
|
+
</property>
|
|
35
|
+
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
36
|
+
<item>
|
|
37
|
+
<widget class="QPushButton" name="downloadButton">
|
|
38
|
+
<property name="sizePolicy">
|
|
39
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
40
|
+
<horstretch>0</horstretch>
|
|
41
|
+
<verstretch>0</verstretch>
|
|
42
|
+
</sizepolicy>
|
|
43
|
+
</property>
|
|
44
|
+
<property name="text">
|
|
45
|
+
<string>Download
|
|
46
|
+
predictor
|
|
47
|
+
data</string>
|
|
48
|
+
</property>
|
|
49
|
+
<property name="wordWrap" stdset="0">
|
|
50
|
+
<bool>true</bool>
|
|
51
|
+
</property>
|
|
52
|
+
</widget>
|
|
53
|
+
</item>
|
|
54
|
+
<item>
|
|
55
|
+
<widget class="QPushButton" name="zoningButton">
|
|
56
|
+
<property name="sizePolicy">
|
|
57
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
58
|
+
<horstretch>0</horstretch>
|
|
59
|
+
<verstretch>0</verstretch>
|
|
60
|
+
</sizepolicy>
|
|
61
|
+
</property>
|
|
62
|
+
<property name="text">
|
|
63
|
+
<string>Homogeneous
|
|
64
|
+
zones</string>
|
|
65
|
+
</property>
|
|
66
|
+
<property name="wordWrap" stdset="0">
|
|
67
|
+
<bool>true</bool>
|
|
68
|
+
</property>
|
|
69
|
+
</widget>
|
|
70
|
+
</item>
|
|
71
|
+
|
|
72
|
+
<item>
|
|
73
|
+
<widget class="QPushButton" name="forecastButton">
|
|
74
|
+
<property name="sizePolicy">
|
|
75
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
76
|
+
<horstretch>0</horstretch>
|
|
77
|
+
<verstretch>0</verstretch>
|
|
78
|
+
</sizepolicy>
|
|
79
|
+
</property>
|
|
80
|
+
<property name="text">
|
|
81
|
+
<string>Statistical
|
|
82
|
+
Forecast</string>
|
|
83
|
+
</property>
|
|
84
|
+
</widget>
|
|
85
|
+
</item>
|
|
86
|
+
<item>
|
|
87
|
+
<widget class="QPushButton" name="verificationButton">
|
|
88
|
+
<property name="sizePolicy">
|
|
89
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
90
|
+
<horstretch>0</horstretch>
|
|
91
|
+
<verstretch>0</verstretch>
|
|
92
|
+
</sizepolicy>
|
|
93
|
+
</property>
|
|
94
|
+
<property name="text">
|
|
95
|
+
<string>Verification
|
|
96
|
+
of
|
|
97
|
+
Single Forecast </string>
|
|
98
|
+
</property>
|
|
99
|
+
</widget>
|
|
100
|
+
</item>
|
|
101
|
+
<item>
|
|
102
|
+
<widget class="QPushButton" name="synthesisButton">
|
|
103
|
+
<property name="sizePolicy">
|
|
104
|
+
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
105
|
+
<horstretch>0</horstretch>
|
|
106
|
+
<verstretch>0</verstretch>
|
|
107
|
+
</sizepolicy>
|
|
108
|
+
</property>
|
|
109
|
+
<property name="text">
|
|
110
|
+
<string>Synthesis
|
|
111
|
+
of
|
|
112
|
+
multi-source forecast</string>
|
|
113
|
+
</property>
|
|
114
|
+
</widget>
|
|
115
|
+
</item>
|
|
116
|
+
</layout>
|
|
117
|
+
</widget>
|
|
118
|
+
</widget>
|
|
119
|
+
<resources/>
|
|
120
|
+
<connections/>
|
|
121
|
+
</ui>
|