"""Shared CLI helpers for calibration scripts.""" from __future__ import annotations import argparse from pathlib import Path from typing import Dict, Optional, Tuple import config def parse_chessboard_size(value: str) -> Tuple[int, int]: parts = value.split(",") if len(parts) != 2: raise argparse.ArgumentTypeError( "chessboard size must be width,height (e.g. 8,7)" ) return tuple(map(int, parts)) def add_session_args(parser: argparse.ArgumentParser) -> None: parser.add_argument("--project", required=True, help="Project name (e.g. Olsen_wings)") parser.add_argument("--date", required=True, help="Date string (e.g. 2026-05-12)") parser.add_argument( "--calib_name", default="calib1", help="Calibration folder name (default: calib1)" ) def add_board_args(parser: argparse.ArgumentParser) -> None: parser.add_argument( "--chessboard_size", type=parse_chessboard_size, default="8,7", help="Default inner corner grid width,height", ) parser.add_argument( "--square_size", type=float, default=0.045, help="Default chessboard square size in metres", ) parser.add_argument("--left_chessboard_size", type=parse_chessboard_size, default=None) parser.add_argument("--right_chessboard_size", type=parse_chessboard_size, default=None) parser.add_argument("--left_square_size", type=float, default=None) parser.add_argument("--right_square_size", type=float, default=None) parser.add_argument( "--preprocessing", type=str, default="None", help="Pre-detection chain: G=gray, C=CLAHE, T=threshold (e.g. C, GC)", ) def add_troubleshooting_arg(parser: argparse.ArgumentParser) -> None: parser.add_argument( "--troubleshooting", action="store_true", help=( "Verbose logs and intermediate debug files (corners/, pairing_reports/, " "rectified/). Default: minimal logs; step 2 writes only params/" ), ) def resolve_input_path(args) -> Path: return config.CALIB_DATA_DIR / args.project / args.date / args.calib_name def build_board_config(args) -> Tuple[Dict[str, Tuple[int, int]], Dict[str, float]]: default_board = args.chessboard_size default_square = args.square_size left_board = args.left_chessboard_size or default_board right_board = args.right_chessboard_size or default_board left_square = args.left_square_size if args.left_square_size is not None else default_square right_square = ( args.right_square_size if args.right_square_size is not None else default_square ) board_sizes = { "lc": left_board, "lc-ir": left_board, "rc": right_board, "rg": right_board, "ir": right_board, } square_sizes = { "lc": left_square, "lc-ir": left_square, "rc": right_square, "rg": right_square, "ir": right_square, } return board_sizes, square_sizes