Spaces:
Running
Running
File size: 4,205 Bytes
6cbe52d | 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 | """
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}
}
|