Spaces:
Running
Running
| """ | |
| Substrate settings for force map prediction. | |
| Loads from config/substrate_settings.json - users can edit this file to add/modify substrates. | |
| """ | |
| import os | |
| import json | |
| def _default_config_path(): | |
| """Default path to substrate settings config (S2F/config/substrate_settings.json).""" | |
| this_dir = os.path.dirname(os.path.abspath(__file__)) | |
| project_root = os.path.dirname(this_dir) # S2F root | |
| return os.path.join(project_root, 'config', 'substrate_settings.json') | |
| def load_substrate_config(config_path=None): | |
| """ | |
| Load substrate settings from config file. | |
| Args: | |
| config_path: Path to JSON config. If None, uses config/substrate_settings.json in S2F root. | |
| Returns: | |
| dict: Config with 'substrates', 'default_substrate' | |
| """ | |
| path = config_path or _default_config_path() | |
| if not os.path.exists(path): | |
| raise FileNotFoundError( | |
| f"Substrate config not found at {path}. " | |
| "Create config/substrate_settings.json or pass config_path." | |
| ) | |
| with open(path, 'r') as f: | |
| return json.load(f) | |
| def resolve_substrate(name, config=None, config_path=None): | |
| """ | |
| Resolve substrate name to a canonical substrate key. | |
| Args: | |
| name: Substrate key (e.g. 'fibroblasts_PDMS', 'PDMS_10kPa') | |
| config: Pre-loaded config dict. If None, loads from config_path. | |
| config_path: Path to config file (used if config is None). | |
| Returns: | |
| str: Canonical substrate key | |
| """ | |
| if config is None: | |
| config = load_substrate_config(config_path) | |
| s = (name or '').strip() | |
| if not s: | |
| return config.get('default_substrate', 'fibroblasts_PDMS') | |
| substrates = config.get('substrates', {}) | |
| s_lower = s.lower() | |
| for key in substrates: | |
| if key.lower() == s_lower: | |
| return key | |
| for key in substrates: | |
| if s_lower.startswith(key.lower()) or key.lower().startswith(s_lower): | |
| return key | |
| return config.get('default_substrate', 'fibroblasts_PDMS') | |
| def get_settings_of_category(substrate_name, config=None, config_path=None): | |
| """ | |
| Get pixelsize and young's modulus for a substrate. | |
| Args: | |
| substrate_name: Substrate or folder name (case-insensitive) | |
| config: Pre-loaded config dict. If None, loads from config_path. | |
| config_path: Path to config file (used if config is None). | |
| Returns: | |
| dict: {'name': str, 'pixelsize': float, 'young': float} | |
| """ | |
| if config is None: | |
| config = load_substrate_config(config_path) | |
| substrate_key = resolve_substrate(substrate_name, config=config) | |
| substrates = config.get('substrates', {}) | |
| default = config.get('default_substrate', 'fibroblasts_PDMS') | |
| if substrate_key in substrates: | |
| return substrates[substrate_key].copy() | |
| default_settings = substrates.get(default, {'name': 'Fibroblasts on PDMS', 'pixelsize': 3.0769, 'young': 6000}) | |
| return default_settings.copy() | |
| def list_substrates(config=None, config_path=None): | |
| """ | |
| Return list of available substrate keys for user selection. | |
| Returns: | |
| list: Substrate keys | |
| """ | |
| if config is None: | |
| config = load_substrate_config(config_path) | |
| return list(config.get('substrates', {}).keys()) | |
| def compute_settings_normalization(config=None, config_path=None): | |
| """ | |
| Compute min-max normalization parameters from all substrates in config. | |
| Returns: | |
| dict: {'pixelsize': {'min', 'max'}, 'young': {'min', 'max'}} | |
| """ | |
| if config is None: | |
| config = load_substrate_config(config_path) | |
| substrates = config.get('substrates', {}) | |
| all_pixelsizes = [s['pixelsize'] for s in substrates.values()] | |
| all_youngs = [s['young'] for s in substrates.values()] | |
| if not all_pixelsizes or not all_youngs: | |
| pixelsize_min, pixelsize_max = 3.0769, 9.8138 | |
| young_min, young_max = 1000.0, 10000.0 | |
| else: | |
| pixelsize_min, pixelsize_max = min(all_pixelsizes), max(all_pixelsizes) | |
| young_min, young_max = min(all_youngs), max(all_youngs) | |
| return { | |
| 'pixelsize': {'min': pixelsize_min, 'max': pixelsize_max}, | |
| 'young': {'min': young_min, 'max': young_max} | |
| } | |