"""Input validation and position constraint building.""" import pandas as pd def _validate_design_inputs(pdb_files: list | None, ensemble_mode: str) -> str | None: if not pdb_files: return "Upload at least one PDB or CIF file." if ensemble_mode == "user" and len(pdb_files) < 2: return "User ensemble mode requires at least two files." single_file_mode_messages = { "none": "Single structure mode requires exactly one file.", "synthetic": "Protpardelle mode requires exactly one file.", } message = single_file_mode_messages.get(ensemble_mode) if message and len(pdb_files) != 1: return message return None def _build_pos_constraint_df( pdb_key: str, fixed_pos_seq: str, fixed_pos_scn: str, fixed_pos_override_seq: str, pos_restrict_aatype: str, symmetry_pos: str, ) -> pd.DataFrame | None: row = {} if fixed_pos_seq and fixed_pos_seq.strip(): row["fixed_pos_seq"] = fixed_pos_seq.strip() if fixed_pos_scn and fixed_pos_scn.strip(): row["fixed_pos_scn"] = fixed_pos_scn.strip() if fixed_pos_override_seq and fixed_pos_override_seq.strip(): row["fixed_pos_override_seq"] = fixed_pos_override_seq.strip() if pos_restrict_aatype and pos_restrict_aatype.strip(): row["pos_restrict_aatype"] = pos_restrict_aatype.strip() if symmetry_pos and symmetry_pos.strip(): row["symmetry_pos"] = symmetry_pos.strip() if not row: return None row["pdb_key"] = pdb_key return pd.DataFrame([row])