Исправлен расчёт +1 и -1 факторов эксперимента

This commit is contained in:
2026-05-27 01:09:11 +05:00
parent 1ddfe20a8d
commit f479674332
3 changed files with 145 additions and 102 deletions
+49 -35
View File
@@ -13,7 +13,13 @@
from typing import List, Dict, Tuple, Optional
import random
import numpy as np
from calculations.medium import (
calculate_medium_composition,
convert_units,
VOLUME_UNITS,
MASS_UNITS
)
from calculations.models.project_data import FactorData
# Типы расчёта шага
FACTOR_TYPES = {
'absolute': 'ед.', # абсолютный шаг
@@ -22,41 +28,49 @@ FACTOR_TYPES = {
def calculate_factor_levels(
center_value: float,
step_value: float,
step_type: str,
base_value: float = None
) -> Tuple[float, float]:
"""
РАССЧИТЫВАЕТ ВЕРХНИЙ И НИЖНИЙ УРОВНИ ФАКТОРА
Параметры:
center_value: нулевой уровень фактора (центральная точка)
step_value: значение шага
step_type: тип шага ("ед." - абсолютный, "%" - относительный)
base_value: базовое значение для относительного шага (если None, используется center_value)
Возвращает:
(high_level, low_level): верхний и нижний уровни
Пример:
>>> calculate_factor_levels(100, 10, "%")
(110.0, 90.0)
>>> calculate_factor_levels(100, 20, "ед.")
(120.0, 80.0)
"""
# Определяем абсолютное значение шага
if step_type == "%":
base = base_value if base_value is not None else center_value
step_abs = center_value * step_value / 100
else: # "ед." или "absolute"
step_abs = step_value
high_level = center_value + step_abs
low_level = center_value - step_abs
return high_level, low_level
factor: 'FactorData',
total_volume: float = 1000,
volume_unit: str = "мл"
) -> 'FactorData':
"""Рассчитывает high/low уровни фактора через калькулятор сред"""
# Функция для расчёта количества реагента при заданном проценте
def calc_amount(percentage: float) -> float:
reagents = [{
'name': factor.name,
'percentage': max(0, percentage),
'unit': factor.unit,
'dilution_factor': factor.dilution_factor or 1.0
}]
result = calculate_medium_composition(total_volume, volume_unit, reagents)
return result['reagents'][0]['calculated_amount']
# Определяем проценты для верхнего и нижнего уровней
if factor.step_type == "%":
low = calc_amount(factor.percentage - factor.step) # low - нижний уровень
high = calc_amount(factor.percentage + factor.step) # high - верхний уровень
else: # "ед."
# Конвертируем абсолютный шаг в проценты
low = calc_amount(factor.percentage) - factor.step
high = calc_amount(factor.percentage) + factor.step
# ВОЗВРАЩАЕМ НОВЫЙ ОБЪЕКТ FactorData
return FactorData(
name=factor.name,
center=factor.center,
low=low, # low - нижний уровень
high=high, # high - верхний уровень
step=factor.step,
step_type=factor.step_type,
unit=factor.unit,
percentage=factor.percentage or factor.center,
dilution_factor=factor.dilution_factor
)
def calculate_all_factors_levels(factors: List['FactorData'], **kwargs) -> List['FactorData']:
"""Рассчитывает уровни для всех факторов"""
return [calculate_factor_levels(f, **kwargs) for f in factors]
def generate_factorial_design(
factors: List[Dict],