labels¶
Labels: a project's hand-labeled 2D keypoints, their files, and the labeling aids.
Below deeperfly.project: a Labels set is built from view and keypoint names and a frame count alone. store is the sparse label set and its file, and files where one project's files live. The aids sit above them and are not imported here: detections merges a project's runs into the detector 2D (ADR-0083), identity tells which of a run's animals each labeled one is (ADR-0128), check is the labeling solve and its checks, suggest ranks the joints a label would most likely fix.
LabelFiles
dataclass
¶
One project's label files, keyed to the project they are read against.
Attributes:
| Name | Type | Description |
|---|---|---|
directory |
Path
|
The project folder holding the files, whether or not it exists yet. |
view_names |
tuple[str, ...]
|
The project's views, in order. |
keypoint_names |
tuple[str, ...]
|
The skeleton's points, in order. |
n_frames |
int
|
The project's frame count. |
Source code in src/deeperfly/labels/files.py
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
discarded_path
property
¶
Where the labels the last discard threw away are kept (ADR-0120).
autosave ¶
Write in-progress labels to the recovery sidecar, keeping them dirty.
A discard kept from before is stale now: restoring it would drop this edit.
Source code in src/deeperfly/labels/files.py
discard_unsaved ¶
Set the unsaved labels aside and reload the saved ones.
labels are the unsaved ones, an open session's; without them the sidecar is
what is set aside. Either way it lands at discarded_path, for
restore_discarded.
Source code in src/deeperfly/labels/files.py
load ¶
open ¶
The labels for editing and whether they came from the recovery sidecar.
Recovered labels load dirty, so the operator saves or discards them.
Source code in src/deeperfly/labels/files.py
restore_discarded ¶
Put what the last discard set aside back as the sidecar; whether there was.
It is touched as it lands, so the labels load from it again, dirty.
Source code in src/deeperfly/labels/files.py
save ¶
Persist the labels to labels.h5, clearing the sidecar and any discard.
Source code in src/deeperfly/labels/files.py
Labels ¶
Sparse per-(view, frame, keypoint) 2D ground truth for one project.
The V and K axes are positional, in the rig's and skeleton's order; an
unlabeled cell is NaN, and dirty tracks unsaved edits. Every accessor takes a
keyword-only instance, slot 0 by default.
Source code in src/deeperfly/labels/store.py
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
__init__ ¶
An empty label set over the given views, keypoints and frame count.
Source code in src/deeperfly/labels/store.py
absent_frame ¶
The (K,) absent mask for frame t (all False if none).
Source code in src/deeperfly/labels/store.py
absent_keypoint ¶
One keypoint's per-frame absent mask over every frame.
Source code in src/deeperfly/labels/store.py
changed_frames ¶
The frames whose authored state differs from other's, sorted.
A pixel, a hidden flag or an absent declaration of any instance counts; an empty cell and a cleared one are the same. The two sets share their shape.
Source code in src/deeperfly/labels/store.py
clear_instance ¶
Forget what one instance holds in one frame: points, flags, absences.
Source code in src/deeperfly/labels/store.py
clear_point ¶
Remove the label of one (view, frame, keypoint) cell, if any.
Source code in src/deeperfly/labels/store.py
frame ¶
The (V, K, 2) labels of one instance of frame t, all NaN if none.
Source code in src/deeperfly/labels/store.py
frame_effective ¶
The frame's GT with absent keypoints masked to NaN -- what the solve sees.
Source code in src/deeperfly/labels/store.py
frame_instances ¶
Every instance slot that holds anything in frame t, sorted.
A pixel, a hidden flag or an absent declaration counts, unlike
labeled_instances, which takes pixels only.
Source code in src/deeperfly/labels/store.py
hidden_frame ¶
The (V, K) hidden mask for frame t (all False if none).
Source code in src/deeperfly/labels/store.py
is_absent ¶
Whether a keypoint is declared not-on-this-animal in frame t.
Source code in src/deeperfly/labels/store.py
label_counts ¶
How many (view, keypoint) cells each of labeled_frames carries.
Source code in src/deeperfly/labels/store.py
labeled_frames ¶
Frame indices that carry a labeled point, sorted, each once.
labeled_instances ¶
The instance slots labeled in frame t, sorted (sparse track ids).
Source code in src/deeperfly/labels/store.py
open_keypoints ¶
How many keypoints each of labeled_frames still lacks to be complete.
A frame is complete (0) when every non-absent keypoint of each labeled
instance has at least min_views clicked views (ADR-0102). Counted per
instance, so a second animal with nothing clicked is not owed; one with a
single click owes its other keypoints.
Source code in src/deeperfly/labels/store.py
set_absent ¶
Declare a keypoint absent (or present again) in one frame.
Source code in src/deeperfly/labels/store.py
set_absent_every_frame ¶
Declare a keypoint absent (or present) in every frame.
Source code in src/deeperfly/labels/store.py
set_absent_keypoint ¶
Replace one keypoint's per-frame absent flags with a whole (T,) mask.
The general form of set_absent_every_frame, so an undo can put back any
pattern.
Source code in src/deeperfly/labels/store.py
set_hidden ¶
set_hidden(
view: int,
frame: int,
keypoint: int,
value: bool = True,
*,
instance: int = 0,
) -> None
Set or clear the hidden (exclude-from-loss) flag of one cell.
Source code in src/deeperfly/labels/store.py
set_point ¶
Set the labeled pixel of one (view, frame, keypoint) cell.
Source code in src/deeperfly/labels/store.py
to_coo ¶
The authored state as flat COO arrays for persistence.
Positions ride view/frame/keypoint/xy, hidden cells the hidden_*
triples, and absence half-open spans per keypoint
(absent_keypoint/absent_start/absent_end); each carries its instance
slot, which save_labels leaves out when only slot 0 is named. Rows are in
(frame, instance) order.
Source code in src/deeperfly/labels/store.py
count_complete_frames ¶
How many frames of a labels.h5 are complete (ADR-0102), from its columns.
count_labeled_frames ¶
How many frames a labels.h5 labels, reading only its frame index.
Nothing is checked against a project, so every project of a collection can be summarized at once.
Source code in src/deeperfly/labels/store.py
label_summary ¶
A project's labeled and complete (ADR-0102) frame counts, and its unsaved.
From one open of the file open would read; unsaved says it is the sidecar.
Source code in src/deeperfly/labels/files.py
labeled_frame_count ¶
How many frames a project has labels for, from the file open would read.
labels_source ¶
The file a project's labels come from, and whether it is the sidecar.
Source code in src/deeperfly/labels/files.py
load_labels ¶
load_labels(
path: str | Path,
*,
view_names: tuple[str, ...],
keypoint_names: tuple[str, ...],
n_frames: int,
) -> Labels
Load a labels.h5, checked and remapped against the current project.
A pure reordering of the views or keypoints is absorbed.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a stored view or keypoint no longer exists, the frame count shrank below a labeled frame, or the format version is unknown. |
Source code in src/deeperfly/labels/store.py
save_labels ¶
Write a label set to a labels.h5, clearing its dirty flag unless told not to.
The file is replaced whole, so a reader never sees it half-written (ADR-0090). An
autosave passes clear_dirty=False, since labels.h5 is still behind.
Source code in src/deeperfly/labels/store.py
Ground-truth 2D labels for one project, and their labels.h5 file.
Labels is sparse (ADR-0026): a frame -> (V, K, 2)
map in memory, COO arrays in HDF5. Beside the pixel an operator authors hidden, a
per-cell flag that only excludes the cell from the loss, and absent, a per-frame
declaration that a keypoint is not on this animal, which masks it at read time without
destroying the pixels. Every cell is keyed by an instance slot, 0 being the one animal
of a single-fly project. A file records the names and frame count it was written
against, and load_labels remaps a reordering and
refuses a file whose views or keypoints are gone.
Labels ¶
Sparse per-(view, frame, keypoint) 2D ground truth for one project.
The V and K axes are positional, in the rig's and skeleton's order; an
unlabeled cell is NaN, and dirty tracks unsaved edits. Every accessor takes a
keyword-only instance, slot 0 by default.
Source code in src/deeperfly/labels/store.py
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
__init__ ¶
An empty label set over the given views, keypoints and frame count.
Source code in src/deeperfly/labels/store.py
absent_frame ¶
The (K,) absent mask for frame t (all False if none).
Source code in src/deeperfly/labels/store.py
absent_keypoint ¶
One keypoint's per-frame absent mask over every frame.
Source code in src/deeperfly/labels/store.py
changed_frames ¶
The frames whose authored state differs from other's, sorted.
A pixel, a hidden flag or an absent declaration of any instance counts; an empty cell and a cleared one are the same. The two sets share their shape.
Source code in src/deeperfly/labels/store.py
clear_instance ¶
Forget what one instance holds in one frame: points, flags, absences.
Source code in src/deeperfly/labels/store.py
clear_point ¶
Remove the label of one (view, frame, keypoint) cell, if any.
Source code in src/deeperfly/labels/store.py
frame ¶
The (V, K, 2) labels of one instance of frame t, all NaN if none.
Source code in src/deeperfly/labels/store.py
frame_effective ¶
The frame's GT with absent keypoints masked to NaN -- what the solve sees.
Source code in src/deeperfly/labels/store.py
frame_instances ¶
Every instance slot that holds anything in frame t, sorted.
A pixel, a hidden flag or an absent declaration counts, unlike
labeled_instances, which takes pixels only.
Source code in src/deeperfly/labels/store.py
hidden_frame ¶
The (V, K) hidden mask for frame t (all False if none).
Source code in src/deeperfly/labels/store.py
is_absent ¶
Whether a keypoint is declared not-on-this-animal in frame t.
Source code in src/deeperfly/labels/store.py
label_counts ¶
How many (view, keypoint) cells each of labeled_frames carries.
Source code in src/deeperfly/labels/store.py
labeled_frames ¶
Frame indices that carry a labeled point, sorted, each once.
labeled_instances ¶
The instance slots labeled in frame t, sorted (sparse track ids).
Source code in src/deeperfly/labels/store.py
open_keypoints ¶
How many keypoints each of labeled_frames still lacks to be complete.
A frame is complete (0) when every non-absent keypoint of each labeled
instance has at least min_views clicked views (ADR-0102). Counted per
instance, so a second animal with nothing clicked is not owed; one with a
single click owes its other keypoints.
Source code in src/deeperfly/labels/store.py
set_absent ¶
Declare a keypoint absent (or present again) in one frame.
Source code in src/deeperfly/labels/store.py
set_absent_every_frame ¶
Declare a keypoint absent (or present) in every frame.
Source code in src/deeperfly/labels/store.py
set_absent_keypoint ¶
Replace one keypoint's per-frame absent flags with a whole (T,) mask.
The general form of set_absent_every_frame, so an undo can put back any
pattern.
Source code in src/deeperfly/labels/store.py
set_hidden ¶
set_hidden(
view: int,
frame: int,
keypoint: int,
value: bool = True,
*,
instance: int = 0,
) -> None
Set or clear the hidden (exclude-from-loss) flag of one cell.
Source code in src/deeperfly/labels/store.py
set_point ¶
Set the labeled pixel of one (view, frame, keypoint) cell.
Source code in src/deeperfly/labels/store.py
to_coo ¶
The authored state as flat COO arrays for persistence.
Positions ride view/frame/keypoint/xy, hidden cells the hidden_*
triples, and absence half-open spans per keypoint
(absent_keypoint/absent_start/absent_end); each carries its instance
slot, which save_labels leaves out when only slot 0 is named. Rows are in
(frame, instance) order.
Source code in src/deeperfly/labels/store.py
count_complete_frames ¶
How many frames of a labels.h5 are complete (ADR-0102), from its columns.
count_frames ¶
How many frames a labels.h5 labels, and how many of them are complete.
Complete by the same rule as Labels.open_keypoints returning 0 (ADR-0102),
without a project, video or Labels object: only the sparse click and
absent-range columns are read, in one open of the file.
Source code in src/deeperfly/labels/store.py
count_labeled_frames ¶
How many frames a labels.h5 labels, reading only its frame index.
Nothing is checked against a project, so every project of a collection can be summarized at once.
Source code in src/deeperfly/labels/store.py
load_labels ¶
load_labels(
path: str | Path,
*,
view_names: tuple[str, ...],
keypoint_names: tuple[str, ...],
n_frames: int,
) -> Labels
Load a labels.h5, checked and remapped against the current project.
A pure reordering of the views or keypoints is absorbed.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a stored view or keypoint no longer exists, the frame count shrank below a labeled frame, or the format version is unknown. |
Source code in src/deeperfly/labels/store.py
name_positions ¶
The index of each of names in among, matched by name.
Source code in src/deeperfly/labels/store.py
reindex_keypoints ¶
A copy of labels with its keypoint axis remapped by name to a new order.
Added keypoints get no labels. The instance slot, the hidden flags and the absent declarations are remapped as the points are; one on a dropped keypoint goes with it; the caller refuses any drop that would strand a label.
Source code in src/deeperfly/labels/store.py
save_labels ¶
Write a label set to a labels.h5, clearing its dirty flag unless told not to.
The file is replaced whole, so a reader never sees it half-written (ADR-0090). An
autosave passes clear_dirty=False, since labels.h5 is still behind.
Source code in src/deeperfly/labels/store.py
stored_n_frames ¶
The frame count a labels.h5 was written against, read from its attributes.
What a whole-file rewrite (a renamed view, a new skeleton) reloads it with, so no video is opened.
Source code in src/deeperfly/labels/store.py
A project's label files: labels.h5 and its recovery sidecar.
LabelFiles carries the directory with the key a
set is checked against (the views, the skeleton's points, the frame count); the two
lookups that need no key are functions over the directory. The sidecar,
labels.autosave.h5, is written after each GUI edit and deleted on a save, and while
it is at least as new as labels.h5 the labels load from it, marked dirty. A discard
sets the unsaved labels aside as labels.discarded.h5, which a restore puts back
until an edit or a save makes it stale (ADR-0120).
LabelFiles
dataclass
¶
One project's label files, keyed to the project they are read against.
Attributes:
| Name | Type | Description |
|---|---|---|
directory |
Path
|
The project folder holding the files, whether or not it exists yet. |
view_names |
tuple[str, ...]
|
The project's views, in order. |
keypoint_names |
tuple[str, ...]
|
The skeleton's points, in order. |
n_frames |
int
|
The project's frame count. |
Source code in src/deeperfly/labels/files.py
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
discarded_path
property
¶
Where the labels the last discard threw away are kept (ADR-0120).
autosave ¶
Write in-progress labels to the recovery sidecar, keeping them dirty.
A discard kept from before is stale now: restoring it would drop this edit.
Source code in src/deeperfly/labels/files.py
discard_unsaved ¶
Set the unsaved labels aside and reload the saved ones.
labels are the unsaved ones, an open session's; without them the sidecar is
what is set aside. Either way it lands at discarded_path, for
restore_discarded.
Source code in src/deeperfly/labels/files.py
load ¶
open ¶
The labels for editing and whether they came from the recovery sidecar.
Recovered labels load dirty, so the operator saves or discards them.
Source code in src/deeperfly/labels/files.py
restore_discarded ¶
Put what the last discard set aside back as the sidecar; whether there was.
It is touched as it lands, so the labels load from it again, dirty.
Source code in src/deeperfly/labels/files.py
save ¶
Persist the labels to labels.h5, clearing the sidecar and any discard.
Source code in src/deeperfly/labels/files.py
label_summary ¶
A project's labeled and complete (ADR-0102) frame counts, and its unsaved.
From one open of the file open would read; unsaved says it is the sidecar.
Source code in src/deeperfly/labels/files.py
labeled_frame_count ¶
How many frames a project has labels for, from the file open would read.
labels_source ¶
The file a project's labels come from, and whether it is the sidecar.
Source code in src/deeperfly/labels/files.py
A project's detections: its runs' pose2d, merged per frame by precedence.
Every run under the project's results/ is a source (ADR-0083). Per frame the winner
is the run written last among those whose pose2d covers it, a tie in written going
to the name that sorts last; where the manifest's [detections] runs lists runs, the
winner is the first listed run covering the frame, and a run left off the list is not
a source. One frame's points, conf, crops and track flags come from the winner,
read on demand, in the caller's view and keypoint order.
detections = Detections.open(
project, view_names=views, keypoint_names=names, n_frames=n_frames
)
points, conf = detections.frame(120) # (V, K, 2), (V, K), or (None, None)
A file that is not a readable results file, is of another format, or was run on another
recording, another skeleton or another set of views is listed in runs with usable
false and why, and logged, never raised. A same-set other-order skeleton or view
list is remapped by name.
Readers open without HDF5's file lock (Results.open in mode "r"), so a run that
deeperfly run holds open in another process is read when it is consistent. Every
request revalidates against signature(), the (path, mtime_ns, size) of each
results file, and reinspects the runs that changed; a read that fails there yields
(None, None) and a runs_error, never an exception. The files are listed again at
most every RELIST_SECONDS (ADR-0141), so another process's write is seen within that.
In one process HDF5 refuses to open a file twice with different locking flags, so a
writer in the same process as a held reader proceeds by release(name), then
Results.open(path, "r+"), the write and its close; the write changes the signature,
and the release has the next request list the files at once, so it reopens the run.
Such a writer holds lock over that whole sequence: every method that touches a
reader takes it too, so a request in another thread waits for the write instead of
reopening the run under it (which would refuse the writer's open).
Detections ¶
A project's merged detections, served one frame at a time.
Holds one reader per usable run for the session; winner, runs, empty and
n_animals are as of the last revalidation, which every request makes. lock,
reentrant, serializes the readers across threads; a writer in this process holds
it from release to its close (see the module).
Source code in src/deeperfly/labels/detections.py
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | |
built
property
¶
The signature() the runs were last built from, which lists no file.
What a cache of something computed from the detections keys on, after a
revalidate.
runs
property
¶
Every results file of the project, usable or not, in path order.
runs_error
property
¶
Why the last request, or a run held open elsewhere, gave no detections.
__init__ ¶
__init__(
project: Project,
*,
view_names: Sequence[str],
keypoint_names: Sequence[str],
n_frames: int,
) -> None
An empty set over the given axes; open builds and fills one.
Source code in src/deeperfly/labels/detections.py
close ¶
covered_frames ¶
crops ¶
The (V, 4) rectangles the winner's detector read frame t through.
None where no run covers the frame, the run stores no crops, or the read
fails.
Source code in src/deeperfly/labels/detections.py
frame ¶
frame(
t: int,
animal: int | None = 0,
*,
min_conf: float = DEFAULT_MIN_CONF,
) -> tuple[np.ndarray, np.ndarray] | tuple[None, None]
One animal's (V, K, 2) pixels and (V, K) confidences at frame t.
animal=None keeps every animal the winner tracked, (N, V, K, 2) and
(N, V, K). A pixel below min_conf is NaN. (None, None) where no run
covers the frame, for an animal the winner did not track, or when the read
fails.
Source code in src/deeperfly/labels/detections.py
is_covered ¶
open
classmethod
¶
open(
project: Project,
*,
view_names: Sequence[str],
keypoint_names: Sequence[str],
n_frames: int,
) -> Detections
The detections of project's runs, in these views, keypoints and frames.
Source code in src/deeperfly/labels/detections.py
read ¶
read(
frames: Sequence[int] | ndarray, animal: int = 0
) -> tuple[
Float[np.ndarray, "V F K 2"], Float[np.ndarray, "V F K"]
]
One animal's pixels (V, F, K, 2) and confidences (V, F, K) at frames.
Unfiltered by confidence; NaN pixels and zero confidence where no run covers a frame, the winner did not track the animal, or its read failed.
Source code in src/deeperfly/labels/detections.py
refresh ¶
Close every reader, list and inspect the runs again, recompute the winner.
Source code in src/deeperfly/labels/detections.py
release ¶
Close one run's reader, reopened by the next request that needs it.
What a writer in this process calls before it opens the run (see the module);
the next revalidate lists the files whatever the time since the last.
Source code in src/deeperfly/labels/detections.py
revalidate ¶
Rebuild what changed, and clear the last request's error.
Only the runs whose (path, mtime_ns, size) moved, or that appeared, are
inspected again; the rest keep their readers, so a run being written costs a
request one reopen, not one per run. The files are listed at most every
RELIST_SECONDS, but a run held open for writing at the last build is retried
at every request until it opens.
Source code in src/deeperfly/labels/detections.py
signature ¶
The (path, mtime_ns, size) of every results file, sorted by path.
Source code in src/deeperfly/labels/detections.py
stale ¶
track_flags ¶
(N, T) int8 tracking flags of the winners, LOST where none covers.
A covered frame of a run that did not track (one animal, no tracker) is
TRACKED, and an animal the winner does not have is LOST.
Source code in src/deeperfly/labels/detections.py
RunInfo
dataclass
¶
One results file of a project, as a source of detections.
covered is the (T,) mask of frames its pose2d wrote, covered_count its sum
and stretches its (start, stop) ranges; written is the run's write time in
whole unix seconds. pose3d_ref names the most refined 3D the run holds
(correction, then smoothing, then pose3d), None without one. A run that
cannot be a source has usable false and says why.
Source code in src/deeperfly/labels/detections.py
find_results ¶
Every run's results file of project, results/**/*.h5, sorted by path.
Runs written elsewhere with --out are not found.
precedence ¶
The (T,) int16 index into runs of each frame's winner, -1 where none.
With the manifest's [detections] runs, the first listed run covering a frame
wins and only listed runs are sources (a listed name with no file is skipped);
otherwise the latest-written covering run wins, the name sorting last breaking a
tie. A run that is not usable never wins.
Source code in src/deeperfly/labels/detections.py
run_name ¶
A results file's run name (nightly/full), None if not under results/.
Which detection slot is which labeled animal, frame by frame (ADR-0128).
A project that labels several animals numbers them twice: the operator numbers the label instances, and a run's tracker numbers its slots, arbitrarily, afresh in every run and possibly switching along a recording. Wherever the two meet (the labeling solve and its guides, the fill of a training target's unclicked views, the joints a suggestion skips), an instance reads the detections of the slot its clicks sit on.
match_slots is that pairing for one frame. A click within MATCH_GATE_PX of a
slot's detection of the same (view, keypoint) cell sits on it and votes for the
slot, the more the nearer, and the instances are assigned to the slots on their
votes. A click farther off votes for nothing: the operator clicks first where the
detector is wrong, so a half-labeled animal's clicks are mostly off its own
detections (ADR-0138). An instance with no vote takes a slot no instance won: its
own number when that one is left, else the lowest left. So in a frame nobody labeled
slot i is instance i, and the skeleton the labeling aid draws for an animal
before its first click is the one that click keeps it on, as does a joint dragged
off it. Only a slot the clicks say is another animal's, over MATCH_SLACK more of
them off its detections than on, is refused, and the labeling aid, which wants a
skeleton to drag, refuses none.
frame_slots ¶
frame_slots(
labels: Labels,
t: int,
detected: Float[ndarray, "S V K 2"],
*,
gate_px: float = MATCH_GATE_PX,
refuse: bool = True,
) -> Int[np.ndarray, " I"]
match_slots of frame t's label instances against the slots' detections.
Covers instances 0 to I - 1, I the larger of the slot count and one past
the highest instance labeled; an instance beyond has no slot. Absent keypoints
are no clicks.
Source code in src/deeperfly/labels/identity.py
instance_frame ¶
instance_frame(
detections: Detections,
labels: Labels,
t: int,
instance: int = 0,
*,
refuse: bool = True,
) -> tuple[np.ndarray, np.ndarray] | tuple[None, None]
The (V, K, 2) pixels and (V, K) confidences of the slot instance matches.
Detections.frame of that slot, a
pixel below its min_conf NaN; (None, None) where no run covers frame t or
no slot is this instance. refuse is as for match_slots.
Source code in src/deeperfly/labels/identity.py
instance_read ¶
instance_read(
detections: Detections,
labels: Labels | None,
frames: Sequence[int] | ndarray,
instance: int = 0,
) -> tuple[
Float[np.ndarray, "V F K 2"], Float[np.ndarray, "V F K"]
]
Detections.read of one instance.
Slot instance wherever no label says otherwise, and at a labeled frame the slot
instance matches there, NaN pixels and zero confidence where none does.
Source code in src/deeperfly/labels/identity.py
match_slots ¶
match_slots(
clicks: Float[ndarray, "I V K 2"],
detected: Float[ndarray, "S V K 2"],
*,
gate_px: float = MATCH_GATE_PX,
refuse: bool = True,
) -> Int[np.ndarray, " I"]
Each label instance's detection slot in one frame, -1 for none.
clicks are the instances' labels and detected the slots' detections, NaN
where none. Of the cells both hold, a click within gate_px of the detection
sits on it and votes for the pair, the more the nearer it sits; the instances
with a vote are assigned by Hungarian assignment on their votes, a tie going to
an instance's own number, and a pair without a vote being no match. The others
take the slots no instance won: their own number where it is left, then the
lowest left.
With refuse, a pair with over MATCH_SLACK more clicks off the detections than
on them is another animal's: its votes do not count, and the instance never takes
that slot, so an instance that every slot left refuses reads none. Without, an
instance keeps a slot whatever its clicks say of it, as long as one is left.
Source code in src/deeperfly/labels/identity.py
run_slots ¶
run_slots(
labels: Labels | None,
frames: Sequence[int] | ndarray,
points: Float[ndarray, "N V F K 2"],
conf: Float[ndarray, "N V F K"],
*,
view_names: Sequence[str],
keypoint_names: Sequence[str],
min_conf: float = DEFAULT_MIN_CONF,
) -> Int[np.ndarray, "N F"]
The slot of a run each label instance reads at each of frames, -1 for none.
Slot i is instance i wherever no label says otherwise; at a labeled frame,
frame_slots on the run's own points there, those under min_conf left
out, as Detections.frame leaves
them. The arrays' views and keypoints are view_names and keypoint_names, met
with the labels' by name.
Source code in src/deeperfly/labels/identity.py
take_slots ¶
Index arr's leading animal axis by label instance, in place.
axis is arr's frame axis; at frame j, index i takes what slot
slots[i, j] held there (run_slots), fill where that is -1.
Source code in src/deeperfly/labels/identity.py
The labeling aid's geometry: the solve behind a reprojected guide, and the checks.
One 3D per keypoint from the labels, the detections and a prior (ADR-0027, ADR-0074), and the checks that flag a label as off. Nothing here knows about a session or HTTP, so the routes of deeperfly.gui.labeling stay thin; deeperfly.labels.suggest is the offline counterpart.
bone_reference ¶
bone_reference(
rig: Rig | None,
skeleton: Skeleton,
labels: Labels,
detections: Detections | None,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]
Each skeleton edge's usual 3D length in a recording: (median, mad, count).
From up to BONE_REF_FRAMES frames of the detections (the frames they cover, for
a project's merged ones), triangulated robustly as the pictorial bone prior is,
else from the labeled frames; NaN where an edge was never measured, empty without
a rig.
Source code in src/deeperfly/labels/check.py
detected_frame ¶
detected_frame(
detections: Detections | None,
labels: Labels,
frame: int,
instance: int = 0,
) -> tuple[np.ndarray | None, np.ndarray | None]
One instance's detector pixels (V, K, 2) and confidences (V, K).
From a project's merged Detections
(ADR-0083), the slot whose detections the instance's clicks sit on
(instance_frame, ADR-0128). No slot
is refused for the clicks that sit off it: the solve's guide is the skeleton the
operator drags into place, and dragging its joints must not take it away
(ADR-0138). NaN where the detector did not fire, absent keypoints masked, and
(None, None) without detections at this frame, or for an instance no slot is.
Source code in src/deeperfly/labels/check.py
detection_precision ¶
Each view's measured precision over a project's detections, (V,).
view_precision over up to
BONE_REF_FRAMES covered frames of every animal, weighted by confidence
(ADR-0129); None without a rig or a covered frame.
Source code in src/deeperfly/labels/check.py
detection_sample ¶
Up to BONE_REF_FRAMES covered frames, spread over the detections, sorted.
The covered frames are first cut to those of at most SAMPLE_CHUNKS chunks of
T_CHUNK frames, taken where evenly spread frames fall, so a sample of a long
recording reads a few dozen chunks rather than one per frame (ADR-0141). Empty
where the detections cover no frame.
Source code in src/deeperfly/labels/check.py
detections_3d ¶
detections_3d(
rig: Rig,
det: ndarray,
conf: ndarray | None,
precision: ndarray | None = None,
) -> tuple[np.ndarray, np.ndarray]
The detections' own 3D per keypoint, (K, 3) NaN where no two views agree.
A confidence-weighted RANSAC, not a least-squares fit (ADR-0074), whose consensus
is voted by the confidences and whose fits weigh each view by its (V,)
precision (detection_precision, ADR-0129); a detection below
DEFAULT_MIN_CONF takes no part, and a keypoint no two views place in depth is
NaN (ADR-0130). Also returns the (V, K) inlier mask.
Source code in src/deeperfly/labels/check.py
epipolar_lines ¶
The source pixel's viewing ray, as a segment in every other view, by name.
Sampled across a band around its closest approach to the world origin, so the segment spans the animal rather than running off to infinity.
Source code in src/deeperfly/labels/check.py
frame_checks ¶
frame_checks(
rig: Rig,
skeleton: Skeleton,
bone_ref: tuple[ndarray, ndarray, ndarray],
gt: ndarray,
) -> dict[str, list]
The label checks of one frame, for the editor to flag (ADR-0074).
label_checks on this frame alone, so a frame's flags are the rows the
project's list holds for it (ADR-0117). outliers are labeled views the consensus
of four or more left out; inconsistent joints whose labeled views do not meet
within CHECK_PX, none to blame; bones edges whose length between two anchors
is off the recording's own distribution, which catches a swap coherent across
every view. gt is the frame's effective (V, K, 2) labels.
Source code in src/deeperfly/labels/check.py
gt_anchor ¶
One keypoint's GT-only 3D anchor, and the (V,) labeled views it rests on.
Two or three labels are triangulated together; four or more take the RANSAC
consensus within CHECK_PX of at least three views (ADR-0074). (None, seen)
below two labels, when nothing triangulates, and when no two labeled views are far
enough from parallel and from opposite to place the point in depth (ADR-0130).
Source code in src/deeperfly/labels/check.py
label_checks ¶
label_checks(
rig: Rig,
skeleton: Skeleton,
bone_ref: tuple[ndarray, ndarray, ndarray],
labels: Labels,
) -> dict
The label checks of every labeled frame at once, worst first (ADR-0102).
Each keypoint with two or more labeled views is anchored by gt_anchor's rule
on the labels alone, with no detections or prior, and every frame is checked in
one batch; frame_checks is the same check on one frame. Returns flags,
{frame, instance, kind, keypoint, view?, views?, residual_px?, edge?, other?,
length?, expected?, ratio?, severity} with kind "outlier", "inconsistent"
or "bone" (severity is the multiple of the threshold the flag exceeds, so
pixels and bone lengths sort together); views and keypoints, {name, n,
median_px, p95_px, max_px} of the labeled cells' reprojection error to their
anchor; and frames_checked.
Source code in src/deeperfly/labels/check.py
prior_3d ¶
prior_3d(
rig: Rig | None,
skeleton: Skeleton,
labels: Labels,
detections: Detections | None,
frame: int,
instance: int = 0,
precision: ndarray | None = None,
) -> tuple[np.ndarray, np.ndarray]
A (K, 3) prior 3D per keypoint (NaN where absent), and which are default pose.
Layered per keypoint (ADR-0074): the skeleton's default pose, overridden by the
nearest earlier frame of this animal that triangulates the keypoint, overridden by
this frame's detections (detections_3d with the views' precision). The (K,)
mask names the keypoints left on the default pose alone, a starting instance rather
than a guide. Absent keypoints are NaN.
Source code in src/deeperfly/labels/check.py
project_all ¶
A (K, 3) pose projected into every view as (V, K, 2) (NaN where none).
Source code in src/deeperfly/labels/check.py
solve_keypoint ¶
solve_keypoint(
rig: Rig,
gt: ndarray,
det: ndarray,
prior: ndarray,
det_conf: ndarray | None = None,
precision: ndarray | None = None,
) -> tuple[np.ndarray | None, str]
One keypoint's 3D from this frame's evidence, and what anchored it.
The cascade of ADR-0027, strongest first: GT views that place the keypoint in depth,
or GT views with detections, give "gt", solved by
triangulate_stabilized
with the detections (else the prior reprojected) as the stabilizer (ADR-0068); GT
views and a prior give "ray", the prior slid onto a label's ray; two or more
detected views give "detected" (detections_3d); the prior alone gives
"prior"; nothing gives (None, "none"). GT views that look along one line, such
as a ventral and a dorsal label, fix the keypoint across that line only, so its
depth comes from what follows them (ADR-0130). gt, det are (V, 2) and prior
(3,), NaN where missing; det_conf drops the detections below DEFAULT_MIN_CONF,
votes in the consensus solves and weighs their fits with the views' (V,)
precision (ADR-0129).
Source code in src/deeperfly/labels/check.py
Label suggestions: the joints of a project a label would most likely fix.
Every (view, frame, keypoint) cell of the detector's 2D is scored by its residual
against the other views' RANSAC consensus, in units of the project's typical
residual; a joint takes its worst view, boosted by its drivers (the views disagree, a
bone off its usual length, a detection off the image, a view's sides exchanged), and
picks are whole frames ranked by the evidence their suspicious joints carry
(ADR-0073). suggest_sample is the cold start, whole frames spread over the unlabeled
part. The GUI's Suggested panel writes a project's suggestions.json and walks it
(ADR-0084).
BONE_MIN_SAMPLES
module-attribute
¶
Frames a bone must be measured in before its usual length counts (ADR-0074).
BONE_RATIO
module-attribute
¶
A bone longer or shorter than its usual length by this factor is a driver.
GATE_PX
module-attribute
¶
RANSAC inlier gate, in view pixels: the consensus a view must fall within.
MIN_SCORE
module-attribute
¶
A joint at or above this many typical residuals is suspicious and gets listed.
PER_FRAME
module-attribute
¶
Joints a picked frame lists at most: a labeling stop, not the whole budget.
SIDES_MARGIN
module-attribute
¶
Typical residuals a view's mirrored fit must win by to call its sides exchanged.
CellEvidence
dataclass
¶
What a run's 2D says about each (view, frame, keypoint) cell.
residual is in pixels against the consensus (or a run's 3D), NaN without a
detection or a reference, and at least the gate where no two views agree.
inlier marks the views the consensus kept and off_frame a detection outside
its image; bone_ratio and bone_edge are, per joint, the bone that strays
farthest from its usual length, and sides_exchanged marks a (view, frame)
whose paired joints fit the others better mirrored.
Source code in src/deeperfly/labels/suggest.py
FlaggedView
dataclass
¶
One view a suggestion says to look at, with the numbers behind it.
score is the residual in typical residuals; rejected says the consensus left
the view out, off_frame that its detection lies outside its image.
Source code in src/deeperfly/labels/suggest.py
Ranked
dataclass
¶
A project's picks, best first, with the ranking's stats for the document.
Source code in src/deeperfly/labels/suggest.py
Suggestion
dataclass
¶
One joint to label: a frame, a keypoint, the views that make the case, and why.
score is the worst view's, boosted by the drivers; keypoint=None is a whole
frame to label, naming no views. instance is the animal the pick is about.
Source code in src/deeperfly/labels/suggest.py
cell_evidence ¶
cell_evidence(
rig: Rig,
points: Float[ndarray, "V T K 2"],
conf: Float[ndarray, "V T K"],
*,
sizes: Sequence[tuple[int, int] | None] | None = None,
pts3d: Float[ndarray, "T K 3"] | None = None,
edges: Int[ndarray, "E 2"] | None = None,
flip_perm: Int[ndarray, " K"] | None = None,
gate_px: float = GATE_PX,
sides_margin: float = SIDES_MARGIN,
) -> CellEvidence
Triangulate the 2D by consensus and measure every cell against it.
sizes (per view (height, width)), edges and flip_perm enable the off-frame,
bone and exchanged-sides drivers, each skipped when None; pts3d replaces the
consensus as the residuals' reference where it is finite, though the consensus
still decides which views agree.
Source code in src/deeperfly/labels/suggest.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
labeled_joints ¶
labeled_joints(
labels: Labels,
n_frames: int,
keypoints: Sequence[str],
*,
instance: int = 0,
) -> Bool[np.ndarray, "T K"]
(T, K): one animal's joints that carry a label in any view or an absent mark.
Matched by name, so a run made before a skeleton edit still lines up.
Source code in src/deeperfly/labels/suggest.py
read_suggestions ¶
Read a suggestions document of the current format, FORMAT_VERSION.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file is not a suggestions document, or one of another format version, which is refused rather than migrated (ADR-0061): suggesting again rewrites it. |
Source code in src/deeperfly/labels/suggest.py
results_source ¶
The provenance a document records for picks scored from a run's results.
Source code in src/deeperfly/labels/suggest.py
score_cells ¶
Per-cell scores: the residual in typical residuals, NaN without a residual.
score_joints ¶
score_joints(
evidence: CellEvidence,
cells: Float[ndarray, "V T K"] | None = None,
*,
disagree_boost: float = DISAGREE_BOOST,
bone_boost: float = BONE_BOOST,
off_frame_boost: float = OFF_FRAME_BOOST,
) -> Float[np.ndarray, "T K"]
Per-joint scores: the worst view's cell score times the drivers' boosts.
NaN below two detections, so such a joint is never suggested.
Source code in src/deeperfly/labels/suggest.py
select_frames ¶
select_frames(
joint: Float[ndarray, "T K"],
*,
labeled: Bool[ndarray, "T K"] | None = None,
frames: Sequence[int] | ndarray | None = None,
count: int = 100,
gap: int = 0,
min_score: float = MIN_SCORE,
per_frame: int = PER_FRAME,
) -> list[tuple[int, list[int]]]
Rows to label, best first, each with its suspicious joints, best first.
A joint is suspicious at or above min_score, labeled ones never. A row's evidence
is sum(log2(score)) over the per_frame joints it would list, each weighted
1 / (1 + n) by how often its keypoint was picked; rows are taken greedily, no two
within gap frames (frames maps rows to recording frames), until count joints
are listed. Returns (row, keypoint indices) pairs.
Source code in src/deeperfly/labels/suggest.py
suggest_detections ¶
suggest_detections(
rig: Rig,
detections: Detections,
labels: Labels | None = None,
*,
sizes: Sequence[tuple[int, int] | None] | None = None,
edges: Int[ndarray, "E 2"] | None = None,
flip_perm: Int[ndarray, " K"] | None = None,
count: int = 100,
gap: int = 0,
min_score: float = MIN_SCORE,
per_frame: int = PER_FRAME,
gate_px: float = GATE_PX,
) -> Ranked
The suggestions of one project from its runs' merged detections (ADR-0083).
Only the frames the detections cover are scored, each from its winning run, and
residuals are against the views' consensus, never a run's 3D; several animals
are ranked one at a time and merged, each label instance from the slot its
clicks sit on (instance_read,
ADR-0128). The arguments are as for suggest_points.
Source code in src/deeperfly/labels/suggest.py
suggest_points ¶
suggest_points(
rig: Rig,
points: Float[ndarray, "V T K 2"],
conf: Float[ndarray, "V T K"],
*,
keypoints: Sequence[str],
labels: Labels | None = None,
sizes: Sequence[tuple[int, int] | None] | None = None,
frames: Sequence[int] | ndarray | None = None,
pts3d: Float[ndarray, "T K 3"] | None = None,
edges: Int[ndarray, "E 2"] | None = None,
flip_perm: Int[ndarray, " K"] | None = None,
count: int = 100,
gap: int = 0,
min_score: float = MIN_SCORE,
per_frame: int = PER_FRAME,
gate_px: float = GATE_PX,
instance: int = 0,
) -> Ranked
Rank the joints of one animal's 2D (ADR-0073).
points (V, T, K, 2) is the detector's 2D over the frames scored, keypoints
the names along K, and frames the recording frame of each T index. labels
are skipped, pts3d replaces the consensus as the reference, and sizes,
edges and flip_perm enable the drivers as for cell_evidence; the rest are
select_frames' knobs. Every pick is tagged with instance, and only that
animal's labels are skipped.
Source code in src/deeperfly/labels/suggest.py
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | |
suggest_results ¶
suggest_results(
res: Results,
labels: Labels | None = None,
*,
rig: Rig | None = None,
edges: Int[ndarray, "E 2"] | None = None,
flip_perm: Int[ndarray, " K"] | None = None,
count: int = 100,
gap: int = 0,
min_score: float = MIN_SCORE,
per_frame: int = PER_FRAME,
gate_px: float = GATE_PX,
) -> Ranked
The suggestions of one project, from its run's pose2d (and pose3d).
Only the frames pose2d covers are scored (ADR-0082). The residuals are against
pose3d/points on the frames pose3d covers, else against the views' consensus,
and several tracked animals are ranked one at a time and merged, each label
instance from the slot its clicks sit on
(run_slots, ADR-0128). The views are
the run's own when it stores them, else rig's, taken by name in the run's view
order: a pose2d-only run of one animal stores none (ADR-0086). The file's frame
sizes drive the off-frame driver; edges and flip_perm index the run's
keypoints; the other arguments are as for suggest_points.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the results have no 2D stage, or store no views and |
Source code in src/deeperfly/labels/suggest.py
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | |
suggest_sample ¶
suggest_sample(
n_frames: int,
labels: Labels | None = None,
*,
count: int = 100,
) -> list[Suggestion]
count whole frames spread over the unlabeled part of the recording.
Farthest-first from every labeled frame, so however few get labeled they cover
the recording; score is the distance to the nearest covered frame when picked, as
a fraction of the recording.
Source code in src/deeperfly/labels/suggest.py
to_document ¶
to_document(
project: str,
suggestions: list[Suggestion],
*,
source: dict[str, Any],
params: dict[str, Any],
stats: dict[str, Any] | None = None,
) -> dict[str, Any]
The suggestions.json document: provenance, parameters, stats and the picks.
Source code in src/deeperfly/labels/suggest.py
write_run_suggestions ¶
write_run_suggestions(
results_path: str | Path,
labels: Labels,
skeleton,
*,
project: str,
target: str | Path,
count: int = 100,
gap: int = 20,
min_score: float = MIN_SCORE,
per_frame: int = PER_FRAME,
) -> Ranked
Score a run's results against a project's labels; write its suggestions.json.
suggest_results on results_path,
written to target with its source and parameters.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the results hold no |
Source code in src/deeperfly/labels/suggest.py
write_suggestions ¶
Write a suggestions document as JSON, creating the directory.