Generated banner for Amc Run Sample Calibration
Generated logo for Amc Run Sample Calibration

Amc Run Sample Calibration

NVIDIAOfficialCreated by Shubham AgrawalDistributed by NVIDIA

  • Skill
  • Workflow
  • Software development
  • Apache-2.0
  • Medium risk
  • Has scripts

From the author

Run end-to-end calibration on the shipped sample dataset (sdg_08_2_sample_data_010926.zip) against a running AMC microservice. Use when user says 'test sample dataset', 'run sample calibration', 'verify AMC install', or 'launch and test'.
— the description by Shubham Agrawal

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides an automated workflow to verify that a running AutoMagicCalib (AMC) microservice stack is functioning correctly. By processing a specific bundled sample dataset (sdg_08_2_sample_data_010926.zip) containing synthetic warehouse camera data and ground truth, it performs a full calibration cycle. The process includes project creation, data uploading, calibration execution, and evaluation metric reporting, ensuring the environment is ready for production data.

What it does

  • Detects a running AMC microservice on local ports 8000-8009.
  • Extracts and prepares the bundled sample dataset for processing.
  • Automates the full calibration pipeline including video, alignment, and ground truth uploads.
  • Executes calibration and reports performance metrics like L2 distance and reprojection error.
  • Attempts VGGT refinement if the project state allows.
  • Provides a manual Swagger UI walkthrough alternative for non-scripted interaction.

When to use it

  • Immediately after deploying an AMC stack to verify successful installation.
  • When troubleshooting a suspected configuration issue in the AMC microservice.
  • Before running calibration on custom video data to ensure the environment is stable.
  • When a user requests a sanity check of the system using provided sample assets.

Advantages

  • Validates the entire end-to-end stack, not just individual components.
  • Uses ground truth data to provide objective performance metrics.
  • Automates repetitive API sequences, reducing manual configuration errors.
  • Includes built-in checks for prerequisites like backend connectivity and file availability.

Usage examples

“verify AMC install”
The agent scans for a running AMC backend, extracts the sample dataset, runs the calibration script, and reports the final evaluation metrics.
“test sample dataset”
The agent executes the automated calibration workflow and provides a summary of the L2 distance and reprojection error results.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/nvidia/amc-run-sample-calibration/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip amc-run-sample-calibration.zip -d .agents/skills

Documentation by Shubham Agrawal

Skill: Calibrate Sample Dataset

When to Use This Skill

Activate this skill when the user wants to sanity-check a running AMC stack with the bundled sample dataset. Typical prompts:

  • "test the sample dataset" / "run sample calibration"

  • "verify AMC install"

  • "launch and test" (chain with amc-setup-calibration-stack if the MS isn't already running)

Do NOT use this skill when:

  • The user references their own video paths (e.g. /data/videos/, cam_*.mp4 not from the bundled zip) — route to amc-run-video-calibration.

  • The user provides live RTSP streams or rtsp://... URLs — route to amc-run-rtsp-calibration.

  • This skill is exclusively for assets/sdg_08_2_sample_data_010926.zip.

Prerequisite: AMC microservice running on a port in 8000-8009. If no backend is detected, delegate to amc-setup-calibration-stack first.

If execution cannot proceed in the current environment (no backend, missing sample data, etc.), surface the blocker AND describe the expected workflow + API sequence concisely so the user understands what will run once prerequisites are met. Do not fabricate calibration outputs, evaluation metrics, or trajectories.

Overview

Run a full calibration on the bundled sample dataset (sdg_08_2_sample_data_010926.zip, 4 synthetic warehouse cameras with ground truth) against a running AutoMagicCalib microservice. Useful for verifying that a freshly-launched stack works end-to-end before throwing real data at it.

The sample includes GT, so the run produces evaluation metrics (L2 distance, reprojection error) — no calibration parameter tuning needed.

Prerequisites

  • [ ] AMC microservice running (follow skills/amc-setup-calibration-stack/SKILL.md if not)

  • [ ] Sample zip present at assets/sdg_08_2_sample_data_010926.zip

  • [ ] Python 3 with requests installed, or use the Swagger UI path below

    • Install it explicitly before running the script: python3 -m pip install requests

    • If pip is unavailable, install your distro's Python packaging support first

Instructions

"launch AMC and test sample dataset" (or similar):

  1. Run skills/amc-setup-calibration-stack/SKILL.md first.

  2. Wait for /v1/ready to return OK.

  3. Extract sample data (snippet below) — idempotent, safe to re-run.

  4. Run the bundled script in Run Script.

  5. Report final metrics + UI URL for manual inspection.

  6. VGGT refinement is attempted by default when the project reports vggt_state: READY; otherwise the script explains that VGGT setup is optional and can be enabled later for refinement.

"test sample dataset" (MS already running):

  1. Detect backend: scan ports 8000–8009 for a /v1/ready response.

  2. If none → point to the setup skill.

  3. Extract sample data if not already cached.

  4. Run the bundled script.

  5. Report metrics.

Detect Running Backend
MS_PORT=""
for port in {8000..8009}; do
  if curl -s "http://localhost:$port/v1/ready" | grep -q '"code":0'; then
    MS_PORT=$port; break
  fi
done
[ -z "$MS_PORT" ] && { echo "No running backend. Run amc-setup-calibration-stack skill first."; exit 1; }
echo "Backend on port $MS_PORT"
Locate + Extract Sample Data (idempotent)
: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }

SAMPLE_ZIP="$REPO_ROOT/assets/sdg_08_2_sample_data_010926.zip"
[ -f "$SAMPLE_ZIP" ] || { echo "Sample zip not found at $SAMPLE_ZIP"; exit 1; }

# Cache directory next to the zip.
SAMPLE_DIR="$(dirname "$SAMPLE_ZIP")/.cache/sdg_08_2_sample_data_010926"

if [ ! -d "$SAMPLE_DIR" ]; then
  mkdir -p "$SAMPLE_DIR"
  unzip -q "$SAMPLE_ZIP" -d "$SAMPLE_DIR"
fi
ls "$SAMPLE_DIR"
# Expected (possibly inside a wrapper folder): alignment_data/  GT.zip  videos/

Run Script

Run the bundled script from the amc-run-sample-calibration skill package, not from the auto-magic-calib repo root. If the user points the agent at this skill folder directly instead of installing it, set AMC_SAMPLE_SKILL_DIR to the directory containing this SKILL.md, or run the command from that directory. Set REPO_ROOT to the AutoMagicCalib checkout resolved by amc-setup-calibration-stack; the script auto-detects a running backend on localhost ports 8000-8009 when BASE_URL / MS_PORT are not set, accepts BASE_URL, MS_PORT, SAMPLE_DIR, and RUN_VGGT overrides, creates a fresh project each run, attempts VGGT when ready, and prints the NGC warehouse dataset note at the end.

# REPO_ROOT must point to the auto-magic-calib checkout, not the DeepStream repo.
: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }

# If AMC was resolved from DeepStream's tools/auto-magic-calib submodule,
# derive the DeepStream root so the unpacked repo skill can be used directly.
if [ -z "${DEEPSTREAM_REPO_ROOT:-}" ] && [ -d "$REPO_ROOT/../../skills/amc-run-sample-calibration" ]; then
  DEEPSTREAM_REPO_ROOT="$(cd "$REPO_ROOT/../.." && pwd)"
fi

SCRIPT_PATH=""
for candidate in \
  "${AMC_SAMPLE_SKILL_DIR:+$AMC_SAMPLE_SKILL_DIR/scripts/run_sample_calibration.py}" \
  "$PWD/scripts/run_sample_calibration.py" \
  "${DEEPSTREAM_REPO_ROOT:+$DEEPSTREAM_REPO_ROOT/skills/amc-run-sample-calibration/scripts/run_sample_calibration.py}" \
  "$PWD/skills/amc-run-sample-calibration/scripts/run_sample_calibration.py" \
  "$HOME/.claude/skills/amc-run-sample-calibration/scripts/run_sample_calibration.py" \
  "$HOME/.codex/skills/amc-run-sample-calibration/scripts/run_sample_calibration.py" \
  "$HOME/.cursor/skills/amc-run-sample-calibration/scripts/run_sample_calibration.py"; do
  if [ -f "$candidate" ]; then
    SCRIPT_PATH="$candidate"
    break
  fi
done

[ -n "$SCRIPT_PATH" ] || {
  echo "ERROR: could not find amc-run-sample-calibration/scripts/run_sample_calibration.py" >&2
  echo "Set AMC_SAMPLE_SKILL_DIR to the amc-run-sample-calibration skill directory, or run this block from that directory." >&2
  exit 1
}

python3 "$SCRIPT_PATH"

Alternative: Swagger UI Walkthrough

Agent shortcut: if the user explicitly requested a Swagger UI walkthrough (or said "no Python"), emit the table below and stop — do not invoke shell tooling, read other sections, or run the bundled Python script.

The microservice exposes an interactive OpenAPI UI at http://<HOST_IP>:<MS_PORT>/docs. If you prefer clicking through the API by hand:

  1. Open http://<HOST_IP>:<MS_PORT>/docs in a browser.

  2. Unzip sdg_08_2_sample_data_010926.zip into a cache directory next to it.

  3. Execute these endpoints in order, copying the project_id from step 1 into subsequent paths:

    #EndpointBody / Files
    1POST /v1/create_projectproject_name: any string
    2POST /v1/upload_video_files/{project_id}files: upload all 4 videos/cam_0*.mp4 sorted by name
    3POST /v1/upload_alignment/{project_id}alignment_file: alignment_data/alignment_data.json
    4POST /v1/upload_layout/{project_id}layout_file: alignment_data/layout.png
    5POST /v1/upload_gt_file/{project_id}gt_file: GT.zip
    6POST /v1/verify_project/{project_id}— (expect project_state: READY)
    7POST /v1/calibrate/{project_id}JSON: {"detector_type": "resnet"}
    8GET /v1/get_project_info/{project_id}Refresh every ~10 s until project_state = COMPLETED
    9GET /v1/result/{project_id}/evaluation_statisticsRead L2 distance + reprojection error
    10 optionalPOST /v1/vggt/calibrate/{project_id} then GET /v1/vggt_results/{project_id}/evaluation_statisticsRun only when vggt_state is READY; poll vggt_state until COMPLETED

This is the same sequence the bundled Python script runs, just executed manually. Step 10 is attempted by default when vggt_state is READY; otherwise it is skipped with setup guidance.

Status Fields from get_project_info

project_info.project_state is the AMC calibration lifecycle for the project. Poll it until it reaches COMPLETED (or stop on ERROR).

project_info.vggt_state is a per-project VGGT refinement lifecycle, a project-scoped status rather than a direct global service or model-load status. A newly created project can report vggt_state: "INIT" even when the VGGT model is present and mounted. The expected lifecycle is INIT → READY after AMC calibration completes → RUNNING while VGGT refinement runs → COMPLETED (or ERROR). Interpret INIT on a new or uncalibrated project as normal project state. If AMC calibration is complete and the project remains in a non-ready VGGT state, confirm VGGT setup and model availability with the setup skill checks and service logs.

Success Criteria

  • Project reaches project_state == "COMPLETED" within ~30 min.

  • /v1/result/{id}/evaluation_statistics returns non-empty statistics (GT was uploaded).

  • VGGT either runs to vggt_state == "COMPLETED" and reports /v1/vggt_results/{id}/evaluation_statistics, or is skipped with setup guidance because the project is not READY for VGGT.

  • No ERROR state encountered.

Representative metrics for the sample (yours should be similar):

Average L2 distance(m)               : < 1.5
Average reprojection error 0(px)     : < 10

Key Output Files (on the server)

Results persist under $REPO_ROOT/projects/project_<project_id>/:

projects/project_<project_id>/
├── output/
│   ├── single_view_results/cam_XX/
│   │   ├── camInfo_hyper_XX.yaml
│   │   └── trajDump_Stream_0_3d.txt
│   └── multi_view_results/BA_output/results_ba/refined/
│       └── camInfo_XX.yaml          # ← final calibration (use this)
└── calibration.log

Monitoring Progress

PROJECT_ID=<id_from_step_1>
: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }
tail -F --retry "$REPO_ROOT/projects/project_${PROJECT_ID}/calibration.log"

Or stream MS logs:

: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }
docker compose -f "$REPO_ROOT/compose/compose.yml" logs -f auto-magic-calib-ms

Troubleshooting

IssueFix
requests not installedInstall it before running the script: python3 -m pip install requests
[2] Uploaded N videos where N >> 4SAMPLE_DIR resolved to the repo root (or another over-broad path) and rglob("cam_*.mp4") swept stale videos from .cache/, projects/, etc. Correct SAMPLE_DIR, then start a fresh project instead of trying to salvage the bad upload set. The script anchors on videos/ and asserts len(videos) <= 16 to fail loud
verify_project returns state != READYConfirm all 4 videos + alignment + layout + GT uploaded; inspect GET /v1/get_project_info/{id} response
Sample not extractedunzip <repo_root>/assets/sdg_08_2_sample_data_010926.zip -d <repo_root>/assets/.cache/sdg_08_2_sample_data_010926/
cam_*.mp4 glob finds 0 filesCheck wrapper-folder depth: find <sample_dir> -name "cam_*.mp4"
Calibration times out (>60 min)Check calibration.log for "insufficient tracklets"; see root README.md guidelines on input videos
Upload returns 413Raise server upload limit, or split files (sample files are <200 MB total so this is unusual)
Port scan finds no backendBackend not running — run amc-setup-calibration-stack skill

Additional Sample Dataset

The root README.md also documents nv_warehouse_032326.zip, a real-world warehouse dataset available from NGC. Download it with ngc registry resource download-version "nvidia/amc-nv-warehouse"; then use amc-run-video-calibration, upload nv_warehouse_config.json in the config step, and run with the transformer detector. It does not include ground-truth data.

  • skills/amc-setup-calibration-stack/SKILL.md — launch MS + UI (prerequisite).

  • skills/amc-run-video-calibration/SKILL.md — run calibration on your own pre-recorded MP4s.

  • skills/amc-run-rtsp-calibration/SKILL.md — run calibration from live RTSP streams through VIOS capture.

Root README.md "Sample Data Setup" and "Calibration Workflow (UI)" sections cover the human-oriented path through the same sample.

<!-- signing marker -->

Files

scripts/run_sample_calibration.py

#!/usr/bin/env python3
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Run AMC calibration against the bundled synthetic sample dataset."""

import os
import sys
import time
from contextlib import ExitStack
from pathlib import Path

try:
    import requests
except ModuleNotFoundError as exc:
    raise SystemExit(
        "This script requires Python 3 with the 'requests' package installed. "
        "Install it first, for example: python3 -m pip install requests"
    ) from exc


def _env_bool(name: str, default: bool) -> bool:
    value = os.environ.get(name)
    if value is None:
        return default
    return value.strip().lower() in ("1", "true", "yes", "y")


def _normalize_base_url(value: str) -> str:
    base = value.rstrip("/")
    return base if base.endswith("/v1") else f"{base}/v1"


def _detect_ms_port() -> str:
    for port in range(8000, 8010):
        try:
            response = requests.get(f"http://localhost:{port}/v1/ready", timeout=(3, 5))
            response.raise_for_status()
            payload = response.json()
        except (requests.RequestException, ValueError):
            continue
        if payload.get("code") in (0, "0"):
            return str(port)
    raise SystemExit(
        "No running AMC backend detected on localhost ports 8000-8009. "
        "Start the stack first or set BASE_URL / MS_PORT explicitly."
    )


# Run from the auto-magic-calib repo root, or set REPO_ROOT explicitly.
REPO_ROOT = Path(os.environ.get("REPO_ROOT") or Path.cwd())
BASE_URL = os.environ.get("BASE_URL")
if BASE_URL:
    BASE_URL = _normalize_base_url(BASE_URL)
else:
    MS_PORT = os.environ.get("MS_PORT") or _detect_ms_port()
    BASE_URL = f"http://localhost:{MS_PORT}/v1"
RUN_VGGT = _env_bool("RUN_VGGT", True)

# Sample zip lives in assets/.
def _find_sample_dir() -> Path:
    candidate = REPO_ROOT / "assets" / ".cache" / "sdg_08_2_sample_data_010926"
    if candidate.exists():
        return candidate
    sys.exit(
        "Sample data not extracted. Run the extraction snippet from this skill first, "
        "or pass SAMPLE_DIR= explicitly."
    )

# NOTE: do NOT write `Path(os.environ.get("SAMPLE_DIR", "")) or _find_sample_dir()`
# -- Path("") evaluates to Path('.') which is truthy, so the `or` never falls
# through and the script silently picks `.` (typically the repo root). Rglobbing
# `cam_*.mp4` from there can sweep dozens of stale videos from prior test runs.
_env_sample = os.environ.get("SAMPLE_DIR")
SAMPLE_DIR = Path(_env_sample).resolve() if _env_sample else _find_sample_dir()

# Locate sample files (handle an optional wrapper folder from unzip)
def _find(path: Path, name: str) -> Path:
    hits = list(path.rglob(name))
    if not hits:
        sys.exit(f"Could not find {name} under {path}")
    return hits[0]

# Anchor video discovery on the canonical `videos/` directory if present
# (non-recursive). Only fall back to rglob if no `videos/` folder exists,
# and assert a sane upper bound so a misconfigured SAMPLE_DIR fails loud
# instead of uploading every cam_*.mp4 in the tree.
videos_dirs = list(SAMPLE_DIR.rglob("videos"))
videos_dir = next((d for d in videos_dirs if d.is_dir()), None)
if videos_dir is not None:
    videos = sorted(videos_dir.glob("cam_*.mp4"))
else:
    videos = sorted(SAMPLE_DIR.rglob("cam_*.mp4"))

alignment = _find(SAMPLE_DIR, "alignment_data.json")
layout = _find(SAMPLE_DIR, "layout.png")
gt_zip = _find(SAMPLE_DIR, "GT.zip")

assert len(videos) >= 2, f"Need >=2 cam_XX.mp4 under {SAMPLE_DIR}, found {len(videos)}"
# Sample dataset has 4 cameras -- bail if SAMPLE_DIR is so wide we'd upload
# unrelated videos. Override SAMPLE_DIR explicitly if you need a different one.
assert len(videos) <= 16, (
    f"Found {len(videos)} cam_*.mp4 under {SAMPLE_DIR} -- looks like SAMPLE_DIR "
    "is too broad (probably picked up stale test caches). Set SAMPLE_DIR to the "
    "extracted sample folder explicitly and re-run."
)
print(f"Base URL:   {BASE_URL}")
print(f"Sample dir: {SAMPLE_DIR}")
print(f"Videos:     {[v.name for v in videos]}")

s = requests.Session()
DEFAULT_TIMEOUT = (10, 120)  # (connect, read) -- keeps hung MS calls from blocking the 3600s budget

# Step 1 -- Create project
project_name = f"sample_test_{int(time.time())}"
r = s.post(f"{BASE_URL}/create_project", data={"project_name": project_name}, timeout=DEFAULT_TIMEOUT)
r.raise_for_status()
project_id = r.json()["project_id"]
print(f"[1] Created project {project_name} -> {project_id}")

# Step 2 -- Upload videos (sorted alphabetically; upload order defines camera indices)
with ExitStack() as stack:
    files = []
    for video in videos:
        handle = stack.enter_context(open(video, "rb"))
        files.append(("files", (video.name, handle, "video/mp4")))
    r = s.post(f"{BASE_URL}/upload_video_files/{project_id}", files=files, timeout=300)
r.raise_for_status()
print(f"[2] Uploaded {len(videos)} videos")

# Step 3 -- Upload alignment JSON
with open(alignment, "rb") as f:
    r = s.post(f"{BASE_URL}/upload_alignment/{project_id}",
               files={"alignment_file": (alignment.name, f, "application/json")},
               timeout=DEFAULT_TIMEOUT)
    r.raise_for_status()
print("[3] Uploaded alignment JSON")

# Step 4 -- Upload layout PNG
with open(layout, "rb") as f:
    r = s.post(f"{BASE_URL}/upload_layout/{project_id}",
               files={"layout_file": (layout.name, f, "image/png")},
               timeout=DEFAULT_TIMEOUT)
    r.raise_for_status()
print("[4] Uploaded layout PNG")

# Step 5 -- Upload GT zip (enables evaluation metrics)
with open(gt_zip, "rb") as f:
    r = s.post(f"{BASE_URL}/upload_gt_file/{project_id}",
               files={"gt_file": (gt_zip.name, f, "application/zip")}, timeout=120)
    r.raise_for_status()
print("[5] Uploaded GT zip")

# Step 6 -- Verify project
r = s.post(f"{BASE_URL}/verify_project/{project_id}", timeout=DEFAULT_TIMEOUT)
r.raise_for_status()
state = r.json()["project_state"]
print(f"[6] verify_project -> {state}")
if state != "READY":
    raise RuntimeError(f"Expected READY, got {state}")

# Step 7 -- Start calibration (defaults work for this dataset)
r = s.post(f"{BASE_URL}/calibrate/{project_id}", json={"detector_type": "resnet"}, timeout=DEFAULT_TIMEOUT)
r.raise_for_status()
print("[7] Calibration started (detector=resnet)")

# Step 8 -- Poll for completion (~10-30 min for sample). Print on every state
# change, plus a heartbeat at least once a minute so a long RUNNING state still
# shows progress.
print("[8] Polling (expect 10-30 min)...")
start, last_state, last_beat = time.time(), "", 0.0
while time.time() - start < 3600:
    r = s.get(f"{BASE_URL}/get_project_info/{project_id}", timeout=DEFAULT_TIMEOUT)
    r.raise_for_status()
    st = r.json()["project_info"]["project_state"]
    mins, secs = divmod(int(time.time() - start), 60)
    if st != last_state or time.time() - last_beat >= 60:
        print(f"    [{mins:>3}m {secs:02d}s] {st}", flush=True)
        last_state, last_beat = st, time.time()
    if st == "COMPLETED":
        print(f"[8] Completed in {mins}m {secs:02d}s")
        break
    if st == "ERROR":
        # Surface the tail of the calibration log so the failure is actionable.
        try:
            log_lines = s.get(f"{BASE_URL}/amc/calibrate/{project_id}/log", timeout=DEFAULT_TIMEOUT).text.splitlines()
            print("    --- last calibration log lines ---")
            for line in log_lines[-20:]:
                print(f"    {line}")
        except requests.RequestException as exc:
            print(f"    warning: could not fetch calibration log tail: {exc}")
        sys.exit(f"Calibration failed. Full log: GET {BASE_URL}/amc/calibrate/{project_id}/log")
    time.sleep(10)
else:
    sys.exit("Timed out after 60 min")

# Step 9 -- Evaluation statistics (GT was uploaded, so this should return metrics)
r = s.get(f"{BASE_URL}/result/{project_id}/evaluation_statistics", timeout=DEFAULT_TIMEOUT)
if r.status_code == 200:
    stats = r.json().get("statistics", r.json())
    print("\n[9] Evaluation statistics:")
    for k, v in stats.items():
        print(f"    {k}: {v}")
else:
    print(f"\n[9] evaluation_statistics returned {r.status_code}: {r.text[:200]}")

# Step 10 -- Optional VGGT refinement
if RUN_VGGT:
    info = s.get(f"{BASE_URL}/get_project_info/{project_id}", timeout=DEFAULT_TIMEOUT).json()
    vggt_state = info.get("project_info", {}).get("vggt_state", "INIT")
    if vggt_state == "READY":
        r = s.post(f"{BASE_URL}/vggt/calibrate/{project_id}", timeout=DEFAULT_TIMEOUT)
        r.raise_for_status()
        print("\n[10] VGGT refinement started")
        t0 = time.time()
        while time.time() - t0 < 900:
            info = s.get(f"{BASE_URL}/get_project_info/{project_id}", timeout=DEFAULT_TIMEOUT).json()
            vs = info.get("project_info", {}).get("vggt_state", "INIT")
            if vs == "COMPLETED":
                print("[10] VGGT refinement completed")
                r = s.get(f"{BASE_URL}/vggt_results/{project_id}/evaluation_statistics", timeout=DEFAULT_TIMEOUT)
                if r.status_code == 200:
                    print("\n[10] VGGT evaluation statistics:")
                    for k, v in (r.json().get("statistics") or r.json()).items():
                        print(f"    {k}: {v}")
                else:
                    print(f"\n[10] VGGT evaluation_statistics returned {r.status_code}: {r.text[:200]}")
                break
            if vs == "ERROR":
                raise RuntimeError("VGGT refinement failed")
            time.sleep(10)
        else:
            raise RuntimeError("VGGT refinement still running after 15 min")
    else:
        print(f"\n[10] VGGT skipped: project vggt_state={vggt_state}")
        print("     To run VGGT refinement later, set up the VGGT model with amc-setup-calibration-stack and rerun this optional step.")

print(f"\nProject ID: {project_id}")
print("Inspect in UI: open the project in the web UI to view results and overlay videos")
print("Additional dataset: nv_warehouse_032326.zip is available from NGC; download with: ngc registry resource download-version \"nvidia/amc-nv-warehouse\"")
print("Use amc-run-video-calibration with nv_warehouse_config.json and detector=transformer.")

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs network access, Needs a command-line tool, Needs Python

Security

What our scanner noticed· Medium risk

  • Large base64-encoded blobs
  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Shubham Agrawal
Publisher
NVIDIA (Official)
Distributed by
NVIDIA
Source
NVIDIA/skills · skills/amc-run-sample-calibration · commit fce3cca
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE-APACHE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Shubham Agrawal or NVIDIA.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download amc-run-sample-calibration.zip