| """ |
| 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) |
| 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} |
| } |
|
|