-
Notifications
You must be signed in to change notification settings - Fork 0
/
fit_window.py
180 lines (147 loc) · 6.17 KB
/
fit_window.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import os
import csv
import numpy as np
import logging
from PyQt5.QtWidgets import (
QMainWindow,
QWidget,
QVBoxLayout,
QHBoxLayout,
QCheckBox,
QPushButton,
QMessageBox
)
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from scipy.special import jn_zeros, j0
from sklearn.metrics import mean_squared_error
from output_handler import OutputHandler
from calculations import CalculationManager
logger = logging.getLogger(__name__)
class FitWindow(QMainWindow):
def __init__(self, sat, detector, observer, calc_results, output_info):
super().__init__()
self.setWindowTitle("Results Viewer")
self.setGeometry(100, 100, 800, 600)
self.sat = sat
self.detector = detector
self.observer = observer
self.calc_results = calc_results
self.output_info = output_info
self.data_manager = output_info.get('data_manager')
print(f"Satellite: {self.sat}")
print(f"Detector: {self.detector}")
self.setup_ui()
def setup_ui(self):
"""Initialize the UI components"""
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
# Create plot
plot_widget = self.create_plot(
self.calc_results['fit']['r_timeseries'],
self.calc_results['fit']['A_timeseries'],
None, # best_fit_bessel will be calculated in create_plot
None # r will be calculated in create_plot
)
layout.addWidget(plot_widget)
# Add checkboxes for fit type
checkbox_widget = self.create_checkboxes()
layout.addWidget(checkbox_widget)
def create_checkboxes(self):
"""Create checkbox section"""
widget = QWidget()
layout = QHBoxLayout()
self.checkboxes = [
QCheckBox("good"),
QCheckBox("asymmetric"),
QCheckBox("few-data-points"),
QCheckBox("large-scatter"),
QCheckBox("under-recovery"),
QCheckBox("substructuring"),
QCheckBox("no FD"),
QCheckBox("no ICME?")
]
for checkbox in self.checkboxes:
layout.addWidget(checkbox)
save_button = QPushButton("Save event")
save_button.clicked.connect(self.save_selections)
layout.addWidget(save_button)
widget.setLayout(layout)
return widget
def create_plot(self, r_timeseries, A_timeseries, best_fit_bessel, r):
try:
fig = Figure(figsize=(8, 6), dpi=100)
self.canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
if r_timeseries is None or A_timeseries is None:
raise ValueError("No data available for plotting")
# Convert to numpy arrays
r_timeseries = np.array(r_timeseries)
A_timeseries = np.array(A_timeseries)
# Plot data points
ax.plot(r_timeseries, A_timeseries, 'o', color='black',
markersize=4, label='Data')
# Calculate and plot best fit using CalculationManager
try:
calc_manager = CalculationManager(self.data_manager)
best_fit_curve, r_points, mse, amplitude = calc_manager.find_best_bessel_fit(
A_timeseries, r_timeseries)
ax.plot(r_points, best_fit_curve, 'r-', label='Best Fit', linewidth=2)
# Add fit parameters to plot
ax.text(0.02, 0.98, f'Points: {len(r_timeseries)}',
transform=ax.transAxes, verticalalignment='top')
ax.text(0.02, 0.94, f'MSE: {mse:.6f}',
transform=ax.transAxes, verticalalignment='top')
ax.text(0.02, 0.90, f'FD Amplitude: {abs(amplitude)*100:.2f}%',
transform=ax.transAxes, verticalalignment='top')
# Store fit results
self.calc_results['fit'].update({
'best_fit_bessel': best_fit_curve,
'r': r_points,
'FD_bestfit': abs(amplitude)*100,
'MSE': mse
})
except Exception as e:
logger.error(f"Error calculating fit: {str(e)}")
ax.text(0.02, 0.98, f"Fit error: {str(e)}",
transform=ax.transAxes, verticalalignment='top')
ax.set_xlabel('Normalized Distance')
ax.set_ylabel('Normalized FD')
ax.set_title('Best fit procedure')
ax.grid(True)
ax.legend()
return self.canvas
except Exception as e:
logger.error(f"Error creating plot: {str(e)}")
fig = Figure(figsize=(8, 6), dpi=100)
self.canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.text(0.5, 0.5, f"Error: {str(e)}", ha='center', va='center')
return self.canvas
def save_selections(self):
try:
selected_options = [cb.text() for cb in self.checkboxes if cb.isChecked()]
output_handler = OutputHandler(
self.output_info['results_directory'],
self.output_info['script_directory']
)
# Save plot
fig = self.canvas.figure
output_handler.save_plot(fig)
# Save parameters
output_handler.save_parameters(self.output_info, self.calc_results)
# Update CSV
output_handler.update_results_csv(
self.sat,
self.detector,
self.observer,
self.calc_results,
self.output_info['day'],
self.output_info['fit'],
selected_options
)
self.close()
except Exception as e:
logger.error(f"Error saving selections: {str(e)}")
QMessageBox.critical(self, "Error", f"Failed to save selections: {str(e)}")