Spaces:
Sleeping
Sleeping
| """ | |
| ================================================================= | |
| RESPONSE ENGINE β The Brain of DermaScan-AI | |
| ================================================================= | |
| Takes model prediction β generates complete clinical response: | |
| - Diagnosis with confidence | |
| - Severity tier (CANCER / PRE-CANCER / BENIGN / DISEASE) | |
| - Care advice | |
| - Hospital recommendation | |
| - Urgency level | |
| ================================================================= | |
| """ | |
| import json | |
| from pathlib import Path | |
| from typing import Dict, Any, Optional | |
| import numpy as np | |
| class ResponseEngine: | |
| """ | |
| Generates structured clinical responses based on model predictions. | |
| """ | |
| def __init__( | |
| self, | |
| class_config_path: str = "configs/class_config.json", | |
| response_templates_path: str = "configs/response_templates.json", | |
| ): | |
| # Load class config | |
| with open(class_config_path, 'r') as f: | |
| self.class_config = json.load(f) | |
| # Load response templates | |
| with open(response_templates_path, 'r') as f: | |
| self.templates = json.load(f) | |
| self.num_classes = len(self.class_config) | |
| self.class_names = [self.class_config[str(i)]['name'] for i in range(self.num_classes)] | |
| self.class_tiers = [self.class_config[str(i)]['tier'] for i in range(self.num_classes)] | |
| # Confidence thresholds | |
| self.HIGH_CONFIDENCE = 0.7 | |
| self.MEDIUM_CONFIDENCE = 0.4 | |
| self.LOW_CONFIDENCE = 0.2 | |
| def generate_response( | |
| self, | |
| predicted_class: int, | |
| confidence: float, | |
| all_probabilities: np.ndarray, | |
| ) -> Dict[str, Any]: | |
| """ | |
| Generate a complete response for a prediction. | |
| Args: | |
| predicted_class: Index of predicted class | |
| confidence: Confidence of top prediction (0-1) | |
| all_probabilities: Array of probabilities for all 13 classes | |
| Returns: | |
| Complete response dictionary | |
| """ | |
| class_name = self.class_names[predicted_class] | |
| template = self.templates.get(class_name, {}) | |
| class_info = self.class_config[str(predicted_class)] | |
| # ββ Confidence assessment ββ | |
| if confidence >= self.HIGH_CONFIDENCE: | |
| confidence_level = "HIGH" | |
| confidence_message = "The AI model has high confidence in this assessment." | |
| elif confidence >= self.MEDIUM_CONFIDENCE: | |
| confidence_level = "MEDIUM" | |
| confidence_message = "The AI model has moderate confidence. Consider getting a professional opinion." | |
| else: | |
| confidence_level = "LOW" | |
| confidence_message = "The AI model has low confidence. This result should be verified by a medical professional." | |
| # ββ Check for close second prediction ββ | |
| sorted_indices = np.argsort(all_probabilities)[::-1] | |
| second_class = sorted_indices[1] | |
| second_prob = all_probabilities[second_class] | |
| second_name = self.class_names[second_class] | |
| close_call = (confidence - second_prob) < 0.15 | |
| # ββ Build differential diagnosis ββ | |
| differential = [] | |
| for idx in sorted_indices[:3]: | |
| if all_probabilities[idx] > 0.05: | |
| differential.append({ | |
| "class_name": self.class_names[idx], | |
| "probability": round(float(all_probabilities[idx]), 4), | |
| "tier": self.class_tiers[idx], | |
| }) | |
| # ββ Is any cancer class in top 3? ββ | |
| cancer_alert = False | |
| cancer_in_top3 = [] | |
| for d in differential: | |
| if d['tier'] in ['CANCER', 'PRE-CANCER']: | |
| cancer_in_top3.append(d) | |
| if d['probability'] > 0.1: | |
| cancer_alert = True | |
| # ββ Build response ββ | |
| response = { | |
| # Core prediction | |
| "predicted_class": class_name, | |
| "predicted_class_idx": int(predicted_class), | |
| "confidence": round(float(confidence), 4), | |
| "confidence_level": confidence_level, | |
| "confidence_message": confidence_message, | |
| # Classification | |
| "tier": class_info['tier'], | |
| "severity": template.get('severity', class_info['severity']), | |
| "emoji": template.get('emoji', 'β'), | |
| "tagline": template.get('tagline', f'{class_name} Detected'), | |
| # Action | |
| "action": template.get('action', 'CONSULT A DOCTOR'), | |
| "urgency_message": template.get('urgency_message', ''), | |
| "description": template.get('description', ''), | |
| # Care advice | |
| "care_advice": template.get('care_advice', []), | |
| "risk_factors": template.get('risk_factors', []), | |
| # Hospital | |
| "hospital_search_query": template.get('hospital_search_query', 'dermatologist near me'), | |
| "hospital_type": template.get('hospital_type', 'Dermatology Clinic'), | |
| # Differential diagnosis | |
| "differential_diagnosis": differential, | |
| "close_call": close_call, | |
| # Cancer alert | |
| "cancer_alert": cancer_alert, | |
| "cancer_in_differential": cancer_in_top3, | |
| # All probabilities (for chart) | |
| "all_probabilities": { | |
| self.class_names[i]: round(float(all_probabilities[i]), 4) | |
| for i in range(self.num_classes) | |
| }, | |
| # Disclaimer | |
| "disclaimer": ( | |
| "β οΈ IMPORTANT: This is an AI-assisted analysis tool for educational purposes only. " | |
| "It is NOT a substitute for professional medical diagnosis. The accuracy of AI predictions " | |
| "can vary. Always consult a qualified dermatologist or healthcare professional for " | |
| "proper diagnosis and treatment. If you notice any suspicious changes in your skin, " | |
| "please seek medical attention promptly." | |
| ), | |
| } | |
| # ββ Override: If cancer probability is high, ALWAYS warn ββ | |
| if cancer_alert and class_info['tier'] not in ['CANCER', 'PRE-CANCER']: | |
| highest_cancer = max(cancer_in_top3, key=lambda x: x['probability']) | |
| response['cancer_warning'] = ( | |
| f"β οΈ Note: While the top prediction is {class_name}, " | |
| f"the model also detected a {highest_cancer['probability']:.0%} probability of " | |
| f"{highest_cancer['class_name']} ({highest_cancer['tier']}). " | |
| f"We strongly recommend consulting a dermatologist to rule out any malignancy." | |
| ) | |
| return response | |
| def get_severity_color(self, severity: str) -> str: | |
| """Return color hex code for severity level.""" | |
| colors = { | |
| "CRITICAL": "#e74c3c", | |
| "HIGH": "#e67e22", | |
| "MEDIUM": "#f39c12", | |
| "LOW": "#27ae60", | |
| } | |
| return colors.get(severity, "#95a5a6") | |
| def get_tier_color(self, tier: str) -> str: | |
| """Return color hex code for tier.""" | |
| colors = { | |
| "CANCER": "#e74c3c", | |
| "PRE-CANCER": "#f39c12", | |
| "BENIGN": "#27ae60", | |
| "DISEASE": "#3498db", | |
| } | |
| return colors.get(tier, "#95a5a6") |