update simulation api

feature/reliability_stat
Cizz22 1 year ago
parent 970df9e179
commit f4a50706d1

@ -1,3 +1,5 @@
from typing import Optional
from uuid import UUID
import numpy as np import numpy as np
from sqlalchemy import Select, func, select from sqlalchemy import Select, func, select
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
@ -7,7 +9,7 @@ from src.scope.model import Scope
from src.database.core import DbSession from src.database.core import DbSession
from src.scope.service import get_all from src.scope.service import get_all
from .schema import CalculationTimeConstrainsParametersRead, CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersCreate from .schema import CalculationTimeConstrainsParametersRead, CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersCreate
from .service import get_overhaul_cost_by_time_chart, get_corrective_cost_time_chart, create_param_and_data, get_calculation_data_by_id from .service import get_calculation_by_reference_and_parameter, get_calculation_result, get_overhaul_cost_by_time_chart, get_corrective_cost_time_chart, create_param_and_data, get_calculation_data_by_id, create_calculation_result_service
from .model import CalculationResult from .model import CalculationResult
from .model import CalculationParam from .model import CalculationParam
@ -61,38 +63,40 @@ async def get_create_calculation_parameters(*, db_session: DbSession, calculatio
) )
async def create_calculation(*, db_session: DbSession, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, created_by:str): async def create_calculation(*, db_session: DbSession, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, created_by: str):
days = 60
##
calculation_data = await create_param_and_data( calculation_data = await create_param_and_data(
db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=created_by) db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=created_by)
overhaul_cost_points = get_overhaul_cost_by_time_chart( results = await create_calculation_result_service(db_session=db_session, calculation_id=calculation_data.id)
calculation_time_constrains_in.overhaulCost, days)
corrective_cost_points, dailyNumberOfFailure = get_corrective_cost_time_chart(
calculation_time_constrains_in.costPerFailure, days)
total_cost = overhaul_cost_points + corrective_cost_points return results
optimumOH = np.argmin(total_cost)
numbersOfFailure = sum(dailyNumberOfFailure[:optimumOH])
# raise Exception(optimumOH) async def get_or_create_scope_equipment_calculation(*, db_session: DbSession, scope_calculation_id, calculation_time_constrains_in: Optional[CalculationTimeConstrainsParametersCreate]):
scope_calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=scope_calculation_id)
calculation_results = [] if not scope_calculation:
for i in range(days): raise HTTPException(
result = CalculationResult( status_code=status.HTTP_404_NOT_FOUND,
parameter_id=calculation_data.parameter_id, detail="A data with this id does not exist.",
calculation_data_id=calculation_data.id,
day=(i + 1),
corrective_cost=float(corrective_cost_points[i]),
overhaul_cost=float(overhaul_cost_points[i]),
num_failures=int(dailyNumberOfFailure[i]),
) )
calculation_results.append(result)
db_session.add_all(calculation_results) # Check if calculation already exist
await db_session.commit() scope_equipment_calculation = await get_calculation_by_reference_and_parameter(
db_session=db_session, calculation_reference_id=calculation_time_constrains_in.assetnum, parameter_id=scope_calculation.parameter_id)
return calculation_data.id if not scope_equipment_calculation:
# Update Parameter input from scope calculation
calculation_time_constrains_in.costPerFailure = scope_calculation.parameter.avg_failure_cost
calculation_time_constrains_in.overhaulCost = scope_calculation.parameter.overhaul_cost
scope_equipment_calculation = await create_param_and_data(
db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=scope_calculation.created_by, parameter_id=scope_calculation.parameter_id)
results = await create_calculation_result_service(db_session=db_session, calculation_id=scope_equipment_calculation.id)
return results
results = await get_calculation_result(db_session=db_session, calculation_id=scope_equipment_calculation.id)
return results

@ -1,7 +1,7 @@
from enum import Enum from enum import Enum
from typing import List, Union from typing import List, Optional, Union
from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from src.database.core import Base, DbSession from src.database.core import Base, DbSession
@ -63,7 +63,8 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
parameter_id = Column(UUID(as_uuid=True), ForeignKey( parameter_id = Column(UUID(as_uuid=True), ForeignKey(
'oh_ms_calculation_param.id'), nullable=True) 'oh_ms_calculation_param.id'), nullable=True)
overhaul_reference_type = Column(String(10), nullable=False) overhaul_reference_type = Column(String(10), nullable=False)
reference_id = Column(UUID(as_uuid=True), nullable=False) reference_id = Column(String, nullable=False)
optimum_oh_day = Column(Integer, nullable=True)
parameter = relationship( parameter = relationship(
"CalculationParam", back_populates="calculation_data") "CalculationParam", back_populates="calculation_data")
@ -78,33 +79,35 @@ class CalculationData(Base, DefaultMixin, IdentityMixin):
overhaul_reference_type: str, overhaul_reference_type: str,
reference_id: Union[str, UUID], reference_id: Union[str, UUID],
db: DbSession, db: DbSession,
avg_failure_cost: float, avg_failure_cost: Optional[float],
overhaul_cost: float, overhaul_cost: Optional[float],
created_by: str, created_by: str,
params_id: Optional[UUID]
): ):
# Create Params if not params_id:
params = CalculationParam( # Create Params
avg_failure_cost=avg_failure_cost, params = CalculationParam(
overhaul_cost=overhaul_cost, avg_failure_cost=avg_failure_cost,
created_by=created_by overhaul_cost=overhaul_cost,
) created_by=created_by
)
db.add(params) db.add(params)
await db.flush() await db.flush()
params_id = params.id
calculation_data = cls( calculation_data = cls(
overhaul_reference_type=overhaul_reference_type, overhaul_reference_type=overhaul_reference_type,
reference_id=reference_id, reference_id=str(reference_id),
created_by=created_by, created_by=created_by,
parameter_id=params.id parameter_id=params_id
) )
db.add(calculation_data) db.add(calculation_data)
await db.commit() await db.commit()
await db.refresh(calculation_data) await db.refresh(calculation_data)
return calculation_data return calculation_data

@ -6,18 +6,25 @@ from src.database.core import DbSession
from src.models import StandardResponse from src.models import StandardResponse
from src.auth.service import CurrentUser from src.auth.service import CurrentUser
from .service import create_param_and_data, get_calculation_result from .service import create_param_and_data, get_calculation_result
from .flows import get_create_calculation_parameters, create_calculation from .flows import get_create_calculation_parameters, create_calculation, get_or_create_scope_equipment_calculation
from fastapi.params import Query from fastapi.params import Query
router = APIRouter() router = APIRouter()
@router.post("", response_model=StandardResponse[str]) @router.post("", response_model=StandardResponse[Union[str, CalculationTimeConstrainsRead]])
async def create_calculation_time_constrains(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate): async def create_calculation_time_constrains(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate, scope_calculation_id: Optional[str] = Query(None), with_results: Optional[int] = Query(0)):
"""Save calculation time constrains Here""" """Save calculation time constrains Here"""
calculation_data = await create_calculation(db_session=db_session, calculation_time_constrains_in=calculation_time_constrains_in, created_by=current_user.name)
return StandardResponse(data=str(calculation_data), message="Data created successfully") if scope_calculation_id:
results = await get_or_create_scope_equipment_calculation(db_session=db_session, scope_calculation_id=scope_calculation_id, calculation_time_constrains_in=calculation_time_constrains_in)
else:
results = await create_calculation(db_session=db_session, calculation_time_constrains_in=calculation_time_constrains_in, created_by=current_user.name)
if not with_results:
results = str(results.id)
return StandardResponse(data=results, message="Data created successfully")
@router.get("/parameters", response_model=StandardResponse[Union[CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersRead]]) @router.get("/parameters", response_model=StandardResponse[Union[CalculationTimeConstrainsParametersRetrive, CalculationTimeConstrainsParametersRead]])
@ -37,37 +44,23 @@ async def get_calculation_results(db_session: DbSession, calculation_id):
results = await get_calculation_result(db_session=db_session, calculation_id=calculation_id) results = await get_calculation_result(db_session=db_session, calculation_id=calculation_id)
return StandardResponse( return StandardResponse(
data=CalculationTimeConstrainsRead( data=results,
id=calculation_id,
results=results
),
message="Data retrieved successfully", message="Data retrieved successfully",
) )
@router.post("/simulation", response_model=StandardResponse[Dict[str, Any]])
# @router.post("/parameters", response_model=StandardResponse[str]) async def get_simulation_result():
# async def create_calculation_time_constrains_parameter(db_session: DbSession, current_user: CurrentUser, calculation_time_constrains_in: CalculationTimeConstrainsParametersCreate): results = {
# """Save parameter Here""" "simulation": {
# parameters = await create_param(db_session=db_session, calculation_param_in=calculation_time_constrains_in, created_by=current_user.name) "intervalDays": 45,
"numberOfFailures": 75,
# return StandardResponse(data=str(parameters.id), message="Parameter Data created successfully") "totalCost": 550000000,
},
"comparison": {
# @router.get("/simulation", response_model=StandardResponse[Dict[str, Any]]) "vsOptimal": {
# async def get_simulation_result(): "failureDifference": 16,
"costDifference": 50000000
# results = { },
# "simulation": { }
# "intervalDays": 45, }
# "numberOfFailures": 75, return StandardResponse(data=results, message="Data retrieved successfully")
# "totalCost": 550000000,
# },
# "comparison": {
# "vsOptimal": {
# "failureDifference": 16,
# "costDifference": 50000000
# },
# }
# }
# return StandardResponse(data=results, message="Data retrieved successfully")

@ -36,10 +36,11 @@ class CalculationTimeConstrainsParametersRead(CalculationTimeConstrainsBase):
class CalculationTimeConstrainsParametersCreate(CalculationTimeConstrainsBase): class CalculationTimeConstrainsParametersCreate(CalculationTimeConstrainsBase):
overhaulCost: float = Field(..., description="Overhaul cost") overhaulCost: Optional[float] = Field(0, description="Overhaul cost")
scopeOH: Optional[str] = Field(None, description="Scope OH") scopeOH: Optional[str] = Field(None, description="Scope OH")
assetnum: Optional[str] = Field(None, description="Assetnum") assetnum: Optional[str] = Field(None, description="Assetnum")
costPerFailure: float = Field(..., description="Cost per failure") costPerFailure: Optional[float] = Field(0,
description="Cost per failure")
# class CalculationTimeConstrainsCreate(CalculationTimeConstrainsBase): # class CalculationTimeConstrainsCreate(CalculationTimeConstrainsBase):
@ -57,7 +58,9 @@ class CalculationResultsRead(CalculationTimeConstrainsBase):
class CalculationTimeConstrainsRead(CalculationTimeConstrainsBase): class CalculationTimeConstrainsRead(CalculationTimeConstrainsBase):
id: Union[UUID, str] id: Union[UUID, str]
reference: str
results: List[CalculationResultsRead] results: List[CalculationResultsRead]
optimumOh: Dict[str, Any]
class CalculationTimeConstrainsSimulationRead(CalculationTimeConstrainsBase): class CalculationTimeConstrainsSimulationRead(CalculationTimeConstrainsBase):

@ -1,11 +1,13 @@
from typing import Optional
from uuid import UUID
import numpy as np import numpy as np
from sqlalchemy import select from sqlalchemy import and_, select
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from src.database.core import DbSession from src.database.core import DbSession
from .schema import CalculationTimeConstrainsParametersCreate from .schema import CalculationTimeConstrainsParametersCreate, CalculationTimeConstrainsRead
from .model import CalculationParam, OverhaulReferenceType, CalculationData, CalculationResult from .model import CalculationParam, OverhaulReferenceType, CalculationData, CalculationResult
from fastapi import HTTPException, status from fastapi import HTTPException, status
from src.scope.service import get_by_scope_name from src.scope.service import get_by_scope_name, get
def get_overhaul_cost_by_time_chart(overhaul_cost: float, days: int) -> list: def get_overhaul_cost_by_time_chart(overhaul_cost: float, days: int) -> list:
@ -35,7 +37,7 @@ def get_corrective_cost_time_chart(cost_per_failure: float, days: int) -> list:
return corrective_costs, failure_counts return corrective_costs, failure_counts
async def create_param_and_data(*, db_session: DbSession, calculation_param_in: CalculationTimeConstrainsParametersCreate, created_by: str): async def create_param_and_data(*, db_session: DbSession, calculation_param_in: CalculationTimeConstrainsParametersCreate, created_by: str, parameter_id: Optional[UUID] = None):
"""Creates a new document.""" """Creates a new document."""
if calculation_param_in.scopeOH is None and calculation_param_in.assetnum is None: if calculation_param_in.scopeOH is None and calculation_param_in.assetnum is None:
raise HTTPException( raise HTTPException(
@ -67,18 +69,37 @@ async def create_param_and_data(*, db_session: DbSession, calculation_param_in:
avg_failure_cost=calculation_param_in.costPerFailure, avg_failure_cost=calculation_param_in.costPerFailure,
overhaul_cost=calculation_param_in.overhaulCost, overhaul_cost=calculation_param_in.overhaulCost,
created_by=created_by, created_by=created_by,
params_id=parameter_id
) )
return calculationData return calculationData
async def get_calculation_result(db_session: DbSession, calculation_id: str): async def get_calculation_result(db_session: DbSession, calculation_id: str):
calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=calculation_id)
reference = calculation.reference_id if calculation.overhaul_reference_type == OverhaulReferenceType.ASSET else await get(db_session=db_session, scope_id=calculation.reference_id)
stmt = select(CalculationResult).filter( stmt = select(CalculationResult).filter(
CalculationResult.calculation_data_id == calculation_id).order_by(CalculationResult.day) CalculationResult.calculation_data_id == calculation_id).order_by(CalculationResult.day)
results = await db_session.execute(stmt)
return results.scalars().all() optimum = stmt.filter(CalculationResult.day == calculation.optimum_oh_day)
results = await db_session.execute(stmt)
optimumOh = await db_session.scalar(optimum)
optimumRes = {
"overhaulCost": optimumOh.overhaul_cost,
"correctiveCost": optimumOh.corrective_cost,
"numOfFailures": optimumOh.num_failures,
"days": optimumOh.day
}
return CalculationTimeConstrainsRead(
id=calculation.id,
reference=reference if isinstance(
reference, str) else reference.scope_name,
results=results.scalars().all(),
optimumOh=optimumRes
)
async def get_calculation_data_by_id(db_session: DbSession, calculation_id) -> CalculationData: async def get_calculation_data_by_id(db_session: DbSession, calculation_id) -> CalculationData:
@ -87,3 +108,68 @@ async def get_calculation_data_by_id(db_session: DbSession, calculation_id) -> C
result = await db_session.execute(stmt) result = await db_session.execute(stmt)
return result.unique().scalar() return result.unique().scalar()
async def create_calculation_result_service(db_session: DbSession, calculation_id: UUID):
days = 60
calculation = await get_calculation_data_by_id(db_session=db_session, calculation_id=calculation_id)
reference = calculation.reference_id if calculation.overhaul_reference_type == OverhaulReferenceType.ASSET else await get(db_session=db_session, scope_id=calculation.reference_id)
# Parameter
overhaulCost = calculation.parameter.overhaul_cost
costPerFailure = calculation.parameter.avg_failure_cost
overhaul_cost_points = get_overhaul_cost_by_time_chart(
overhaulCost, days=days)
corrective_cost_points, dailyNumberOfFailure = get_corrective_cost_time_chart(
costPerFailure, days)
total_cost = overhaul_cost_points + corrective_cost_points
optimumOHIndex = np.argmin(total_cost)
numbersOfFailure = sum(dailyNumberOfFailure[:optimumOHIndex])
optimum = {
"overhaulCost": float(overhaul_cost_points[optimumOHIndex]),
"correctiveCost": float(corrective_cost_points[optimumOHIndex]),
"numOfFailures": int(numbersOfFailure),
"days": int(optimumOHIndex+1)
}
calculation_results = []
for i in range(days):
result = CalculationResult(
parameter_id=calculation.parameter_id,
calculation_data_id=calculation.id,
day=(i + 1),
corrective_cost=float(corrective_cost_points[i]),
overhaul_cost=float(overhaul_cost_points[i]),
num_failures=int(dailyNumberOfFailure[i]),
)
calculation_results.append(result)
calculation.optimum_oh_day = int(optimumOHIndex+1)
db_session.add_all(calculation_results)
await db_session.commit()
return CalculationTimeConstrainsRead(
id=calculation.id,
reference=reference if isinstance(
reference, str) else reference.scope_name,
results=calculation_results,
optimumOh=optimum
)
async def get_calculation_by_reference_and_parameter(*, db_session: DbSession, calculation_reference_id, parameter_id):
stmt = select(CalculationData).filter(and_(
CalculationData.reference_id == calculation_reference_id,
CalculationData.parameter_id == parameter_id,
))
result = await db_session.execute(stmt)
return result.scalar()

Loading…
Cancel
Save