Теперь фактор, шаг которого равен нулю, не учитывается, но отображается отдельным столбцом с однаковым значением.
This commit is contained in:
+8
-1
@@ -53,7 +53,7 @@ def calculate_factor_levels(
|
|||||||
else: # "ед."
|
else: # "ед."
|
||||||
# Конвертируем абсолютный шаг в проценты
|
# Конвертируем абсолютный шаг в проценты
|
||||||
low = calc_amount(factor.percentage) - factor.step
|
low = calc_amount(factor.percentage) - factor.step
|
||||||
high = calc_amount(factor.percentage) + factor.step
|
high = calc_amount(factor.center) + factor.step
|
||||||
|
|
||||||
# ВОЗВРАЩАЕМ НОВЫЙ ОБЪЕКТ FactorData
|
# ВОЗВРАЩАЕМ НОВЫЙ ОБЪЕКТ FactorData
|
||||||
return FactorData(
|
return FactorData(
|
||||||
@@ -72,6 +72,12 @@ def calculate_all_factors_levels(factors: List['FactorData'], **kwargs) -> List[
|
|||||||
"""Рассчитывает уровни для всех факторов"""
|
"""Рассчитывает уровни для всех факторов"""
|
||||||
return [calculate_factor_levels(f, **kwargs) for f in factors]
|
return [calculate_factor_levels(f, **kwargs) for f in factors]
|
||||||
|
|
||||||
|
def get_active_factors(factors):
|
||||||
|
return [f for f in factors if f['step'] != 0]
|
||||||
|
|
||||||
|
def get_inactive_factors(factors):
|
||||||
|
return [f for f in factors if f['step'] == 0]
|
||||||
|
|
||||||
def generate_factorial_design(
|
def generate_factorial_design(
|
||||||
factors: List[Dict],
|
factors: List[Dict],
|
||||||
center_points: int = 3,
|
center_points: int = 3,
|
||||||
@@ -159,6 +165,7 @@ def generate_factorial_design(
|
|||||||
# Добавление центральных точек
|
# Добавление центральных точек
|
||||||
for i in range(center_points):
|
for i in range(center_points):
|
||||||
center_experiment = {}
|
center_experiment = {}
|
||||||
|
|
||||||
for j in range(k):
|
for j in range(k):
|
||||||
center_experiment[f"Фактор_{j+1}"] = {
|
center_experiment[f"Фактор_{j+1}"] = {
|
||||||
'coded': 0,
|
'coded': 0,
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ from calculations.doe import (
|
|||||||
generate_factorial_design,
|
generate_factorial_design,
|
||||||
analyze_experiment,
|
analyze_experiment,
|
||||||
calculate_factor_levels,
|
calculate_factor_levels,
|
||||||
|
get_active_factors,
|
||||||
|
get_inactive_factors,
|
||||||
FACTOR_TYPES
|
FACTOR_TYPES
|
||||||
)
|
)
|
||||||
# Импорт моделей для JSON
|
# Импорт моделей для JSON
|
||||||
@@ -439,7 +441,7 @@ class MainWindow(QMainWindow):
|
|||||||
step_item = self.factors_table.item(row, 4)
|
step_item = self.factors_table.item(row, 4)
|
||||||
high_item = self.factors_table.item(row, 6)
|
high_item = self.factors_table.item(row, 6)
|
||||||
low_item = self.factors_table.item(row, 7)
|
low_item = self.factors_table.item(row, 7)
|
||||||
unit_item = self.factors_table.item(row, 8)
|
unit_item = self.factors_table.cellWidget(row, 8)
|
||||||
step_combo = self.factors_table.cellWidget(row, 5)
|
step_combo = self.factors_table.cellWidget(row, 5)
|
||||||
|
|
||||||
if not all([name_item, center_item, high_item, low_item]):
|
if not all([name_item, center_item, high_item, low_item]):
|
||||||
@@ -457,7 +459,7 @@ class MainWindow(QMainWindow):
|
|||||||
'center': float(center_text),
|
'center': float(center_text),
|
||||||
'high': float(high_text),
|
'high': float(high_text),
|
||||||
'low': float(low_text),
|
'low': float(low_text),
|
||||||
'unit': unit_item.text() if unit_item else "",
|
'unit': unit_item.currentText() if unit_item else "г",
|
||||||
'step': float(step_item.text()) if step_item and step_item.text() else 0,
|
'step': float(step_item.text()) if step_item and step_item.text() else 0,
|
||||||
'step_type': step_combo.currentText() if step_combo else "ед."
|
'step_type': step_combo.currentText() if step_combo else "ед."
|
||||||
}
|
}
|
||||||
@@ -524,11 +526,14 @@ class MainWindow(QMainWindow):
|
|||||||
layout.addWidget(self.design_info)
|
layout.addWidget(self.design_info)
|
||||||
|
|
||||||
return tab
|
return tab
|
||||||
|
|
||||||
def _generate_design(self):
|
def _generate_design(self):
|
||||||
"""Генерирует план эксперимента"""
|
"""Генерирует план эксперимента"""
|
||||||
factors = self._get_factors_from_table()
|
all_factors = self._get_factors_from_table()
|
||||||
|
factors = get_active_factors(all_factors)
|
||||||
|
# Выбираем только те факторы, шаг которых не равен нулю
|
||||||
|
i_factors = get_inactive_factors(all_factors)
|
||||||
|
# Отдельно сохраняем неактивные факторы
|
||||||
if len(factors) == 0:
|
if len(factors) == 0:
|
||||||
QMessageBox.warning(self, "Предупреждение", "Добавьте хотя бы один фактор!")
|
QMessageBox.warning(self, "Предупреждение", "Добавьте хотя бы один фактор!")
|
||||||
return
|
return
|
||||||
@@ -539,27 +544,24 @@ class MainWindow(QMainWindow):
|
|||||||
center_points=self.center_points_spin.value(),
|
center_points=self.center_points_spin.value(),
|
||||||
randomize=self.randomize_check.isChecked()
|
randomize=self.randomize_check.isChecked()
|
||||||
)
|
)
|
||||||
|
|
||||||
self.generated_design = design
|
self.generated_design = design
|
||||||
|
|
||||||
n_exp = len(design)
|
n_exp = len(design)
|
||||||
n_factors = len(factors)
|
n_factors = len(factors)
|
||||||
|
n_i_factors = len(i_factors)
|
||||||
self.design_matrix.setRowCount(n_exp)
|
self.design_matrix.setRowCount(n_exp)
|
||||||
self.design_matrix.setColumnCount(n_factors + 2)
|
self.design_matrix.setColumnCount(n_factors + 3)
|
||||||
headers = ["№"] + [f['name'] for f in factors] + ["Тип"]
|
headers = [f['name'] for f in factors] + [f['name'] for f in i_factors] + ["Растворитель"] +["Тип"] +["Отклик"]
|
||||||
self.design_matrix.setHorizontalHeaderLabels(headers)
|
self.design_matrix.setHorizontalHeaderLabels(headers)
|
||||||
|
|
||||||
for exp_idx, exp in enumerate(design):
|
for exp_idx, exp in enumerate(design):
|
||||||
self.design_matrix.setItem(exp_idx, 0, QTableWidgetItem(str(exp_idx + 1)))
|
|
||||||
|
|
||||||
for f_idx in range(n_factors):
|
for f_idx in range(n_factors):
|
||||||
key = f"Фактор_{f_idx + 1}"
|
key = f"Фактор_{f_idx+1}"
|
||||||
if key not in exp:
|
if key not in exp:
|
||||||
continue
|
continue
|
||||||
value = exp[key]['natural']
|
value = exp[key]['natural']
|
||||||
unit = factors[f_idx]['unit']
|
unit = factors[f_idx]['unit']
|
||||||
|
|
||||||
display = self._format_number(value)
|
display = self._format_number(value)
|
||||||
if unit:
|
if unit:
|
||||||
display += f" {unit}"
|
display += f" {unit}"
|
||||||
@@ -567,14 +569,25 @@ class MainWindow(QMainWindow):
|
|||||||
item = QTableWidgetItem(display)
|
item = QTableWidgetItem(display)
|
||||||
if exp.get('is_center', False):
|
if exp.get('is_center', False):
|
||||||
item.setBackground(QColor(255, 255, 200))
|
item.setBackground(QColor(255, 255, 200))
|
||||||
self.design_matrix.setItem(exp_idx, f_idx + 1, item)
|
self.design_matrix.setItem(exp_idx, f_idx, item)
|
||||||
|
if n_i_factors>0:
|
||||||
|
for f_idx in range(n_i_factors):
|
||||||
|
value = i_factors[f_idx]['center']
|
||||||
|
unit = i_factors[f_idx]['unit']
|
||||||
|
display = self._format_number(value)
|
||||||
|
if unit:
|
||||||
|
display += f" {unit}"
|
||||||
|
item = QTableWidgetItem(display)
|
||||||
|
|
||||||
|
item.setBackground(QColor(255, 255, 200))
|
||||||
|
self.design_matrix.setItem(exp_idx, n_factors + f_idx, item)
|
||||||
|
|
||||||
if exp.get('is_center', False):
|
if exp.get('is_center', False):
|
||||||
type_item = QTableWidgetItem(f"Центр #{exp['center_num']}")
|
type_item = QTableWidgetItem(f"Центр #{exp['center_num']}")
|
||||||
type_item.setBackground(QColor(255, 255, 200))
|
type_item.setBackground(QColor(255, 255, 200))
|
||||||
else:
|
else:
|
||||||
type_item = QTableWidgetItem("Факторная")
|
type_item = QTableWidgetItem("Факторная")
|
||||||
self.design_matrix.setItem(exp_idx, n_factors + 1, type_item)
|
self.design_matrix.setItem(exp_idx, n_factors+n_i_factors, type_item)
|
||||||
|
|
||||||
self.design_matrix.resizeColumnsToContents()
|
self.design_matrix.resizeColumnsToContents()
|
||||||
|
|
||||||
@@ -600,7 +613,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.results_table.setHorizontalHeaderLabels(["№ опыта", "Результат"])
|
self.results_table.setHorizontalHeaderLabels(["№ опыта", "Результат"])
|
||||||
|
|
||||||
for i in range(n_experiments):
|
for i in range(n_experiments):
|
||||||
self.results_table.setItem(i, 0, QTableWidgetItem(str(i + 1)))
|
self.results_table.setItem(i, 0, QTableWidgetItem(str(i)))
|
||||||
|
|
||||||
def _export_design_csv(self):
|
def _export_design_csv(self):
|
||||||
"""Экспортирует матрицу планирования в CSV"""
|
"""Экспортирует матрицу планирования в CSV"""
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
# main.py
|
# main.py
|
||||||
"""
|
"""
|
||||||
Биохимический помощник - точка входа в приложение
|
Биохимический помощник - точка входа в приложение
|
||||||
|
TODO:
|
||||||
|
- Добавить информацию о количестве раствора в DOE
|
||||||
|
- Не считать фактор, если его шаг 0 ОК
|
||||||
|
- Добавить столбец в матрицу планирования с информацией о количестве добавленного растворителя, учитывая все реагенты
|
||||||
|
- Начать делать анализ
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
Reference in New Issue
Block a user