Repository navigation
Keep a fixed list of occurrences as a set, and make one from the occurrences page - #1492
Draft
mohamedelabbas1996 wants to merge 5 commits into
Draft
mohamedelabbas1996 wants to merge 5 commits into
mohamedelabbas1996 wants to merge 5 commits into
Conversation
A project needs the same occurrences again later: comparing two classifiers only means something if both saw the same rows, and a review pass wants the list it started from. A filter answers differently as data arrives, so the membership is stored rather than described. An OccurrenceSet holds its occurrences and the projects it belongs to. A set with no project is global and is offered everywhere, following how TaxaList already treats a list with no project. Membership is decided when the set is created and nothing adds to or removes from one afterwards, because anything recorded against a set was measured on exactly those occurrences. Creating, renaming and deleting are gated on new project permissions, held by the roles that already curate a project's data. A global set has no single project to check against, so it cannot be edited through the API at all. The occurrence list takes an occurrence_set filter, and the sets are offered as choices the same way capture sets are.
Adds the occurrence set to the occurrence filter panel, picked from the set choices endpoint the same way a capture set is. A set is only useful if you can look at what is in it, and this is where someone reviewing one starts. The field is carried over from other views like the existing filters, so arriving with a set already chosen shows it in the panel where it can be cleared.
Someone filtering the occurrence list to the rows they care about had no way to keep that selection. Selecting occurrences now offers saving them as a set, next to the identification actions already there. The action does not change any occurrence, so it is not behind update rights on them; the endpoint gates it on the project's own permission instead.
Registering a filter in the shared list is not enough for it to appear: the occurrences page renders one FilterControl per field it offers, and the set was missing from that list, so the filter existed everywhere except on screen. It sits under More filters beside the capture set, and that section now opens on arrival when a set is already applied, as it does for the other filters there.
The selection bar holds identification actions and is hidden from anyone without update rights on the occurrences, so saving a set — which changes none of them — was unavailable to a reader who could still create one. It also sat there as an unlabelled icon among three others. It now sits beside Export as a labelled button, and appears only while something is selected, since that is the only time it does anything.
✅ Deploy Preview for antenna-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for antenna-ssec canceled.
|
mohamedelabbas1996
force-pushed
the
feat/occurrence-sets
branch
from
October 8, 2026 21:19
cf617ad to
c731d37
Compare
mihow
added this pull request to stack #1498
October 8, 2026 21:52
Collaborator
|
Great work!
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
A project needs the same occurrences again later: comparing two classifiers only means
something if both saw the same rows, and a review pass wants the list it started from.
Describing that list as a filter answers differently as data arrives, so this stores the
membership instead.
An occurrence set is a fixed list of occurrences. It is created from the occurrences
page — select some rows, save them as a set — and the occurrence list can then be filtered
back down to it. Membership is decided when the set is created and nothing adds to or
removes from one afterwards.
This is split out of #1407, where sets are what a classifier is scored against. Nothing
here depends on that work, and scoring is not included.
List of Changes
OccurrenceSetinami/main/models.py: occurrences and projects,for_project()andvisible_for_user()scoping; a set with no project is global, asTaxaListalready doescreate_occurrenceset/update_/delete_onProject.Permissions, held byMLDataManager(and soProjectManager); object-level backfill for existing projects in0099occurrence_idsis write-only and refused on update; noPUT, which would carry the occurrencesOccurrenceSet.get_project()returns the first project, andBaseModel.check_permissionrefuses every action without oneoccurrence_setonOccurrenceFilterSet, mapped to theevaluation_setsreverse relationchoicesaction onOccurrenceSetViewSet, followingSourceImageCollectionViewSet.choicesoccurrence-set-filter.tsx+ filter registry, dispatch and carry-over list, built like the capture-set filtercreate-occurrence-setpopover beside Export, built likesuggest-id;useCreateOccurrenceSethookScreenshots
The occurrences page as it is today. Nothing is selected, so there is nothing to save.
Selecting rows reveals Create set in the toolbar, beside Export. It is only there while
something is selected, because that is the only time it does anything.
Naming the set. The line under the field says how many occurrences it will hold and that
the contents will not change afterwards.
The set then appears in the occurrence filters, under More filters beside Capture set.
Choosing it narrows the list to exactly the occurrences the set holds.
Related Issues
Split out of #1407 (retraining and scoring). The scoring side will consume these sets.
Detailed Description
on exactly those occurrences. A set that grows quietly makes an old number mean something
different, with nothing on screen to say so.
object exists yet; everything else goes through the object check. Saving a set changes no
occurrence, so it is not behind update rights on them — which is why the button sits in
the toolbar rather than in the selection bar, where the identification actions live.
ami/tests/fixtures/.create_capturestimes its images from
datetime.now(), and event grouping reads image dimensions fromstorage. Neither is deterministic in a test, so occurrences built that way made unrelated
assertions fail at random, differently each run.
make_occurrencein the test file buildsthe detection and determination the list endpoint needs. This is a deviation from
canonical-patterns.mdand worth a look.Testing
ami.main.test_occurrence_sets— 16 tests, stable across repeated runs: creating,permissions, membership immutability, global sets, listing scope, and the filter.
until rows are selected, the popover refuses an empty name, the set saves with exactly the
rows chosen, the filter narrows the list to them, and another project cannot see the set.