From 821a1eb4730113d4e0154123f20dca0dda60c1e8 Mon Sep 17 00:00:00 2001 From: AnnZhimol Date: Mon, 9 Dec 2024 22:32:11 +0300 Subject: [PATCH] added plot --- .../ch_experimentdb_experiment_data_repos.py | 4 +- .../experiment_parameters_repos.py | 2 - main.py | 39 +++++++++++++ .../routes/experiment_parameters_router.py | 55 +++++++++++++++++- network/schemas.py | 6 ++ requirements.txt | Bin 1598 -> 1636 bytes 6 files changed, 101 insertions(+), 5 deletions(-) diff --git a/db/repositories/ch_experimentdb_experiment_data_repos.py b/db/repositories/ch_experimentdb_experiment_data_repos.py index 6356244..780cec7 100644 --- a/db/repositories/ch_experimentdb_experiment_data_repos.py +++ b/db/repositories/ch_experimentdb_experiment_data_repos.py @@ -1,3 +1,5 @@ +from typing import List + from db.models.ch_experimentdb_experiment_data_model import ChExperimentDBExperimentData from sqlalchemy import select,func @@ -11,7 +13,7 @@ class ChExperimentDBExperimentDataRepository: def get_by_id(self, id: int) -> ChExperimentDBExperimentData: return self.session.query(ChExperimentDBExperimentData).filter(ChExperimentDBExperimentData.id == id).one_or_none() - def get_by_file_id(self, file_id: str) -> ChExperimentDBExperimentData: + def get_by_file_id(self, file_id: str) -> List[ChExperimentDBExperimentData]: return self.session.query(ChExperimentDBExperimentData).filter(ChExperimentDBExperimentData.file_id == file_id).all() def create(self, ch_experiment_data: ChExperimentDBExperimentData) -> ChExperimentDBExperimentData: diff --git a/db/repositories/experiment_parameters_repos.py b/db/repositories/experiment_parameters_repos.py index 67e7e1c..8fc7de1 100644 --- a/db/repositories/experiment_parameters_repos.py +++ b/db/repositories/experiment_parameters_repos.py @@ -37,11 +37,9 @@ def generate_experiment_hash(data: dict) -> str: async def save_experiment_to_db(df: pd.DataFrame): for _, row in df.iterrows(): try: - # Преобразуем load и recycling_level в соответствующие id load = int(row['load']) recycling = int(row['recycling_level']) - # Генерация хеша для experiment_hash experiment_hash = generate_experiment_hash(row) exp = await create( diff --git a/main.py b/main.py index 74e5fdd..9cdc769 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,19 @@ +from random import uniform, random +from traceback import format_exc + import pandas as pd from fastapi import FastAPI, HTTPException, BackgroundTasks from pyDOE3 import pbdesign, lhs from db.csv_to_db import csv_to_db +from db.models import ChExperimentDBExperimentData from db.repositories import save_experiment_to_db from network.routes import (ch_experimentdb_experiment_data_router, experiment_data_router, experiment_parameters_router, experiment_category_router) from network.routes import load_parameters_router, recycling_parameters_router +from network.routes.ch_experimentdb_experiment_data_router import create_ch_experimentdb_experiment_data +from network.routes.experiment_data_router import create_experiment_data +from network.routes.experiment_parameters_router import get_all_experiment_parameters from network.schemas import * from new_experiment_planner import run_experiment from new_experiment_planner_pyDOE3 import scale_design, scale_design_lhs, round_by_index @@ -61,6 +68,38 @@ async def init_db_data(background_tasks: BackgroundTasks): print(str(e.with_traceback())) raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") +@app.get('/init_data_plot') +async def init_data_plot(): + try: + parameters = await get_all_experiment_parameters() + + async def generate_data_for_file_id(file_id): + for _ in range(100): + await create_ch_experimentdb_experiment_data( + ChExperimentDBExperimentData( + volume=uniform(1e-8, 6.3e-6), + nitrogen_oxide_emission=uniform(2.7e-10, 8.92e-10), + temperature=uniform(1543.0, 2432.0), + co_fraction=uniform(0.0875, 0.4567), + co2_fraction=uniform(0.0824, 0.5678), + x=uniform(0.0002, 0.9849), + y=uniform(4.25, 10.31), + z=uniform(4.20, 10.26), + file_id=file_id + ) + ) + + for param in parameters: + print(param) + file_id = param.experiment_hash + if file_id: + await generate_data_for_file_id(file_id) + + return {"status": "success", "message": "Добавление данных в БД успешно завершено"} + except Exception as e: + print(format_exc()) + raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") + # Пример запроса # { # "param_ranges": { diff --git a/network/routes/experiment_parameters_router.py b/network/routes/experiment_parameters_router.py index 2487c36..5ca0127 100644 --- a/network/routes/experiment_parameters_router.py +++ b/network/routes/experiment_parameters_router.py @@ -1,12 +1,19 @@ import yaml from fastapi import APIRouter, HTTPException -from scipy.stats import alpha +from pydantic import BaseModel +from typing import List, Tuple +import matplotlib.pyplot as plt +from matplotlib import cm +from mpl_toolkits.mplot3d import Axes3D +import io +import base64 from db.crud import * from db.models import LoadParameters from db.repositories import get_exp_parameters_by_category, get_exp_parameters_by_exp_hash from macros_generator import load_calculation, recycling_calculation -from network.schemas import ExperimentParametersBody +from network.routes.ch_experimentdb_experiment_data_router import get_ch_experimentdb_experiment_data_by_file_id +from network.schemas import ExperimentParametersBody, ExperimentParametersPlot router = APIRouter() @@ -28,6 +35,50 @@ async def create_experiment_parameters(body: ExperimentParametersBody): except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") +@router.post('/plot') +async def create_plot(body: ExperimentParametersPlot): + try: + exp_data = await get_ch_experimentdb_experiment_data_by_file_id(body.file_id) + if not exp_data: + raise HTTPException(status_code=404, detail="Данные не найдены для указанного file_id") + + filtered_data = [ + record for record in exp_data + if body.range[0] <= getattr(record, body.additional_dimension, None) <= body.range[1] + ] + + if not filtered_data: + return {"message": "Нет данных для отображения в заданном диапазоне"} + + x = [record.x for record in filtered_data] + y = [record.y for record in filtered_data] + z = [record.z for record in filtered_data] + color_values = [getattr(record, body.additional_dimension, None) for record in filtered_data] + + fig = plt.figure(figsize=(10, 8)) + ax = fig.add_subplot(111, projection='3d') + scatter = ax.scatter(x, y, z, c=color_values, cmap=cm.viridis, marker='o') + + cbar = fig.colorbar(scatter, ax=ax) + cbar.set_label(body.additional_dimension) + + ax.set_xlabel('X') + ax.set_ylabel('Y') + ax.set_zlabel('Z') + + plt.title(f"3D график с измерением: {body.additional_dimension}") + + buf = io.BytesIO() + plt.savefig(buf, format='png') + buf.seek(0) + image_base64 = base64.b64encode(buf.getvalue()).decode('utf-8') + buf.close() + plt.close(fig) + + return {"message": "График построен успешно", "plot": image_base64} + + except Exception as e: + raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") @router.get('/all') async def get_all_experiment_parameters(): diff --git a/network/schemas.py b/network/schemas.py index d59261d..537061a 100644 --- a/network/schemas.py +++ b/network/schemas.py @@ -1,5 +1,7 @@ +from enum import Enum from typing import Optional, Dict, Tuple, List +from psycopg.types import enum from pydantic import BaseModel, ConfigDict class ExperimentParametersPyDOE3(BaseModel): @@ -15,6 +17,10 @@ class ExperimentParameters(BaseModel): load: str recycling: str +class ExperimentParametersPlot(BaseModel): + file_id: str + additional_dimension: str + range: Tuple[float, float] class ChExperimentDBExperimentDataBody(BaseModel): model_config = ConfigDict(from_attributes=True) diff --git a/requirements.txt b/requirements.txt index 804802e5dd95e7801217a661495d488a4d0ccb15..68b34760109bca8f7a8b812a448d4d3661754f9c 100644 GIT binary patch delta 46 ycmdnT^Mq%E9h(|20~bRsLn1>7Ljgk$Lq3qsVaQ}iVyI)VWiV#YW3U8bV+H{C-U!+N delta 7 OcmaFDvyW$k9UA}*0|KuA