Merge 2025-07-15 batch into the xlsx; tools to detect & re-track
- merge_2025_07_15_into_xlsx.py: pivot the legacy 2025_07_15_metadata_fixed.csv into the unified xlsx schema (one row per fly, training_date_time + testing_date_time). Backs up the xlsx before writing. 24 new rows across machines 076 / 139 / 145 / 268. - pick_targets.py: --video flag to bypass the inventory's in_xlsx filter, so a specific mp4 can be picked outside the normal flow. - explore_barrier_signal.py: visualises raw y(t), per-frame inter-fly distance, and sliding min/mean distance against a known barrier-opening time. Used for prototyping the detector. - detect_barrier_opening.py: per-ROI sliding-window mean-distance change-point estimator (median across ROIs). Currently noisy on a one-video calibration set; will be re-tuned once the 4 missing 2025-07-15 videos are re-tracked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8f3c4ca89c
commit
847d2cbd1b
4 changed files with 480 additions and 1 deletions
|
|
@ -363,6 +363,12 @@ def main() -> None:
|
|||
"--limit", type=int, default=None,
|
||||
help="only process the first N videos",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--video", action="append", default=[],
|
||||
metavar="MP4_PATH",
|
||||
help="explicit mp4 path to pick targets for (bypasses the inventory's "
|
||||
"in_xlsx filter). Repeat to specify multiple videos.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not INVENTORY_CSV.exists():
|
||||
|
|
@ -372,7 +378,27 @@ def main() -> None:
|
|||
)
|
||||
|
||||
inv = pd.read_csv(INVENTORY_CSV)
|
||||
todo = inv[inv["in_xlsx"] & ~inv["already_tracked"]].copy()
|
||||
if args.video:
|
||||
# Reason: explicit --video paths skip the in_xlsx filter so we can
|
||||
# re-track recordings that aren't in the merged xlsx (e.g. the
|
||||
# 2025-07-15 multi-recording sessions). Each path must exist in
|
||||
# the inventory so we still get machine_name / session_datetime
|
||||
# for the prompt; build a small synthetic todo from those rows.
|
||||
wanted = {str(Path(p).resolve()) for p in args.video}
|
||||
inv["_resolved"] = inv["mp4_path"].apply(lambda p: str(Path(p).resolve()))
|
||||
todo = inv[inv["_resolved"].isin(wanted)].drop(columns="_resolved").copy()
|
||||
missing = wanted - set(
|
||||
inv["mp4_path"].apply(lambda p: str(Path(p).resolve()))
|
||||
)
|
||||
if missing:
|
||||
print(f"⚠ {len(missing)} requested video(s) not in inventory; "
|
||||
"rebuild it with build_video_inventory.py if needed:")
|
||||
for m in sorted(missing):
|
||||
print(f" {m}")
|
||||
if todo.empty:
|
||||
sys.exit("No matching videos in inventory.")
|
||||
else:
|
||||
todo = inv[inv["in_xlsx"] & ~inv["already_tracked"]].copy()
|
||||
todo = todo.sort_values(
|
||||
["session_date", "machine_name", "session_time"]
|
||||
).reset_index(drop=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue