Expand Seg task coverage and coverage dashboard
This commit is contained in:
191
backend/app/coverage.py
Normal file
191
backend/app/coverage.py
Normal file
@@ -0,0 +1,191 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .catalog import TASK_DEFAULTS, TASK_TYPES
|
||||
from .config import settings
|
||||
from .modules import build_module_task
|
||||
from .paths import rel
|
||||
|
||||
|
||||
SCRIPT_TASK_MAP: dict[str, str] = {
|
||||
"Back_Up.sh": "system.backup",
|
||||
"Check_Graph_Card.sh": "system.check_graph_card",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/1_rename_pics.sh": "dataset.rename",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/2_1_Trans_to_png.py": "dataset.to_png",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/2_2_Resize.py": "dataset.resize_single",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/2_reformate_pics.sh": "dataset.resize",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/3_pair_ori_label.sh": "dataset.pair",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/4_deal_labels.py": "dataset.deal_labels",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/4_deal_labels_old(老版程序).py": "dataset.deal_labels_old",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/4_rebuild_labels.sh": "dataset.rebuild_labels",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/5_TOOL_stack_pics.sh": "dataset.stack",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/5_stack_picture.py": "dataset.stack_single",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/6_TOOL_stitch_pics.sh": "dataset.stitch",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/6_stitch_picture.py": "dataset.stitch_single",
|
||||
"DataSet_Own/1. 图片预处理(内含使用手册)/Seg_data_run.sh": "dataset.run_wizard",
|
||||
"Seg_All_In_One_Analysis/1_Analysis_All.py": "analysis.all",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/0_Initial_Save_All_Model_locally.py": "mmseg.init_weights",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/1_Initial_Data_All-ori.py": "mmseg.generate_data_legacy",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/1_Initial_Data_All_data_from_1_Data_Parameter-V1.py": "mmseg.generate_data_v1",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/1_Initial_Data_All_data_from_1_Data_Parameter-V2.py": "mmseg.generate_data",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/2_Initial_Alg_All-ori-old.py": "mmseg.generate_alg_legacy",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/2_Initial_Alg_All_data_from_2_Alg_Program-V1.py": "mmseg.generate_alg_v1",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/2_Initial_Alg_All_data_from_2_Alg_Program-V2.py": "mmseg.generate_alg",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/3_Find_And_Delete_Special_Epoch.py": "mmseg.delete_epoch",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/3_Tool_Copy_Result_To_Hardisk.sh": "mmseg.copy_result",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_1_predict_params_FLOPs_FPS_V2.py": "mmseg.flops_fps",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_1_predict_params_and_FLOPs_V1.py": "mmseg.flops_fps_v1",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_2_predict_matrics_from_log_V1.py": "mmseg.metrics_v1",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_2_predict_matrics_from_log_V2.py": "mmseg.metrics",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_3_predict_draw_pictures_and_tabels.py": "mmseg.draw",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/4_4_extract_loss_and_best_miou.py": "mmseg.extract_loss_miou",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/x4_Predict_V1-.py": "mmseg.predict_v1",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/x4_Predict_V2-.py": "mmseg.predict_v2",
|
||||
"Seg_All_In_One_MMSeg/tools/train.py": "mmseg.train",
|
||||
"Seg_All_In_One_SegModel/1_predict.py": "segmodel.predict",
|
||||
"Seg_All_In_One_SegModel/1_predict_raw_masks_check.py": "segmodel.raw_mask_check",
|
||||
"Seg_All_In_One_SegModel/2_predict_params_and_FLOPs_V1.py": "segmodel.flops",
|
||||
"Seg_All_In_One_SegModel/2_predict_params_and_FLOPs_V2.py": "segmodel.flops",
|
||||
"Seg_All_In_One_SegModel/3_predict_matrics_from_log.py": "segmodel.metrics",
|
||||
"Seg_All_In_One_SegModel/Tool_Copy_Best_Model.sh": "segmodel.copy_best",
|
||||
"Seg_All_In_One_SegModel/Tool_benchmark_smp.py": "segmodel.benchmark",
|
||||
"Seg_All_In_One_SegModel/Tool_get_params_and_FLOPs.py": "segmodel.params_flops",
|
||||
"Seg_All_In_One_SegModel/predict.sh": "segmodel.batch_predict",
|
||||
"Seg_All_In_One_SegModel/train.py": "segmodel.train",
|
||||
"Seg_All_In_One_SegModel/train.sh": "segmodel.batch_train",
|
||||
"Seg_All_In_One_YoloModel/Tool_Yolo_Copy_Best_Model.sh": "yolo.copy_best",
|
||||
"Seg_All_In_One_YoloModel/Yolo可视化测试/yolo_layer_tester.py": "yolo.layer_tester",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/0_1_check_picture_pair.py": "dataset.yolo_check_pairs",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/0_2_TOOL_stack_pics.sh": "dataset.yolo_stack",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/0_2_stack_picture.py": "dataset.yolo_stack_single",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/1_deal_labels.py": "dataset.yolo_rebuild_labels",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/2_Check_and_Gen_Txt_Label_ori_label.py": "dataset.yolo_txt_ori",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/2_Check_and_Gen_Txt_Label_sort_label.py": "dataset.yolo_txt_sort",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/Tool_convert_bmp_jpg_to_png.py": "dataset.yolo_convert_png",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/Tool_resize_pics.py": "dataset.yolo_resize",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict.sh": "yolo.batch_predict",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict_V1.py": "yolo.predict_v1",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict_V2.py": "yolo.predict",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict_V2_compare_all.py": "yolo.compare",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict_raw_masks_check.py": "yolo.raw_mask_check",
|
||||
"Seg_All_In_One_YoloModel/yolo_predict_visualize_nn.py": "yolo.heatmap",
|
||||
"Seg_All_In_One_YoloModel/yolo_train.py": "yolo.train",
|
||||
"Seg_All_In_One_YoloModel/yolo_train.sh": "yolo.batch_train",
|
||||
"Seg_Predict_Own_Video_V2/1_Save_Frame_V1.py": "dataset.video_frames",
|
||||
"Seg_Predict_Own_Video_V2/1_Save_Frame_V2.py": "dataset.video_frames",
|
||||
"Seg_Predict_YoloModel/yolo_Seg_Video-V1-Visible.py": "yolo.video_visible",
|
||||
"Seg_Predict_YoloModel/yolo_Seg_Video-V2-UnVisible.py": "yolo.video_unvisible",
|
||||
"Tool-可视化/0_图片Labels生成/4_deal_labels.py": "visual.deal_labels",
|
||||
"Tool-可视化/0_图片Labels生成/Tool_deal_labels.py": "visual.tool_deal_labels_demo",
|
||||
"Tool-可视化/Tool_Check_and_Gen_Txt_Label_ori_label.py": "visual.label_ori",
|
||||
"Tool-可视化/Tool_Check_and_Gen_Txt_Label_sort_label.py": "visual.label_sort",
|
||||
"Tool-可视化/Tool_Gen_8_Bit_PNG[没用,不认].py": "visual.gen_8bit_png",
|
||||
"Tool-可视化/get_FPS.py": "visual.fps",
|
||||
"Tool-可视化/inference.py": "visual.inference",
|
||||
"Tool-可视化/train.py": "visual.train",
|
||||
"Tool-可视化/yolov11_heatmap_V1.py": "visual.yolo11_heatmap_v1",
|
||||
"Tool-可视化/yolov11_heatmap_V2.py": "visual.yolo11_heatmap_v2",
|
||||
"Tool-图片堆叠/1_check_picture_pair.py": "dataset.stack_pair_check",
|
||||
"Tool-图片堆叠/2_TOOL_stack_pics.sh": "dataset.stack_tool_batch",
|
||||
"Tool-图片堆叠/2_stack_picture.py": "dataset.stack_tool_single",
|
||||
}
|
||||
|
||||
SUPPORTING_SCRIPT_PATTERNS = (
|
||||
"Seg_All_In_One_MMSeg/demo/",
|
||||
"Seg_All_In_One_MMSeg/build/",
|
||||
"Seg_All_In_One_MMSeg/configs/",
|
||||
"Seg_All_In_One_MMSeg/docker/",
|
||||
"Seg_All_In_One_MMSeg/docs/",
|
||||
"Seg_All_In_One_MMSeg/projects/",
|
||||
"Seg_All_In_One_MMSeg/mmseg/",
|
||||
"Seg_All_In_One_MMSeg/tests/",
|
||||
"Seg_All_In_One_MMSeg/setup.py",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/2_Alg_Program/",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/Initial_Alg_Program/",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/Initial_Data_Program/",
|
||||
"Seg_All_In_One_MMSeg/My_All_In_One/Initial_Schedule_Program/",
|
||||
"Seg_All_In_One_MMSeg/tools/dist_",
|
||||
"Seg_All_In_One_MMSeg/tools/slurm_",
|
||||
"Seg_All_In_One_MMSeg/tools/test.py",
|
||||
"Seg_All_In_One_MMSeg/tools/analysis_tools/",
|
||||
"Seg_All_In_One_MMSeg/tools/dataset_converters/",
|
||||
"Seg_All_In_One_MMSeg/tools/deployment/",
|
||||
"Seg_All_In_One_MMSeg/tools/misc/",
|
||||
"Seg_All_In_One_MMSeg/tools/model_converters/",
|
||||
"Seg_All_In_One_MMSeg/tools/torchserve/",
|
||||
"Seg_All_In_One_SegModel/config.py",
|
||||
"Seg_All_In_One_SegModel/dataset.py",
|
||||
"Seg_All_In_One_SegModel/loss.py",
|
||||
"Seg_All_In_One_SegModel/utils.py",
|
||||
"Seg_All_In_One_YoloModel/yolo_config.py",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/Tool_Classes_And_Palette.py",
|
||||
"Seg_All_In_One_YoloModel/Yolo数据集构建/Tool_deal_labels.py",
|
||||
"Seg_Predict_YoloModel/yolo_config.py",
|
||||
"Seg_Predict_YoloModel/yolo_train.py",
|
||||
"DataSet_Own/2. 图片分割程序(mmseg)/",
|
||||
)
|
||||
|
||||
|
||||
def _script_inventory() -> list[str]:
|
||||
scripts = []
|
||||
for path in settings.source_root.rglob("*"):
|
||||
if path.is_file() and path.suffix in {".py", ".sh"}:
|
||||
scripts.append(rel(path, settings.source_root))
|
||||
return sorted(scripts)
|
||||
|
||||
|
||||
def _is_supporting_script(relative_path: str) -> bool:
|
||||
return any(relative_path.startswith(pattern) or relative_path == pattern for pattern in SUPPORTING_SCRIPT_PATTERNS)
|
||||
|
||||
|
||||
def _command_script_path(command: list[str]) -> Path | None:
|
||||
if not command:
|
||||
return None
|
||||
if command[0] == "bash" and len(command) > 1:
|
||||
return Path(command[1])
|
||||
if command[0] == "python" and len(command) > 1 and command[1] != "-c":
|
||||
return Path(command[1])
|
||||
if len(command) > 5 and command[:3] == ["conda", "run", "-n"] and command[4] == "python":
|
||||
return Path(command[5])
|
||||
return None
|
||||
|
||||
|
||||
def build_task_checks() -> list[dict[str, Any]]:
|
||||
checks = []
|
||||
for task in TASK_TYPES:
|
||||
params = TASK_DEFAULTS.get(task, {})
|
||||
try:
|
||||
spec = build_module_task(task, dict(params), settings.task_conda_env)
|
||||
script_path = _command_script_path(spec.command) if spec else None
|
||||
checks.append(
|
||||
{
|
||||
"task": task,
|
||||
"passed": spec is not None and (script_path is None or script_path.exists()),
|
||||
"command": spec.command if spec else None,
|
||||
"cwd": str(spec.cwd) if spec else None,
|
||||
"script_exists": None if script_path is None else script_path.exists(),
|
||||
"script": None if script_path is None else str(script_path),
|
||||
}
|
||||
)
|
||||
except Exception as exc:
|
||||
checks.append({"task": task, "passed": False, "error": str(exc)})
|
||||
return checks
|
||||
|
||||
|
||||
def get_coverage_report() -> dict[str, Any]:
|
||||
scripts = _script_inventory()
|
||||
mapped_scripts = [script for script in scripts if script in SCRIPT_TASK_MAP]
|
||||
user_scripts = [script for script in scripts if not _is_supporting_script(script)]
|
||||
unmapped_user_scripts = [script for script in user_scripts if script not in SCRIPT_TASK_MAP]
|
||||
task_checks = build_task_checks()
|
||||
return {
|
||||
"scripts_total": len(scripts),
|
||||
"user_scripts_total": len(user_scripts),
|
||||
"mapped_user_scripts": len(mapped_scripts),
|
||||
"task_build_passed": all(item["passed"] for item in task_checks),
|
||||
"unmapped_user_scripts": unmapped_user_scripts,
|
||||
"script_task_map": SCRIPT_TASK_MAP,
|
||||
"task_build_checks": task_checks,
|
||||
}
|
||||
Reference in New Issue
Block a user