Spaces:
Running on Zero
Running on Zero
Auto-install motion_correction when missing
Browse files- kimodo/postprocess.py +52 -2
kimodo/postprocess.py
CHANGED
|
@@ -4,6 +4,8 @@
|
|
| 4 |
|
| 5 |
import logging
|
| 6 |
import os
|
|
|
|
|
|
|
| 7 |
from types import SimpleNamespace
|
| 8 |
from typing import Dict, List, Optional, Tuple
|
| 9 |
|
|
@@ -26,6 +28,7 @@ from .skeleton import (
|
|
| 26 |
)
|
| 27 |
|
| 28 |
logger = logging.getLogger(__name__)
|
|
|
|
| 29 |
|
| 30 |
|
| 31 |
def _env_bool(name: str, default: bool = False) -> bool:
|
|
@@ -35,6 +38,39 @@ def _env_bool(name: str, default: bool = False) -> bool:
|
|
| 35 |
return str(raw).strip().lower() in {"1", "true", "yes", "on"}
|
| 36 |
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
def extract_input_motion_from_constraints(
|
| 39 |
constraint_lst: List,
|
| 40 |
skeleton: SkeletonBase,
|
|
@@ -315,14 +351,28 @@ def post_process_motion(
|
|
| 315 |
)
|
| 316 |
|
| 317 |
# Call the motion correction for each batch (optional package)
|
|
|
|
| 318 |
try:
|
| 319 |
from motion_correction import motion_postprocess
|
| 320 |
except ImportError as e:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 321 |
if _env_bool("KIMODO_STRICT_MOTION_CORRECTION", default=False):
|
| 322 |
-
|
| 323 |
"Motion correction is required for this postprocessing path but the "
|
| 324 |
"motion_correction package is not installed. Install with: python -m pip install ./MotionCorrection"
|
| 325 |
-
)
|
|
|
|
|
|
|
|
|
|
| 326 |
|
| 327 |
logger.warning(
|
| 328 |
"motion_correction package is not installed; skipping correction and returning "
|
|
|
|
| 4 |
|
| 5 |
import logging
|
| 6 |
import os
|
| 7 |
+
import subprocess
|
| 8 |
+
import sys
|
| 9 |
from types import SimpleNamespace
|
| 10 |
from typing import Dict, List, Optional, Tuple
|
| 11 |
|
|
|
|
| 28 |
)
|
| 29 |
|
| 30 |
logger = logging.getLogger(__name__)
|
| 31 |
+
_MOTION_CORRECTION_INSTALL_ATTEMPTED = False
|
| 32 |
|
| 33 |
|
| 34 |
def _env_bool(name: str, default: bool = False) -> bool:
|
|
|
|
| 38 |
return str(raw).strip().lower() in {"1", "true", "yes", "on"}
|
| 39 |
|
| 40 |
|
| 41 |
+
def _try_install_motion_correction() -> bool:
|
| 42 |
+
"""Best-effort install for runtimes where optional package is missing."""
|
| 43 |
+
global _MOTION_CORRECTION_INSTALL_ATTEMPTED
|
| 44 |
+
if _MOTION_CORRECTION_INSTALL_ATTEMPTED:
|
| 45 |
+
return False
|
| 46 |
+
_MOTION_CORRECTION_INSTALL_ATTEMPTED = True
|
| 47 |
+
|
| 48 |
+
if not _env_bool("KIMODO_AUTO_INSTALL_MOTION_CORRECTION", default=True):
|
| 49 |
+
return False
|
| 50 |
+
|
| 51 |
+
# Prefer explicit override, then common repo/container locations.
|
| 52 |
+
candidates = [
|
| 53 |
+
os.environ.get("MOTION_CORRECTION_PATH"),
|
| 54 |
+
"./MotionCorrection",
|
| 55 |
+
"/home/user/app/MotionCorrection",
|
| 56 |
+
"/workspace/MotionCorrection",
|
| 57 |
+
]
|
| 58 |
+
install_target = next((path for path in candidates if path and os.path.isdir(path)), None)
|
| 59 |
+
if install_target is None:
|
| 60 |
+
logger.warning("MotionCorrection source directory not found; skipping auto-install attempt.")
|
| 61 |
+
return False
|
| 62 |
+
|
| 63 |
+
cmd = [sys.executable, "-m", "pip", "install", install_target]
|
| 64 |
+
logger.info("Attempting MotionCorrection install via: %s", " ".join(cmd))
|
| 65 |
+
proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
|
| 66 |
+
if proc.returncode != 0:
|
| 67 |
+
logger.warning("MotionCorrection auto-install failed: %s", (proc.stderr or proc.stdout or "").strip())
|
| 68 |
+
return False
|
| 69 |
+
|
| 70 |
+
logger.info("MotionCorrection auto-install succeeded from %s", install_target)
|
| 71 |
+
return True
|
| 72 |
+
|
| 73 |
+
|
| 74 |
def extract_input_motion_from_constraints(
|
| 75 |
constraint_lst: List,
|
| 76 |
skeleton: SkeletonBase,
|
|
|
|
| 351 |
)
|
| 352 |
|
| 353 |
# Call the motion correction for each batch (optional package)
|
| 354 |
+
import_error: Exception | None = None
|
| 355 |
try:
|
| 356 |
from motion_correction import motion_postprocess
|
| 357 |
except ImportError as e:
|
| 358 |
+
import_error = e
|
| 359 |
+
if _try_install_motion_correction():
|
| 360 |
+
try:
|
| 361 |
+
from motion_correction import motion_postprocess
|
| 362 |
+
except ImportError:
|
| 363 |
+
motion_postprocess = None
|
| 364 |
+
else:
|
| 365 |
+
motion_postprocess = None
|
| 366 |
+
|
| 367 |
+
if 'motion_postprocess' not in locals() or motion_postprocess is None:
|
| 368 |
if _env_bool("KIMODO_STRICT_MOTION_CORRECTION", default=False):
|
| 369 |
+
err = RuntimeError(
|
| 370 |
"Motion correction is required for this postprocessing path but the "
|
| 371 |
"motion_correction package is not installed. Install with: python -m pip install ./MotionCorrection"
|
| 372 |
+
)
|
| 373 |
+
if import_error is not None:
|
| 374 |
+
raise err from import_error
|
| 375 |
+
raise err
|
| 376 |
|
| 377 |
logger.warning(
|
| 378 |
"motion_correction package is not installed; skipping correction and returning "
|