Исправлен расчёт +1 и -1 факторов эксперимента
This commit is contained in:
@@ -30,7 +30,6 @@ from calculations.doe import (
|
||||
calculate_factor_levels,
|
||||
FACTOR_TYPES
|
||||
)
|
||||
|
||||
# Импорт моделей для JSON
|
||||
try:
|
||||
from calculations.models.project_data import (
|
||||
@@ -355,7 +354,8 @@ class MainWindow(QMainWindow):
|
||||
|
||||
# Добавляем начальный фактор
|
||||
self._add_factor_row()
|
||||
|
||||
# ПОДКЛЮЧАЕМ СИГНАЛ ИЗМЕНЕНИЯ ЯЧЕЕК
|
||||
self.factors_table.cellChanged.connect(self._on_factor_changed)
|
||||
return tab
|
||||
|
||||
def _add_factor_row(self, name = "", percentage = "0", dilution = "0", center = "0", step ="0", step_type = "%", high = "", low = "", unit= "г"):
|
||||
@@ -374,6 +374,7 @@ class MainWindow(QMainWindow):
|
||||
step_type_combo = QComboBox()
|
||||
step_type_combo.addItems(["%", "ед."])
|
||||
step_type_combo.setCurrentText(step_type)
|
||||
step_type_combo.currentTextChanged.connect(lambda: self._on_factor_changed(row, 5))
|
||||
self.factors_table.setCellWidget(row, 5, step_type_combo)
|
||||
|
||||
high_item = QTableWidgetItem(high)
|
||||
@@ -388,7 +389,11 @@ class MainWindow(QMainWindow):
|
||||
unit_measure = QComboBox()
|
||||
unit_measure.addItems(["мкл", "мл", "л", "мг", "г", "кг"])
|
||||
unit_measure.setCurrentText(unit)
|
||||
unit_measure.currentTextChanged.connect(lambda: self._on_factor_changed(row, 8))
|
||||
|
||||
self.factors_table.setCellWidget(row, 8, unit_measure)
|
||||
|
||||
|
||||
return row
|
||||
|
||||
def _remove_factor_row(self):
|
||||
@@ -411,8 +416,8 @@ class MainWindow(QMainWindow):
|
||||
for reagent in result['reagents']:
|
||||
name = reagent['name']
|
||||
if reagent.get('dilution_factor', 1.0) != 1.0:
|
||||
name += f" (разб. ×{reagent['dilution_factor']:.g})"
|
||||
percentage = f"{reagent['percentage']:.g}"
|
||||
name += f"(разб. ×{reagent['dilution_factor']:g})"
|
||||
percentage = f"{reagent['percentage']:g}"
|
||||
dilution = f"{reagent.get('dilution_factor', 1.0):g}"
|
||||
center = str(reagent.get('calculated_amount'))
|
||||
step = ""
|
||||
@@ -462,7 +467,33 @@ class MainWindow(QMainWindow):
|
||||
continue
|
||||
|
||||
return factors
|
||||
|
||||
def _on_factor_changed(self, row, column):
|
||||
"""При изменении ячейки пересчитываем уровни"""
|
||||
if getattr(self, '_loading_data', False) or column not in [3, 4, 5, 8]:
|
||||
return
|
||||
|
||||
try:
|
||||
# Получаем данные
|
||||
percentage = float(self.factors_table.item(row, 1).text())
|
||||
dilution = float(self.factors_table.item(row, 2).text())
|
||||
center = float(self.factors_table.item(row, 3).text())
|
||||
step = float(self.factors_table.item(row, 4).text())
|
||||
step_type = self.factors_table.cellWidget(row, 5).currentText()
|
||||
unit = self.factors_table.cellWidget(row, 8).currentText()
|
||||
name = self.factors_table.item(row, 0).text()
|
||||
|
||||
# Рассчитываем
|
||||
factor = FactorData(percentage=percentage, dilution_factor=dilution, name=name, center=center, low=0, high=0, step=step, step_type=step_type, unit=unit)
|
||||
result = calculate_factor_levels(factor, self.total_volume_spin.value(), self.volume_unit_combo.currentText())
|
||||
if result:
|
||||
self.factors_table.blockSignals(True)
|
||||
self.factors_table.item(row, 6).setText(self._format_number(result.high))
|
||||
self.factors_table.item(row, 7).setText(self._format_number(result.low))
|
||||
self.factors_table.blockSignals(False)
|
||||
|
||||
except (ValueError, AttributeError):
|
||||
pass
|
||||
|
||||
# ========== ВКЛАДКА 3: МАТРИЦА ПЛАНИРОВАНИЯ ==========
|
||||
|
||||
def _create_design_tab(self):
|
||||
@@ -833,61 +864,66 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def _apply_project_data(self, project):
|
||||
"""Применяет загруженные данные к GUI"""
|
||||
# Применяем данные калькулятора сред
|
||||
self.total_volume_spin.setValue(project.medium_total_volume)
|
||||
|
||||
index = self.volume_unit_combo.findText(project.medium_volume_unit)
|
||||
if index >= 0:
|
||||
self.volume_unit_combo.setCurrentIndex(index)
|
||||
|
||||
self.solvent_input.setText(project.medium_solvent)
|
||||
|
||||
# Очищаем и заполняем таблицу реагентов
|
||||
self.reagents_table.setRowCount(0)
|
||||
for reagent in project.medium_reagents:
|
||||
row = self.reagents_table.rowCount()
|
||||
self.reagents_table.insertRow(row)
|
||||
self.reagents_table.setItem(row, 0, QTableWidgetItem(reagent.name))
|
||||
self.reagents_table.setItem(row, 1, QTableWidgetItem(str(reagent.percentage)))
|
||||
|
||||
unit_combo = QComboBox()
|
||||
unit_combo.addItems(["мг", "г", "кг", "мкг", "нг", "мл", "мкл", "л", "нл"])
|
||||
unit_combo.setCurrentText(reagent.unit)
|
||||
self.reagents_table.setCellWidget(row, 2, unit_combo)
|
||||
|
||||
self.reagents_table.setItem(row, 3, QTableWidgetItem(str(reagent.conversion_factor)))
|
||||
self.reagents_table.setItem(row, 4, QTableWidgetItem(str(reagent.dilution_factor)))
|
||||
self.reagents_table.setItem(row, 5, QTableWidgetItem(""))
|
||||
|
||||
# Применяем данные факторов эксперимента
|
||||
self.factors_table.setRowCount(0)
|
||||
for factor in project.experiment_factors:
|
||||
if factor.percentage is not None:
|
||||
percentage = str(factor.percentage)
|
||||
if factor.dilution_factor is not None:
|
||||
dilution = str(factor.dilution_factor)
|
||||
self._add_factor_row(factor.name, percentage, dilution, str(factor.center),
|
||||
str(factor.step), factor.step_type, str(factor.high),
|
||||
str(factor.low), factor.unit)
|
||||
# Применяем настройки эксперимента
|
||||
self.center_points_spin.setValue(project.experiment_center_points)
|
||||
self.randomize_check.setChecked(project.experiment_randomize)
|
||||
|
||||
# Если есть результаты, загружаем их
|
||||
if project.experiment_results and project.experiment_results.design:
|
||||
self.generated_design = project.experiment_results.design
|
||||
# Обновляем отображение матрицы
|
||||
self._refresh_design_matrix()
|
||||
|
||||
# Загружаем результаты в таблицу
|
||||
if project.experiment_results.results:
|
||||
for i, row_results in enumerate(project.experiment_results.results):
|
||||
if i < self.results_table.rowCount() and row_results:
|
||||
self.results_table.setItem(i, 1, QTableWidgetItem(str(row_results[0])))
|
||||
|
||||
# Переключаемся на вкладку с экспериментом
|
||||
if self.tab_widget:
|
||||
self.tab_widget.setCurrentIndex(0)
|
||||
self._loading_data = True # <- ОТКЛЮЧАЕМ ОБРАБОТЧИК
|
||||
try:
|
||||
|
||||
# Применяем данные калькулятора сред
|
||||
self.total_volume_spin.setValue(project.medium_total_volume)
|
||||
|
||||
index = self.volume_unit_combo.findText(project.medium_volume_unit)
|
||||
if index >= 0:
|
||||
self.volume_unit_combo.setCurrentIndex(index)
|
||||
|
||||
self.solvent_input.setText(project.medium_solvent)
|
||||
|
||||
# Очищаем и заполняем таблицу реагентов
|
||||
self.reagents_table.setRowCount(0)
|
||||
for reagent in project.medium_reagents:
|
||||
row = self.reagents_table.rowCount()
|
||||
self.reagents_table.insertRow(row)
|
||||
self.reagents_table.setItem(row, 0, QTableWidgetItem(reagent.name))
|
||||
self.reagents_table.setItem(row, 1, QTableWidgetItem(str(reagent.percentage)))
|
||||
|
||||
unit_combo = QComboBox()
|
||||
unit_combo.addItems(["мг", "г", "кг", "мкг", "нг", "мл", "мкл", "л", "нл"])
|
||||
unit_combo.setCurrentText(reagent.unit)
|
||||
self.reagents_table.setCellWidget(row, 2, unit_combo)
|
||||
|
||||
self.reagents_table.setItem(row, 3, QTableWidgetItem(str(reagent.conversion_factor)))
|
||||
self.reagents_table.setItem(row, 4, QTableWidgetItem(str(reagent.dilution_factor)))
|
||||
self.reagents_table.setItem(row, 5, QTableWidgetItem(""))
|
||||
|
||||
# Применяем данные факторов эксперимента
|
||||
self.factors_table.setRowCount(0)
|
||||
for factor in project.experiment_factors:
|
||||
if factor.percentage is not None:
|
||||
percentage = str(factor.percentage)
|
||||
if factor.dilution_factor is not None:
|
||||
dilution = str(factor.dilution_factor)
|
||||
self._add_factor_row(factor.name, percentage, dilution, str(factor.center),
|
||||
str(factor.step), factor.step_type, str(factor.high),
|
||||
str(factor.low), factor.unit)
|
||||
# Применяем настройки эксперимента
|
||||
self.center_points_spin.setValue(project.experiment_center_points)
|
||||
self.randomize_check.setChecked(project.experiment_randomize)
|
||||
|
||||
# Если есть результаты, загружаем их
|
||||
if project.experiment_results and project.experiment_results.design:
|
||||
self.generated_design = project.experiment_results.design
|
||||
# Обновляем отображение матрицы
|
||||
self._refresh_design_matrix()
|
||||
|
||||
# Загружаем результаты в таблицу
|
||||
if project.experiment_results.results:
|
||||
for i, row_results in enumerate(project.experiment_results.results):
|
||||
if i < self.results_table.rowCount() and row_results:
|
||||
self.results_table.setItem(i, 1, QTableWidgetItem(str(row_results[0])))
|
||||
|
||||
# Переключаемся на вкладку с экспериментом
|
||||
if self.tab_widget:
|
||||
self.tab_widget.setCurrentIndex(0)
|
||||
finally:
|
||||
self._loading_data = False # <- ВКЛЮЧАЕМ ОБРАТНО
|
||||
|
||||
def _refresh_design_matrix(self):
|
||||
"""Обновляет отображение матрицы планирования"""
|
||||
|
||||
Reference in New Issue
Block a user