Source code for histopath_bim_des.config.resources

"""Resource configuration module for the histopath simulation model."""
import typing as ty

import pandas as pd
import pydantic as pyd
from annotated_types import Annotated, Len
from openpyxl import Workbook

from .. import excel


[docs] class ResourceSchedule(pyd.BaseModel): """A resource allocation schedule.""" day_flags: Annotated[ty.Sequence[bool], Len(7, 7)] """True/1 if resource is scheduled for the day (MON to SUN), False/0 otherwise.""" allocation: Annotated[ty.Sequence[pyd.NonNegativeInt], Len(48, 48)] """Number of resource units allocated for the day (in 30-min intervals), if the corresponding day flag is set to 1. The list length is expected to be 48."""
[docs] @staticmethod def from_pd(df: pd.DataFrame, row_name: str) -> 'ResourceSchedule': """Construct a resource schedule from a DataFrame row. Args: df: The dataframe containing the resource allocation information. row_name: The name of the resource, matching a row index in the inputted dataframe. """ return __class__( day_flags=df.loc[row_name, 'MON':'SUN'].tolist(), allocation=df.loc[row_name, '00:00':'23:30'].tolist() )
[docs] class ResourceInfo(pyd.BaseModel): """Contains information about a resource.""" name: str """The name of the resource, e.g. "Scanning machine".""" type: ty.Literal['staff', 'machine'] """Whether the resource is a staff or machine resource.""" schedule: ResourceSchedule """A schedule defining the number of allocated resource units over the course of a week."""
[docs] class ResourcesInfo(pyd.BaseModel): """Dataclass for tracking the staff resources of a model. The fields in this dataclass **MUST** match the rows of the configuration Excel template ("Resources" tab), with all letters to lowercase, spaces to underscores, and other characters removed.""" booking_in_staff: ResourceInfo =\ pyd.Field(title='Booking-in staff', json_schema_extra={'resource_type': 'staff'}) bms: ResourceInfo =\ pyd.Field(title='BMS', json_schema_extra={'resource_type': 'staff'}) cut_up_assistant: ResourceInfo =\ pyd.Field(title='Cut-up assistant', json_schema_extra={'resource_type': 'staff'}) processing_room_staff: ResourceInfo =\ pyd.Field(title='Processing room staff', json_schema_extra={'resource_type': 'staff'}) microtomy_staff: ResourceInfo =\ pyd.Field(title='Microtomy staff', json_schema_extra={'resource_type': 'staff'}) staining_staff: ResourceInfo =\ pyd.Field(title='Staining staff', json_schema_extra={'resource_type': 'staff'}) scanning_staff: ResourceInfo =\ pyd.Field(title='Scanning staff', json_schema_extra={'resource_type': 'staff'}) qc_staff: ResourceInfo =\ pyd.Field(title='QC staff', json_schema_extra={'resource_type': 'staff'}) histopathologist: ResourceInfo =\ pyd.Field(title='Histopathologist', json_schema_extra={'resource_type': 'staff'}) bone_station: ResourceInfo =\ pyd.Field(title='Bone station', json_schema_extra={'resource_type': 'machine'}) processing_machine: ResourceInfo =\ pyd.Field(title='Processing machine', json_schema_extra={'resource_type': 'machine'}) staining_machine: ResourceInfo =\ pyd.Field(title='Staining machine', json_schema_extra={'resource_type': 'machine'}) coverslip_machine: ResourceInfo =\ pyd.Field(title='Coverslip machine', json_schema_extra={'resource_type': 'machine'}) scanning_machine_regular: ResourceInfo = pyd.Field( title='Scanning machine (regular)', json_schema_extra={'resource_type': 'machine'}) scanning_machine_megas: ResourceInfo = pyd.Field( title='Scanning machine (megas)', json_schema_extra={'resource_type': 'machine'})
[docs] @staticmethod def from_workbook(wbook: Workbook) -> 'ResourcesInfo': """Construct a dataclass instance from an Excel workbook. Args: wbook: The Excel workbook to parse. Returns: The parsed dataclass instance. """ resources_df = ( pd.DataFrame( ( table := excel.get_table(wbook, 'Resource Allocation', 'Resources') )[1:], columns=table[0] ) .fillna(0.) .set_index('Resource') ) return ResourcesInfo.model_validate({ key: ResourceInfo( name=field.title, type=field.json_schema_extra['resource_type'], schedule=ResourceSchedule.from_pd(resources_df, row_name=field.title) ) for key, field in ResourcesInfo.model_fields.items() })