Spaces:
Sleeping
Sleeping
File size: 7,897 Bytes
8e9b78d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# src/models.py
import numpy as np
import pandas as pd
from typing import List, Dict
import logging
from src.utils.logger import setup_logger
logger = setup_logger(__name__)
class TrafficData:
def __init__(self, axle_loads: List[float], traffic_growth_rate: float, analysis_period: int):
"""
Initialize TrafficData with axle loads, growth rate, and analysis period.
:param axle_loads: List of axle loads in kN.
:param traffic_growth_rate: Annual traffic growth rate (decimal, e.g., 0.02 for 2%).
:param analysis_period: Number of years for analysis.
"""
self.axle_loads = axle_loads
self.traffic_growth_rate = traffic_growth_rate
self.analysis_period = analysis_period
def get_total_axle_loads(self) -> List[List[float]]:
"""
Project total axle loads over the analysis period considering growth rate.
:return: A list of lists, each sublist represents axle loads for a year.
"""
total_loads = []
for year in range(self.analysis_period):
growth_factor = (1 + self.traffic_growth_rate) ** year
projected_loads = [load * growth_factor for load in self.axle_loads]
total_loads.append(projected_loads)
logger.debug(f"Year {year + 1}: {projected_loads}")
return total_loads
@staticmethod
def from_dataframe(df: pd.DataFrame) -> 'TrafficData':
"""
Create TrafficData instance from a pandas DataFrame.
:param df: DataFrame with columns 'Axle_Loads', 'Traffic_Growth_Rate', 'Analysis_Period'.
:return: TrafficData instance.
"""
try:
axle_loads = df['Axle_Loads'].dropna().tolist()
traffic_growth_rate = float(df['Traffic_Growth_Rate'].iloc[0])
analysis_period = int(df['Analysis_Period'].iloc[0])
logger.info("TrafficData loaded successfully from DataFrame.")
return TrafficData(axle_loads, traffic_growth_rate, analysis_period)
except Exception as e:
logger.error(f"Error creating TrafficData from DataFrame: {e}")
raise ValueError(f"Invalid Traffic Data: {e}")
class ClimateData:
def __init__(self, average_temperature: float, temperature_variation: float, rainfall: float):
"""
Initialize ClimateData with average temperature, temperature variation, and rainfall.
:param average_temperature: Average temperature in °C.
:param temperature_variation: Temperature variation in °C.
:param rainfall: Annual rainfall in mm.
"""
self.average_temperature = average_temperature
self.temperature_variation = temperature_variation
self.rainfall = rainfall
@staticmethod
def from_dataframe(df: pd.DataFrame) -> 'ClimateData':
"""
Create ClimateData instance from a pandas DataFrame.
:param df: DataFrame with columns 'Average_Temperature', 'Temperature_Variation', 'Rainfall'.
:return: ClimateData instance.
"""
try:
average_temperature = float(df['Average_Temperature'].iloc[0])
temperature_variation = float(df['Temperature_Variation'].iloc[0])
rainfall = float(df['Rainfall'].iloc[0])
logger.info("ClimateData loaded successfully from DataFrame.")
return ClimateData(average_temperature, temperature_variation, rainfall)
except Exception as e:
logger.error(f"Error creating ClimateData from DataFrame: {e}")
raise ValueError(f"Invalid Climate Data: {e}")
class SubgradeProperties:
def __init__(self, modulus: float, CBR: float):
"""
Initialize SubgradeProperties with modulus and California Bearing Ratio (CBR).
:param modulus: Modulus of subgrade reaction in kPa/m.
:param CBR: California Bearing Ratio in %.
"""
self.modulus = modulus
self.CBR = CBR
@staticmethod
def from_dataframe(df: pd.DataFrame) -> 'SubgradeProperties':
"""
Create SubgradeProperties instance from a pandas DataFrame.
:param df: DataFrame with columns 'Modulus', 'CBR'.
:return: SubgradeProperties instance.
"""
try:
modulus = float(df['Modulus'].iloc[0])
CBR = float(df['CBR'].iloc[0])
logger.info("SubgradeProperties loaded successfully from DataFrame.")
return SubgradeProperties(modulus, CBR)
except Exception as e:
logger.error(f"Error creating SubgradeProperties from DataFrame: {e}")
raise ValueError(f"Invalid Subgrade Properties Data: {e}")
class MaterialProperties:
def __init__(self, asphalt_modulus: float, concrete_strength: float, thermal_coeff: float):
"""
Initialize MaterialProperties with asphalt modulus, concrete strength, and thermal coefficient.
:param asphalt_modulus: Asphalt modulus in MPa.
:param concrete_strength: Concrete strength in MPa.
:param thermal_coeff: Thermal coefficient (°C^-1).
"""
self.asphalt_modulus = asphalt_modulus
self.concrete_strength = concrete_strength
self.thermal_coeff = thermal_coeff
@staticmethod
def from_dataframe(df: pd.DataFrame) -> 'MaterialProperties':
"""
Create MaterialProperties instance from a pandas DataFrame.
:param df: DataFrame with columns 'Asphalt_Modulus', 'Concrete_Strength', 'Thermal_Coeff'.
:return: MaterialProperties instance.
"""
try:
asphalt_modulus = float(df['Asphalt_Modulus'].iloc[0])
concrete_strength = float(df['Concrete_Strength'].iloc[0])
thermal_coeff = float(df['Thermal_Coeff'].iloc[0])
logger.info("MaterialProperties loaded successfully from DataFrame.")
return MaterialProperties(asphalt_modulus, concrete_strength, thermal_coeff)
except Exception as e:
logger.error(f"Error creating MaterialProperties from DataFrame: {e}")
raise ValueError(f"Invalid Material Properties Data: {e}")
class Pavement:
def __init__(self, layers: List[float], pavement_type: str = 'Flexible'):
"""
Initialize Pavement structure.
:param layers: List of layer thicknesses in mm.
:param pavement_type: Type of pavement ('Flexible', 'Rigid', 'Composite').
"""
self.layers = layers
self.pavement_type = pavement_type
def add_layer(self, thickness: float):
"""
Add a new layer to the pavement structure.
:param thickness: Thickness of the new layer in mm.
"""
self.layers.append(thickness)
logger.debug(f"Added layer: {thickness} mm. Total layers: {self.layers}")
def remove_layer(self, index: int):
"""
Remove a layer from the pavement structure by index.
:param index: Index of the layer to remove.
"""
if 0 <= index < len(self.layers):
removed = self.layers.pop(index)
logger.debug(f"Removed layer at index {index}: {removed} mm. Remaining layers: {self.layers}")
else:
logger.warning(f"Attempted to remove non-existent layer at index {index}.")
def set_pavement_type(self, pavement_type: str):
"""
Set the type of pavement.
:param pavement_type: Type of pavement ('Flexible', 'Rigid', 'Composite').
"""
if pavement_type in ['Flexible', 'Rigid', 'Composite']:
self.pavement_type = pavement_type
logger.debug(f"Pavement type set to {pavement_type}.")
else:
logger.error(f"Invalid pavement type: {pavement_type}. Must be 'Flexible', 'Rigid', or 'Composite'.")
raise ValueError("Invalid pavement type. Choose from 'Flexible', 'Rigid', or 'Composite'.")
|