Spaces:
Runtime error
Runtime error
Download src/streamlit_app.py from MuhammadNabeelSh/StatisticalControl: direct link, hf CLI and curl.
- Browser
- Download file 12.3 kB
-
https://huggingface.co/spaces/MuhammadNabeelSh/StatisticalControl/resolve/main/src/streamlit_app.py
- Command line
-
hf download hf://spaces/MuhammadNabeelSh/StatisticalControl/src/streamlit_app.py
-
curl -L -o streamlit_app.py https://huggingface.co/spaces/MuhammadNabeelSh/StatisticalControl/resolve/main/src/streamlit_app.py
12.3 kB
| import streamlit as st | |
| import plotly.graph_objects as go | |
| import numpy as np | |
| import pandas as pd | |
| # ============================================================================= | |
| # 1. CONFIGURATION & DATA | |
| # ============================================================================= | |
| st.set_page_config( | |
| page_title="Biomaterials Stress-Strain Explorer", | |
| page_icon="🦷", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Material Database: Dental & Biomaterials | |
| MATERIALS = { | |
| "🦷 Dental Amalgam": { | |
| "E": 80000, "yield": 200, "uts": 260, "strain": 0.006, "type": "brittle", | |
| "desc": "Traditional restorative alloy. High stiffness, low ductility.", | |
| "color": "#4A90D9" | |
| }, | |
| "🦷 Composite Resin": { | |
| "E": 12000, "yield": 90, "uts": 120, "strain": 0.035, "type": "semi-ductile", | |
| "desc": "Tooth-colored restorative. Moderate stiffness and ductility.", | |
| "color": "#E8A838" | |
| }, | |
| "🦷 Zirconia (Y-TZP)": { | |
| "E": 200000, "yield": 900, "uts": 1100, "strain": 0.003, "type": "brittle", | |
| "desc": "High-strength ceramic. Extremely stiff, very brittle failure.", | |
| "color": "#9B59B6" | |
| }, | |
| "🦷 Gold Alloy (Type IV)": { | |
| "E": 85000, "yield": 350, "uts": 500, "strain": 0.12, "type": "ductile", | |
| "desc": "Cast noble metal. Excellent ductility and fatigue resistance.", | |
| "color": "#F39C12" | |
| }, | |
| "🦷 Titanium (Grade 5)": { | |
| "E": 110000, "yield": 850, "uts": 950, "strain": 0.10, "type": "ductile", | |
| "desc": "Ti-6Al-4V alloy. Standard for implants. High strength-to-weight.", | |
| "color": "#3498DB" | |
| }, | |
| "🦷 Glass Ionomer": { | |
| "E": 8000, "yield": 40, "uts": 55, "strain": 0.008, "type": "brittle", | |
| "desc": "Adhesive cement. Low strength, fluoride release.", | |
| "color": "#1ABC9C" | |
| }, | |
| "🦴 Cortical Bone": { | |
| "E": 17000, "yield": 120, "uts": 150, "strain": 0.018, "type": "semi-ductile", | |
| "desc": "Dense outer bone. Anisotropic, moderate stiffness.", | |
| "color": "#ECF0F1" | |
| }, | |
| "🧬 PEEK": { | |
| "E": 3600, "yield": 95, "uts": 100, "strain": 0.06, "type": "ductile", | |
| "desc": "Polyetheretherketone. Used in spinal implants. Low modulus matches bone.", | |
| "color": "#E74C3C" | |
| }, | |
| "🧬 UHMWPE": { | |
| "E": 800, "yield": 20, "uts": 30, "strain": 0.35, "type": "ductile", | |
| "desc": "Ultra-high molecular weight polyethylene. Joint bearing surface.", | |
| "color": "#F1C40F" | |
| }, | |
| "⚙️ Stainless Steel 316L": { | |
| "E": 193000, "yield": 205, "uts": 505, "strain": 0.40, "type": "ductile", | |
| "desc": "Austenitic steel. Surgical instruments and temporary implants.", | |
| "color": "#7F8C8D" | |
| } | |
| } | |
| # ============================================================================= | |
| # 2. PHYSICS ENGINE (Curve Generation) | |
| # ============================================================================= | |
| def generate_stress_strain(E, sigma_y, sigma_uts, epsilon_break, material_type): | |
| """ | |
| Generates a realistic stress-strain curve using a piecewise model. | |
| 1. Elastic: Linear (Hooke's Law) | |
| 2. Plastic: Cosine transition to UTS | |
| 3. Necking: Power-law decay to fracture | |
| """ | |
| # Calculate yield strain | |
| epsilon_y = sigma_y / E | |
| # Determine strain at UTS based on material type | |
| if material_type == "brittle": | |
| epsilon_uts = epsilon_y * 1.1 | |
| elif material_type == "semi-ductile": | |
| epsilon_uts = epsilon_y + (epsilon_break - epsilon_y) * 0.5 | |
| else: # ductile | |
| epsilon_uts = epsilon_y + (epsilon_break - epsilon_y) * 0.4 | |
| # Generate strain points | |
| n_points = 1000 | |
| epsilon = np.linspace(0, epsilon_break, n_points) | |
| sigma = np.zeros_like(epsilon) | |
| for i, eps in enumerate(epsilon): | |
| if eps <= epsilon_y: | |
| # Elastic Region | |
| sigma[i] = E * eps | |
| elif eps <= epsilon_uts: | |
| # Strain Hardening Region (Smooth transition) | |
| # Normalize position between yield and UTS | |
| t = (eps - epsilon_y) / (epsilon_uts - epsilon_y) | |
| # Use cosine for smooth hardening | |
| sigma[i] = sigma_y + (sigma_uts - sigma_y) * (0.5 * (1 - np.cos(np.pi * t))) | |
| else: | |
| # Necking / Softening Region | |
| t = (eps - epsilon_uts) / (epsilon_break - epsilon_uts) | |
| # Stress drops from UTS to near 0 | |
| sigma[i] = sigma_uts * (1 - 0.95 * (t ** 0.7)) | |
| return epsilon, np.maximum(sigma, 0) | |
| # ============================================================================= | |
| # 3. ACCESSIBILITY HELPERS | |
| # ============================================================================= | |
| def inject_accessibility_css(): | |
| """Injects CSS for high contrast and large text modes.""" | |
| st.markdown(""" | |
| <style> | |
| /* High Contrast Mode */ | |
| .high-contrast .st-emotion-cache-1lcbcih { | |
| background-color: #000000 !important; | |
| color: #FFFFFF !important; | |
| } | |
| .high-contrast .st-emotion-cache-18ni7ap { | |
| background-color: #000000 !important; | |
| color: #00FF00 !important; | |
| border: 2px solid #00FF00; | |
| } | |
| .high-contrast .st-emotion-cache-1v0mb8g { | |
| color: #FFFF00 !important; | |
| } | |
| /* Large Text Mode */ | |
| .large-text .st-emotion-cache-1lcbcih { | |
| font-size: 1.5em !important; | |
| } | |
| .large-text .st-emotion-cache-18ni7ap { | |
| font-size: 1.5em !important; | |
| } | |
| .large-text .st-emotion-cache-1v0mb8g { | |
| font-size: 1.5em !important; | |
| } | |
| /* Screen Reader Only Text */ | |
| .sr-only { | |
| position: absolute; | |
| width: 1px; | |
| height: 1px; | |
| padding: 0; | |
| margin: -1px; | |
| overflow: hidden; | |
| clip: rect(0, 0, 0, 0); | |
| white-space: nowrap; | |
| border: 0; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # ============================================================================= | |
| # 4. MAIN APP LOGIC | |
| # ============================================================================= | |
| def main(): | |
| inject_accessibility_css() | |
| # --- Sidebar: Controls & Accessibility --- | |
| with st.sidebar: | |
| st.header("⚙️ Controls") | |
| # Material Selection | |
| selected_material = st.selectbox( | |
| "Select Material Preset", | |
| options=list(MATERIALS.keys()), | |
| index=0 | |
| ) | |
| st.markdown("---") | |
| st.header("📊 Parameters") | |
| # Get current preset values | |
| preset = MATERIALS[selected_material] | |
| # Widgets | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| E = st.slider("Young's Modulus (MPa)", 100, 300000, int(preset["E"]), 100) | |
| sigma_y = st.slider("Yield Strength (MPa)", 10, 1500, int(preset["yield"]), 10) | |
| with col2: | |
| sigma_uts = st.slider("UTS (MPa)", 10, 1500, int(preset["uts"]), 10) | |
| epsilon_break = st.slider("Strain at Break", 0.001, 0.50, float(preset["strain"]), 0.001) | |
| st.markdown("---") | |
| st.header("♿ Accessibility") | |
| # Accessibility Toggles | |
| high_contrast = st.toggle("High Contrast Mode", value=False) | |
| large_text = st.toggle("Large Text Mode", value=False) | |
| screen_reader_mode = st.toggle("Verbose Descriptions", value=False) | |
| # Apply CSS classes based on toggles | |
| css_classes = [] | |
| if high_contrast: css_classes.append("high-contrast") | |
| if large_text: css_classes.append("large-text") | |
| if css_classes: | |
| st.markdown(f'<div class="{" ".join(css_classes)}">', unsafe_allow_html=True) | |
| # --- Main Content --- | |
| # Title | |
| st.title("Biomaterials Stress-Strain Explorer") | |
| # Description Area | |
| st.subheader(f"Material: {selected_material}") | |
| st.info(preset["desc"]) | |
| # Screen Reader Description (Hidden visually but readable) | |
| if screen_reader_mode: | |
| st.markdown(f""" | |
| <p class="sr-only"> | |
| Chart displays stress-strain curve for {selected_material}. | |
| Young's Modulus is {E} MPa. | |
| Yield Strength is {sigma_y} MPa. | |
| Ultimate Tensile Strength is {sigma_uts} MPa. | |
| Fracture occurs at strain {epsilon_break}. | |
| </p> | |
| """, unsafe_allow_html=True) | |
| # --- Calculation --- | |
| strain, stress = generate_stress_strain(E, sigma_y, sigma_uts, epsilon_break, preset["type"]) | |
| # --- Plotly Chart --- | |
| fig = go.Figure() | |
| # 1. The Stress-Strain Curve | |
| fig.add_trace(go.Scatter( | |
| x=strain, | |
| y=stress, | |
| mode='lines', | |
| name='Stress-Strain', | |
| line=dict(color=preset["color"], width=4), | |
| hovertemplate="Strain: %{x:.3f}<br>Stress: %{y:.1f} MPa<extra></extra>" | |
| )) | |
| # 2. Elastic Modulus Line (Dashed, up to yield) | |
| epsilon_y = sigma_y / E | |
| fig.add_trace(go.Scatter( | |
| x=[0, epsilon_y], | |
| y=[0, sigma_y], | |
| mode='lines', | |
| name='Elastic Modulus', | |
| line=dict(color='red', width=2, dash='dash'), | |
| hoverinfo="skip" | |
| )) | |
| # 3. Annotations for Key Points | |
| annotations = [] | |
| # Yield Point | |
| annotations.append(dict( | |
| x=epsilon_y, y=sigma_y, | |
| xref="x", yref="y", | |
| text=f"Yield Point<br>σ={sigma_y} MPa", | |
| showarrow=True, arrowhead=2, arrowsize=1, arrowwidth=2, arrowcolor="orange", | |
| bordercolor="orange", borderwidth=1, borderpad=4, bgcolor="white", | |
| font=dict(family="Arial", size=12, color="orange") | |
| )) | |
| # UTS Point | |
| # Find index closest to UTS for accurate annotation placement | |
| uts_idx = np.argmax(stress) | |
| uts_strain = strain[uts_idx] | |
| annotations.append(dict( | |
| x=uts_strain, y=sigma_uts, | |
| xref="x", yref="y", | |
| text=f"UTS<br>σ={sigma_uts} MPa", | |
| showarrow=True, arrowhead=2, arrowsize=1, arrowwidth=2, arrowcolor="purple", | |
| bordercolor="purple", borderwidth=1, borderpad=4, bgcolor="white", | |
| font=dict(family="Arial", size=12, color="purple") | |
| )) | |
| # Fracture Point | |
| annotations.append(dict( | |
| x=epsilon_break, y=0, | |
| xref="x", yref="y", | |
| text=f"Fracture<br>ε={epsilon_break}", | |
| showarrow=True, arrowhead=2, arrowsize=1, arrowwidth=2, arrowcolor="black", | |
| bordercolor="black", borderwidth=1, borderpad=4, bgcolor="white", | |
| font=dict(family="Arial", size=12, color="black") | |
| )) | |
| fig.update_layout( | |
| annotations=annotations, | |
| xaxis_title="Strain (ε) - Dimensionless", | |
| yaxis_title="Stress (σ) - MPa", | |
| title="Stress-Strain Curve", | |
| template="plotly_white" if not high_contrast else "plotly_dark", | |
| hovermode="x unified", | |
| legend=dict(x=0.01, y=0.99, bgcolor="rgba(255,255,255,0.8)"), | |
| margin=dict(l=50, r=50, t=50, b=50) | |
| ) | |
| # Accessibility: If high contrast, force dark background on plot | |
| if high_contrast: | |
| fig.update_layout(paper_bgcolor="black", plot_bgcolor="black") | |
| fig.update_xaxes(gridcolor="gray", zerolinecolor="white", tickfont=dict(color="white")) | |
| fig.update_yaxes(gridcolor="gray", zerolinecolor="white", tickfont=dict(color="white")) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # --- Data Table (For Accessibility/Reference) --- | |
| st.subheader("📋 Key Mechanical Properties") | |
| df_props = pd.DataFrame({ | |
| "Property": ["Young's Modulus", "Yield Strength", "Ultimate Tensile Strength", "Strain at Break", "Yield Strain", "Toughness (Approx)"], | |
| "Value": [ | |
| f"{E} MPa", | |
| f"{sigma_y} MPa", | |
| f"{sigma_uts} MPa", | |
| f"{epsilon_break}", | |
| f"{epsilon_y:.4f}", | |
| f"{np.trapezoid(stress, strain):.1f} MJ/m³" | |
| ], | |
| "Description": [ | |
| "Stiffness in elastic region", | |
| "Onset of plastic deformation", | |
| "Maximum stress before necking", | |
| "Strain at fracture", | |
| "Calculated as σ_y / E", | |
| "Area under curve (Energy absorbed)" | |
| ] | |
| }) | |
| st.dataframe(df_props, use_container_width=True, hide_index=True) | |
| # Close the div if we opened it for CSS classes | |
| if css_classes: | |
| st.markdown("</div>", unsafe_allow_html=True) | |
| if __name__ == "__main__": | |
| main() | |