File size: 4,469 Bytes
699f3cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from __future__ import annotations

import json
import shutil
from pathlib import Path
from typing import Any

from src.config.settings import MvpRuntimeSettings
from src.tools.report_paths import EXPORT_REPORTS_DIR


def prepare_runtime_package(
    runtime_settings: MvpRuntimeSettings,
    *,
    base_dir: str | Path = "final_runtime",
    reports_dir: str | Path = EXPORT_REPORTS_DIR,
) -> dict[str, Any]:
    del reports_dir
    base = Path(base_dir)
    config_dir = base / "config"
    artifacts_dir = base / "artifacts" / "task3"
    logs_dir = base / "logs"
    cache_dir = base / "cache"
    for directory in (config_dir, artifacts_dir, logs_dir, cache_dir):
        directory.mkdir(parents=True, exist_ok=True)

    copied_weight = _copy_if_exists(
        runtime_settings.task3_yoloe_weight_path,
        artifacts_dir / Path(runtime_settings.task3_yoloe_weight_path).name,
    )
    manifest = _build_runtime_manifest(
        runtime_settings=runtime_settings,
        copied_weight=copied_weight,
    )
    manifest_path = config_dir / "task3_runtime_manifest.json"
    manifest_path.write_text(json.dumps(manifest, indent=2), encoding="utf-8")

    runtime_toml_path = config_dir / "runtime.toml"
    runtime_toml_path.write_text(_render_runtime_toml(runtime_settings, manifest_path, base), encoding="utf-8")

    readme_path = base / "README.md"
    readme_path.write_text(_render_runtime_readme(), encoding="utf-8")
    return {
        "base_dir": str(base),
        "config_path": str(runtime_toml_path),
        "manifest_path": str(manifest_path),
        "manifest": manifest,
    }


def _build_runtime_manifest(
    *,
    runtime_settings: MvpRuntimeSettings,
    copied_weight: str | None,
) -> dict[str, Any]:
    return {
        "task": "task3",
        "required": [
            {
                "artifact_id": Path(runtime_settings.task3_yoloe_weight_path).name,
                "path": copied_weight,
                "runtime": "ultralytics",
                "required": True,
                "validation_status": copied_weight is not None,
            }
        ],
        "references": {
            "reference_dir": str(runtime_settings.task3_reference_dir),
            "eval_reference_dir": str(runtime_settings.task3_eval_reference_dir),
            "eval_manifest_path": str(runtime_settings.task3_eval_manifest_path),
        },
    }


def _render_runtime_toml(runtime_settings: MvpRuntimeSettings, manifest_path: Path, base_dir: Path) -> str:
    lines = [
        "[task3]",
        f'mode = "{runtime_settings.task3_mode}"',
        f'reference_dir = "{Path(runtime_settings.task3_reference_dir).as_posix()}"',
        f'eval_reference_dir = "{Path(runtime_settings.task3_eval_reference_dir).as_posix()}"',
        f'eval_manifest_path = "{Path(runtime_settings.task3_eval_manifest_path).as_posix()}"',
        f'yoloe_weight_path = "{Path(runtime_settings.task3_yoloe_weight_path).as_posix()}"',
        f'yoloe_device = "{runtime_settings.task3_yoloe_device or "auto"}"',
        f"yoloe_allow_cpu = {str(bool(runtime_settings.task3_yoloe_allow_cpu)).lower()}",
        f"orb_features = {int(runtime_settings.task3_orb_features)}",
        f"match_min_inliers = {int(runtime_settings.task3_match_min_inliers)}",
        f"min_score = {float(runtime_settings.task3_min_score)}",
        f"yoloe_min_score = {float(runtime_settings.task3_yoloe_min_score)}",
        f"yoloe_thermal_min_score = {float(runtime_settings.task3_yoloe_thermal_min_score)}",
        "",
        "[paths]",
        f'log_dir = "{(base_dir / "logs").as_posix()}"',
        f'cache_dir = "{(base_dir / "cache").as_posix()}"',
        f'manifest_path = "{manifest_path.as_posix()}"',
        "",
        "[smoke]",
        'default_mode = "batch"',
        "default_max_frames = 2",
    ]
    return "\n".join(lines) + "\n"


def _render_runtime_readme() -> str:
    return (
        "# Final Runtime\n\n"
        "Bu klasor Task 3 batch/sequential adapter smoke calismalari icin gerekli runtime artefact ve config duzenini toplar.\n"
        "Task 1 ve Task 2 artefactlari bu repodan cikarilmistir.\n"
    )


def _copy_if_exists(source: str | Path | None, destination: Path) -> str | None:
    if source is None:
        return None
    source_path = Path(source)
    if not source_path.exists():
        return None
    destination.parent.mkdir(parents=True, exist_ok=True)
    shutil.copy2(source_path, destination)
    return str(destination)