spacr.qt.dnd_handlers¶
Per-module drop handlers.
Each pipeline app has different expectations for what a “source”
means. This module encodes those policies as DropHandler
subclasses that the AppScreen wires up at construction time.
Handler map (also read by get_handler):
App |
Accepts |
|---|---|
mask measure external_masks annotate classify make_masks map_barcodes umap ml_analyze regression recruitment activation analyze_plaques train_cellpose cellpose_masks cellpose_all other modules |
folder w/ images (auto-parses regex + preview)
folder named |
Every handler falls back to CSV settings-import via spacr.qt.dnd
so users can also drop a settings CSV on any screen to load it.
Classes¶
Use a dropped image folder (or one tile) as Align & Stitch input. |
|
Accept a plate folder with |
|
Load queue files or add dropped settings snapshots as jobs. |
|
Accept one folder with images, for the Cellpose training screens. |
|
Accept a plate folder with |
|
Prediction Profiler: the regression coefficients under |
|
Use a dropped microscopy container or folder as converter input. |
|
Set the project in Data Manager, then measure it. |
|
Open a dropped measurements database in the Database Browser. |
|
Classifier Evaluation: the run folder holding the evaluation bundle. |
|
Fill Explain CV's database or prediction input from one drop. |
|
Append mixed intensity images and external label masks to the mapper. |
|
Populate Import Project from image folders, tables and mapping files. |
|
Image-folder input shared by Model Compare. |
|
Point Import Images at a dropped folder, or at a file's folder. |
|
Fill Investigate Hit's provenance inputs without guessing a hit. |
|
Curate and Napari Bridge: one label mask, from wherever you drop. |
|
Layer Viewer: the dropped array, added as an image or as labels. |
|
Drop policy for a screen that names what it wants, not where it is. |
|
Lineage: a database path field and one load. |
|
Accept image files, folders of images, or both; one drop, one queue. |
|
Accept a FASTQ file ( |
|
Accept a folder of raw microscopy images and preview its filename |
|
Accept the |
|
Accept a database, its measurements folder, or its plate folder. |
|
Methods & Results: fill whichever of its four source fields fits. |
|
Scan checkpoints, or use image-only folders as benchmark fields. |
|
Plaque Assay's own drop policy and its own words. |
|
Queue plate folders that carry spaCR settings snapshots. |
|
A screen that takes a whole project, wherever inside it you drop. |
|
Project Browser: several folders at once, each becoming a root. |
|
Regression's drop: a database to a plate row, CSVs to the sweep card. |
|
Accept a completed spaCR run folder and scan its report inputs. |
|
Database input for Plate Viewer and Annotator Agreement. |
|
Hit List: the |
|
Run History: select the run a dropped run folder belongs to. |
|
Image Scatter: a path field, a table picker, then the read. |
|
General source-path policy for modules without a narrower contract. |
|
Distributed Jobs: a settings snapshot to submit, or the plate with one. |
|
Route dropped CSVs into Parameter Sweep's score and count lists. |
|
A screen that reads one table: the explorers, the plotters, the gates. |
|
Accept a directory and asynchronously scan it for training runs. |
Functions¶
|
How many folder-scan threads |
|
Drop every cached drop decision, so the next one asks again. |
|
Return a fresh DropHandler for |
|
What a drop or a |
|
How many dropped files Plaque Assay leaves aside. |
|
A folder that lists the dropped plaque images, without copying them. |
|
Walk a dropped folder ONCE and return the folder-metadata report. |
|
True while a dropped folder is still being walked for |
|
Read a dropped container's header and plan its extraction. Worker-safe. |
|
Everything a mask drop asks the filesystem about one path. Worker-safe. |
|
List the top level of a dropped folder once. Worker-safe. |
|
Return the tables in a SQLite file, or |
Module Contents¶
- class spacr.qt.dnd_handlers.AlignDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerUse a dropped image folder (or one tile) as Align & Stitch input.
- apply(path: pathlib.Path, screen) None[source]¶
Point
srcat the folder. A dropped FILE gives its parent, because stitching one tile is not a thing you can ask for.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A folder holding image tiles, or one tile file.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name the unit Align works in: a folder of tiles, not one image.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.AnnotateDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a plate folder with
measurements/measurements.dbor the .db file itself.- apply(path: pathlib.Path, screen) None[source]¶
Resolve a dropped database to the plate folder that owns it.
TWO LEVELS UP, BUT ONLY FROM
measurements/. The canonical layout is<plate>/measurements/measurements.db, so climbing two levels finds the plate – butcan_acceptalso allows a loosedb, and climbing blindly from one of those would name a folder that has nothing to do with it.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A
dbfile, or a plate folder holding measurements/measurements.db.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name the file’s path AND which module writes it, so a user who has not run Measure yet learns what is missing rather than that they are wrong.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.BatchDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerLoad queue files or add dropped settings snapshots as jobs.
- accepts_multiple() bool[source]¶
Yes: a batch is many jobs, so many drops is the natural gesture.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Load a saved queue, or add each settings snapshot as a job.
A QUEUE REPLACES, SNAPSHOTS ADD. A JSON or YAML file IS the queue and loading it is the whole gesture; a CSV or a folder contributes jobs to the queue that is already there.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A saved queue, a settings CSV, or a folder of settings snapshots.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name all three shapes; only the first is guessable from the name.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.CellposeFolderDropHandler[source]¶
Bases:
MakeMasksDropHandlerAccept one folder with images, for the Cellpose training screens.
Their
srcis a folder the run lists, so a file is refused here even though Make Masks itself takes one.- apply_all(paths: Sequence[pathlib.Path], screen) bool[source]¶
Decline: each folder is set as
srcbyapply().- Parameters:
paths – the accepted folders.
screen – the screen to wire the drop into.
- Returns:
False.
- can_accept(path: pathlib.Path) bool[source]¶
A folder with images in it.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
The sentence the Cellpose screens have always shown.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ClassifyDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a plate folder with
measurements/measurements.dbor a folder produced by the annotate step.- apply(path: pathlib.Path, screen) None[source]¶
Add the plate to
src, which Classify holds as a LIST.APPENDED, NOT REPLACED. Classify compares plates, so a second drop that overwrote the first would make the comparison impossible to set up by the gesture the rest of the application uses for it.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A plate folder holding measurements, crops, or a training set.
THREE SHAPES BECAUSE THERE ARE TWO WORKFLOWS. Classify trains on measured features or on image crops, and the crops arrive either as
data/from Measure or astrain/from Annotate.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name all three layouts, since which one you have depends on which route through the application you took.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.CoefficientsDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerPrediction Profiler: the regression coefficients under
results/.Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- deliver(screen, value: str, target) None[source]¶
Find the coefficients CSV the regression wrote, and load it.
A folder is searched rather than refused, because
results/is what a user has to hand and the file inside it has a name they did not choose and have no reason to remember.- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.ConvertDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerUse a dropped microscopy container or folder as converter input.
- apply(path: pathlib.Path, screen) None[source]¶
Set the source, normalising a dropped file to its folder.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, or one microscopy container or image file.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name the container formats, because a user with an ND2 will not recognise themselves in the word ‘image’.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.DataManagerDropHandler(app_key: str = '')[source]¶
Bases:
ProjectFolderDropHandlerSet the project in Data Manager, then measure it.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- deliver(screen, value: str, target) None[source]¶
Set the project, then measure it.
The scan is the reason to drop a folder here at all, so it follows the set rather than waiting for a second gesture.
- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.DatabaseDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerOpen a dropped measurements database in the Database Browser.
- apply(path: pathlib.Path, screen) None[source]¶
Open the database, raising the screen’s own reason if it refuses.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Delegated, so the Browser and the measurement screens cannot disagree about what counts as a database.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name all three accepted shapes in the Browser’s own words.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.EvaluationBundleDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerClassifier Evaluation: the run folder holding the evaluation bundle.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- apply(path: pathlib.Path, screen) None[source]¶
Prefer what the vocabulary resolved; fall back to the folder dropped.
The fallback matters: a run folder that the vocabulary cannot place is still the folder the user meant, and scanning it is more useful than refusing it.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A folder, or a file the vocabulary reads as a bundle directly.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- class spacr.qt.dnd_handlers.ExplainCvInputsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerFill Explain CV’s database or prediction input from one drop.
- accepts_multiple() bool[source]¶
Yes: the database and the predictions are two files, dropped together.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Place
pathin Explain CV’s database or prediction control.- Parameters:
path – accepted database, project directory, or prediction CSV.
screen – host screen exposing the
explaininput panel.
- can_accept(path: pathlib.Path) bool[source]¶
Return whether
pathis an Explain CV database or CSV input.- Parameters:
path – database, project directory, or prediction CSV to test.
- error_message(path: pathlib.Path) str[source]¶
Explain why
pathis not an Explain CV input.- Parameters:
path – rejected file or directory.
- class spacr.qt.dnd_handlers.ExternalMasksDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAppend mixed intensity images and external label masks to the mapper.
- accepts_multiple() bool[source]¶
Yes: images and their masks are separate files and arrive together.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Append to the inputs list, and refuse loudly if the screen has none.
APPEND, NOT REPLACE. The mapper pairs images with masks, so a drop that replaced the list would undo the pairing the previous drop just contributed to.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, or an image/mask file in a label-bearing raster format.
No distinction between image and mask here: which is which is decided by the mapper the drop feeds, not by the file’s name.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name the raster formats, and say folders work, since a mask set is normally a folder rather than a file.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ForeignProjectDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerPopulate Import Project from image folders, tables and mapping files.
- accepts_multiple() bool[source]¶
Yes: a foreign project is images plus a table plus, often, a mapping.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Route the drop to whichever of the module’s inputs it fits.
A CSV IS READ BEFORE IT IS PLACED. A mapping and a measurement table are both CSVs, and only the header says which – so the header is checked rather than the extension trusted.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, an image, a measurement table, or a JSON mapping.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name all four kinds, because this module’s whole job is that the inputs did not come from spaCR and so have no expected shape.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ImageFieldsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerImage-folder input shared by Model Compare.
- apply(path: pathlib.Path, screen) None[source]¶
Set the source, and raise with the screen’s own reason if it refuses.
The screen knows why it could not read the folder; repeating a generic sentence over the top of that would hide the useful half.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A folder holding microscopy fields, or one field file.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Say ‘fields’, which is the word this module’s screen uses.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ImageImportDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerPoint Import Images at a dropped folder, or at a file’s folder.
A FOLDER IS THE UNIT, and a dropped file is normalised to the one holding it, because the module reads what VARIES ACROSS a folder to work out what the names mean. One file has no variance and would say nothing; the folder it came out of is what the user meant to hand over anyway.
A JSON file is a saved plan, not an acquisition: dropping one reloads the answers from a previous import, which is the gesture that makes next week’s plate one press.
- apply(path: pathlib.Path, screen) None[source]¶
Load a dropped plan, or point the module at the folder.
A
jsonis a saved plan and reloads previous answers; anything else is normalised to its folder, which is the unit the module reads.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, any image file, or a saved import plan.
Wider than the other handlers on purpose: this module is where a folder goes to be UNDERSTOOD, so refusing one for not looking like images yet would refuse the case it exists for.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name all three things it takes, since the third is not guessable.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.InvestigateHitInputsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerFill Investigate Hit’s provenance inputs without guessing a hit.
- accepts_multiple() bool[source]¶
Yes: provenance is assembled from several files, not one.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Route
pathto the matching Investigate Hit control.- Parameters:
path – accepted database, results directory, prediction CSV, or guide-fraction CSV.
screen – host screen exposing the
investigateinput panel.
- can_accept(path: pathlib.Path) bool[source]¶
Return whether
pathcan supply an Investigate Hit input.- Parameters:
path – database, directory, prediction CSV, or fractions CSV to test.
- error_message(path: pathlib.Path) str[source]¶
Explain why
pathis not an Investigate Hit input.- Parameters:
path – rejected file or directory.
- class spacr.qt.dnd_handlers.LabelMaskDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerCurate and Napari Bridge: one label mask, from wherever you drop.
Dropping the project resolves
masks/; a folder of masks is not one mask, so the file is asked for rather than guessed at.Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- deliver(screen, value: str, target) None[source]¶
Resolve the drop to ONE mask and hand it to whichever setter exists.
Curate and the Napari bridge name the act differently; a handler per spelling would be two copies of this policy that could disagree.
- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.LayerStackDropHandler(app_key: str = '')[source]¶
Bases:
LabelMaskDropHandlerLayer Viewer: the dropped array, added as an image or as labels.
A viewer stacks layers, so a multi-drop of an image and its mask lands as two layers rather than as the first one.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- accepts_multiple() bool[source]¶
Yes: a stack is layers, so several files at once is the gesture.
- Returns:
True to be called once per item on a multi-drop.
- deliver(screen, value: str, target) None[source]¶
Add the array as labels or as an image, decided by where it came from.
A file out of
masks/is a label array; anything else is the image it belongs on. Guessing from the pixels instead would be wrong for a binary image and silent about it.- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.LayoutDropHandler(app_key: str = '')[source]¶
Bases:
spacr.qt.dnd.DropHandlerDrop policy for a screen that names what it wants, not where it is.
A subclass says two things: the vocabulary terms it consumes (
kinds, fromspacr.ports.ALL_KINDS) and what to do with the answer (deliver()). Everything between — climbing from the dropped path to the project root, asking the registry, falling back to the declared layout, noticing that the answer is ambiguous — isspacr.chaining.resolve_drop().Ambiguity is routed through the machinery
spacr.qt.dndalready has: an ambiguous drop reportscan_accept() is Falseand returns the candidates fromsuggest_alternatives(), so the user gets the “did you mean…” chooser andapply()is called again with their answer. A drop that resolves to nothing reportsspacr.chaining.DropResolution.reason, which isspacr.ports.check_ready()’s own sentence about what is missing.- Parameters:
app_key – which screen this handler belongs to, for the messages a refused drop shows. Empty falls back to the subclass’s
label, and then to its class name – so a handler always has something to name itself with rather than reporting an empty string to the user.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- apply(path: pathlib.Path, screen) None[source]¶
Deliver a direct hit, or resolve the folder and deliver what it names.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Accept a direct hit, or a folder the vocabulary resolves unambiguously.
AMBIGUOUS IS A REFUSAL, not a guess. A folder that could serve two of the kinds this screen asks for has no right answer here, and picking one would be wrong half the time and silent both times –
suggest_alternativesoffers the choices instead.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- abstract deliver(screen, value: str, target) None[source]¶
Put
valueinto the screen. Runs on the GUI thread.- Parameters:
screen – the screen the drop landed on.
value – the resolved path.
target – the
spacr.chaining.DropTargetit came from, or None for a file the user dropped directly.
- error_message(path: pathlib.Path) str[source]¶
The resolver’s own reason, or a bare refusal when it could not read.
The resolver knows which kind was missing; a generic sentence over the top of that would replace the only informative half.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- resolve(path: pathlib.Path)[source]¶
Return the
spacr.chaining.DropResolutionforpath.- Parameters:
path – dropped path to resolve against this handler’s app and artifact kinds.
- suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]¶
Every path the resolver considered, flattened for the ‘did you mean’ UI.
This is what makes an ambiguous refusal useful rather than a dead end.
- Parameters:
path – the dropped file or folder.
- Returns:
nearby paths that WOULD be accepted.
- class spacr.qt.dnd_handlers.LineageDropHandler(app_key: str = '')[source]¶
Bases:
TableDropHandlerLineage: a database path field and one load.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- class spacr.qt.dnd_handlers.MakeMasksDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept image files, folders of images, or both; one drop, one queue.
- accepts_multiple() bool[source]¶
Several files and folders in one drop make one queue.
- Returns:
True.
- apply(path: pathlib.Path, screen) None[source]¶
Open the one path; a screen without a queue gets it as
src.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- apply_all(paths: Sequence[pathlib.Path], screen) bool[source]¶
Hand the whole drop to Make Masks, which queues it in drop order.
- Parameters:
paths – the accepted files and folders, in drop order.
screen – the screen to wire the drop into.
- Returns:
False for a screen that is not Make Masks, so each path goes through
apply()as a source folder instead.
- can_accept(path: pathlib.Path) bool[source]¶
An image file, a
.npy, or a folder with images or spaCR output.A folder whose images sit only in subfolders, and a folder spaCR wrote (
merged/*.npy,sorted_channels), are taken too, and a.npyso the screen can say what it is;spacr.drop_classification.classify_drop()decides what the drop means. Pairs are found later, not required here.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Say what the images are FOR – fine-tuning Cellpose – because the folder that is right for this module is not the one that is right for segmentation.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]¶
Nearby folders that do hold images, for the ‘did you mean’ prompt.
- Parameters:
path – the dropped file or folder.
- Returns:
nearby paths that WOULD be accepted.
- class spacr.qt.dnd_handlers.MapBarcodesDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a FASTQ file (
.fastq/.fastq.gz) or a folder containing one.- apply(path: pathlib.Path, screen) None[source]¶
Point
srcat the folder and, for a dropped file,fastqat it.TWO FIELDS FROM ONE DROP. Dropping the FASTQ itself is the precise gesture and fills both; dropping the folder leaves the file unset, because which of several reads was meant is not something to guess.
WHICH OF THE TWO IT IS COMES FROM THE NAME, not from a stat. The
is_file()that stood here asked the filesystem a question the filename had already answered – on the GUI thread, immediately aftercan_accepthad asked it too.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A FASTQ file, or a folder holding one.
Stops at the FIRST match rather than listing the folder: a sequencing run can hold thousands of files and the question is only whether there is one.
THE NAME IS ASKED BEFORE THE FILESYSTEM. The usual drop here is a
.fastq.gz, and its name settles it, so the common case touches the disk not at all. Only a folder has to be listed, and that listing waits at mostDECISION_BUDGET_S– dropping a sequencing folder from a sleeping network share is the exact gesture that was reported as “opening map barcodes crashes spacr”.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name both spellings of the extension, since
gzis the common one and looks like a different kind of file.- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.MaskDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a folder of raw microscopy images and preview its filename regex parse. Multi-drop is supported.
- accepts_multiple() bool[source]¶
Yes: several plates segmented in one gesture is the common case.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Set
src, then read the folder and preview its filename parse.The read is on a worker thread and the report renders when it returns, because a plate can hold thousands of names and the drop must not freeze the window while they are counted.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A folder with images at the top level, or one readable image file.
A CONTAINER FILE IS ASKED, NOT ASSUMED.
describe_filedecides whether acziornd2can actually be read, because the suffix says what a file claims to be and the reader says what it is.Answered from
_facts, which is the ONE walk this drop pays for – the question above is exactly whatscan_mask_dropalready settled.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name the formats AND ‘at the top level’, which is the usual miss: a folder of per-well subfolders looks right and is not.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]¶
Nearby folders that DO hold images, for the ‘did you mean’ prompt.
Only for a folder: a file that is not an image has no near miss worth offering, and
scan_mask_dropreturns none for one.Already found by the same scan that rejected the path. Searching the parent and the children for images is a walk of its own, and doing it here meant a rejected drop paid for a second one.
- Parameters:
path – the dropped file or folder.
- Returns:
nearby paths that WOULD be accepted.
- class spacr.qt.dnd_handlers.MeasureDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept the
mergedfolder produced by the mask module, or a parent folder that contains one.- apply(path: pathlib.Path, screen) None[source]¶
Set
srcto the PLATE folder, not tomerged/inside it.ONE STRING FOR ONE PLACE. This used to drill into
merged, while auto-chaining filled the same field with the plate – so dropping a folder and letting the chain fill it produced two different strings for one plate, and settings files written the two ways did not match.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
The
mergedfolder mask produced, a plate folder holding one, or a single mask/image file.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name
mergedexplicitly, and say the plate folder works too.- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]¶
Any
merged/folder one level down, for the ‘did you mean’ prompt.Dropping the plate folder instead of the
mergedinside it is the mistake this exists to catch.- Parameters:
path – the dropped file or folder.
- Returns:
nearby paths that WOULD be accepted.
- class spacr.qt.dnd_handlers.MeasurementsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a database, its measurements folder, or its plate folder.
Where the screen takes its inputs ONE ROW PER PLATE – today only Regression, through the
paired_datatable – the database is attached to a plate row instead of settingsrc. That is not an app-key special case: it follows the shape of the screen, so any panel that grows a per-plate input table gets it without a registry edit.It matters because the two gestures used to disagree. Dropping
measurements.dbon the regression input table attaches it to a plate; dropping the same file two inches higher, on the screen around it, landed here and setsrc– a key the regression panel does not even display. The drop reported success and changed nothing the user could see.- apply(path: pathlib.Path, screen) None[source]¶
Attach the database to a PLATE ROW, not to
src.This screen’s inputs are one row per plate, so the database belongs on the row it describes.
srcis not where its measurements live, and putting it there would leave the row empty and the run without input.- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
The database, the
measurements/folder, or the plate folder above it.All three name the same database, and which one a user has to hand depends on how far into the tree they happened to be looking.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- static database_file(path: pathlib.Path)[source]¶
The database
pathnames: itself, or the one under it.Returns
Nonewhen there is no database file to be found, so a caller can fall back rather than hand a folder to something that expects to open a database.- Parameters:
path – database file, measurements directory, or plate directory to resolve.
- error_message(path: pathlib.Path) str[source]¶
Name the canonical path, which is the one a user can check.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.MethodsSourcesDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerMethods & Results: fill whichever of its four source fields fits.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- accepts_multiple() bool[source]¶
Yes: the four sources are four separate things to drop.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Fill whichever of the four source fields this path fits.
SORTED BY WHAT THE PATH IS, not by drop order, so the same four files land in the same four fields however they are dropped.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Anything on disk: which of the four fields it fills is decided in
apply, from what the path IS rather than from what was dropped.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- class spacr.qt.dnd_handlers.ModelZooDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerScan checkpoints, or use image-only folders as benchmark fields.
- apply(path: pathlib.Path, screen) None[source]¶
Scan checkpoints, or take the folder as benchmark fields.
THE CHEAP ANSWER FIRST. A dropped checkpoint, or one at the top level of the dropped folder, is one directory listing that stops at the first hit – and that is what a real model folder looks like, so the common drop stays fully synchronous.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, a checkpoint file, or an image file.
THE FOLDER IS NOT INSPECTED HERE. Which of the two kinds it is – checkpoints or benchmark fields – is decided in
apply, because deciding it twice would walk the directory twice.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name both kinds of folder this module takes.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.PlaqueDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerPlaque Assay’s own drop policy and its own words.
It takes plaque images, folders of them, both mixed, and in Figure mode any number of PDFs; other files dropped with them are left aside quietly. Before this handler Plaque Assay was given Make Masks’ policy, which refused a folder it could not use with Make Masks’ sentence.
- accepts_multiple() bool[source]¶
Several images and folders in one drop make one selection.
- Returns:
True.
- apply(path: pathlib.Path, screen) None[source]¶
Take one dropped path.
- Parameters:
path – the dropped file or folder.
screen – the Plaque Assay screen.
- apply_all(paths: Sequence[pathlib.Path], screen) bool[source]¶
Point Plaque Assay at the drop: PDFs to Figure mode, images to src.
The mode follows what was dropped: PDFs, or a folder of them, dropped in Plaque mode ask to switch to Figure mode; images dropped in Figure mode ask to switch to Plaque mode; PDFs and images together say that PDFs are read in Figure mode and images in Plaque mode, and ask which to read. Staying in Figure mode reads the images as figures; staying in Plaque mode leaves the PDFs unread.
- Parameters:
paths – the accepted files and folders, in drop order.
screen – the Plaque Assay screen.
- Returns:
True; the drop is always handled here.
- can_accept(path: pathlib.Path) bool[source]¶
Any file, or a folder with plaque images or PDFs in it.
A file that is neither an image nor a PDF is taken so that
apply_all()can leave it aside quietly when it was dropped with images or PDFs, and refuse it when it was dropped alone.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Say what Plaque Assay reads, in its own terms.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]¶
Nearby folders that hold plaque images.
- Parameters:
path – the dropped file or folder.
- Returns:
sibling and child folders with plaque images in them.
- class spacr.qt.dnd_handlers.PlateQueueDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerQueue plate folders that carry spaCR settings snapshots.
- accepts_multiple() bool[source]¶
Yes: queueing several plates in one gesture is the point.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Queue every plate the drop names.
TWO SHAPES, ONE GESTURE. A CSV is a plate LIST and each row becomes an item; a folder is ONE plate and each settings snapshot in it becomes an item.
A PARTIAL DROP IS REPORTED. One unreadable snapshot among several used to report plain success, so that plate quietly never reached the queue and the user found out when the run they expected was missing.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A plate-list CSV, or a plate folder holding settings snapshots.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name both shapes, and the
srccolumn the CSV form needs.- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ProjectFolderDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerA screen that takes a whole project, wherever inside it you drop.
kindsis empty on purpose: there is no port for “the project”, and inventing one would put it in the module graph. The layout walk still happens — dropping<plate>/measurements/measurements.dbon the pipeline graph opens<plate>.Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- can_accept(path: pathlib.Path) bool[source]¶
A folder the resolver reads as one project, without ambiguity.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- deliver(screen, value: str, target) None[source]¶
Call the first setter this screen actually offers.
SEVERAL SPELLINGS, ONE POLICY. Screens name the act of taking a project differently, and a handler per spelling would be copies of this policy that could drift about what a project is. A screen with none of them is a wiring error and says so rather than failing quietly.
- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.ProjectRootsDropHandler(app_key: str = '')[source]¶
Bases:
ProjectFolderDropHandlerProject Browser: several folders at once, each becoming a root.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- accepts_multiple() bool[source]¶
Yes: several roots at once is what the browser is for.
- Returns:
True to be called once per item on a multi-drop.
- deliver(screen, value: str, target) None[source]¶
Add the root, treating an already-watched folder as a no-op.
add_rootreturns False for a root already listed. That is not a failure and must not be reported as one: dropping a folder the browser already watches should do nothing, not raise an error dialog.- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.RegressionDropHandler[source]¶
Bases:
MeasurementsDropHandlerRegression’s drop: a database to a plate row, CSVs to the sweep card.
Regression takes its measurements one row per plate, which is what
MeasurementsDropHandleralready does. It ALSO carries the parameter sweep as a card, and that card takes the sweep’s two CSV lists – per-object scores and gRNA counts – which a measurements handler rejects outright because they are notmeasurements.db.Both halves have to answer at one drop target. The sweep no longer has a tile of its own, so the Regression screen is the ONLY place its inputs can be dropped; without this, a dropped sweep bundle got “needs a plate folder with measurements/measurements.db” and filled nothing.
The database shape is tried first: it is the screen’s own input, and a
measurements.dbis never one of the sweep’s CSV lists, so the two cannot compete for the same path.- accepts_multiple() bool[source]¶
Yes. The sweep half takes many CSVs at once, which is the gesture the card exists for – one plate’s scores and counts arrive together.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Attach
pathto a plate row or the embedded sweep card.- Parameters:
path – accepted database, plate directory, sweep CSV, or sweep directory.
screen – Regression screen receiving the resolved input.
- can_accept(path: pathlib.Path) bool[source]¶
Return whether Regression can route
pathto either input area.- Parameters:
path – database, plate directory, sweep CSV, or sweep directory to classify.
- error_message(path: pathlib.Path) str[source]¶
Explain why
pathmatches neither Regression input contract.- Parameters:
path – rejected file or directory.
- class spacr.qt.dnd_handlers.ReportDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a completed spaCR run folder and scan its report inputs.
- apply(path: pathlib.Path, screen) None[source]¶
Set the source and scan it, raising the screen’s own reason on failure.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder: whether it holds a run is what the scan answers.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Say the folder must be a COMPLETED run, which is the usual mistake.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.ResultsDatabaseDropHandler[source]¶
Bases:
DatabaseDropHandlerDatabase input for Plate Viewer and Annotator Agreement.
- apply(path: pathlib.Path, screen) None[source]¶
Open the database through whichever setter this screen offers.
TWO SPELLINGS, ONE HANDLER. Plate Viewer and Annotator Agreement name the same act differently, and a handler per spelling would be two copies of this policy that could disagree about what a database is.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- class spacr.qt.dnd_handlers.ResultsFolderDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerHit List: the
results/folder a regression wrote.Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- class spacr.qt.dnd_handlers.RunHistoryDropHandler(app_key: str = '')[source]¶
Bases:
ProjectFolderDropHandlerRun History: select the run a dropped run folder belongs to.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- apply(path: pathlib.Path, screen) None[source]¶
Refresh, then select the run the dropped folder belongs to.
REFRESH FIRST. A run finished after this screen was opened is not in the list yet, and selecting it would fail for a folder that plainly exists – which reads as a bug rather than as a stale list.
The refusal names both ways out, because a run can be missing from the list either by not being there or by being filtered out of it.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Anything on disk; whether it is a known run is decided in
apply.- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- class spacr.qt.dnd_handlers.ScatterTableDropHandler(app_key: str = '')[source]¶
Bases:
TableDropHandlerImage Scatter: a path field, a table picker, then the read.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- class spacr.qt.dnd_handlers.SourceDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerGeneral source-path policy for modules without a narrower contract.
Every standard
AppScreenhas asrcfield. Accepting a real directory here gives newer and less-specialised modules drag-and-drop support automatically instead of requiring a registry edit for every screen. A dropped file is only accepted for known data extensions and is normalised to its containing directory.Where the module declares ports, the value comes from
spacr.chaining.resolve_drop()— the same answer auto-chaining would fill the field with — so dropping<plate>/measurementsand letting the chain fillsrccannot produce two different strings. A module with no declaration keeps the plain normalisation below, which is all there is to go on.- apply(path: pathlib.Path, screen) None[source]¶
Let the vocabulary place the drop, falling back to
src.A screen that declares ports gets them filled; one that declares none still gets its source folder set, which is the behaviour every screen had before ports existed.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder, or a data file in a format the standard screens read.
Deliberately broad: this is the FALLBACK policy, and refusing here would leave a screen with no drop behaviour at all rather than a generic one.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Generic on purpose – a fallback cannot name what it does not know.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.SubmissionSettingsDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerDistributed Jobs: a settings snapshot to submit, or the plate with one.
Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- apply(path: pathlib.Path, screen) None[source]¶
Submit the snapshot, ASKING when the folder holds more than one.
A plate with several snapshots has no right answer, and picking the first would submit a run the user did not choose – expensively, and without saying which one it took.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
A settings snapshot, or a plate folder holding at least one.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Name both file spellings and the folder layout, since which one a user has depends on whether they saved a run or ran one.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- class spacr.qt.dnd_handlers.SweepInputsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerRoute dropped CSVs into Parameter Sweep’s score and count lists.
The sweep takes the same two inputs the regression does, but holds them in two separate list widgets rather than one paired table, so the side has to be decided before the file is added. It is decided the same way Regression decides it – from the CSV header, via
spacr.qt.widgets.file_list.side_for_header()– because a count table filed as a score is not an error the user sees, it is a wrong sweep.A dropped FOLDER contributes the CSVs directly inside it, which is what makes “drop the plate folder” work for a screen whose whole point is running many plates at once.
- accepts_multiple() bool[source]¶
Yes: a plate’s scores and counts arrive together, as two CSVs.
- Returns:
True to be called once per item on a multi-drop.
- apply(path: pathlib.Path, screen) None[source]¶
Route score and count CSVs from
pathto the sweep panel.- Parameters:
path – accepted CSV file or directory of CSV files.
screen – sweep panel or host screen carrying it on
_sweep.
- can_accept(path: pathlib.Path) bool[source]¶
Return whether
pathcontributes at least one sweep CSV.- Parameters:
path – CSV file or directory whose immediate CSV children are considered.
- error_message(path: pathlib.Path) str[source]¶
Explain why
pathcannot populate the sweep inputs.- Parameters:
path – rejected file or directory.
- class spacr.qt.dnd_handlers.TableDropHandler(app_key: str = '')[source]¶
Bases:
LayoutDropHandlerA screen that reads one table: the explorers, the plotters, the gates.
Drop the project and it finds
measurements/measurements.db; drop the database and it uses it; drop a CSV and it reads that. When the database holds more than one table the table is asked rather than taken —load_pathpicks the first one silently, which is fine for a file dialog where the user chose the file and wrong for a drop where they chose a folder.Create the handler, naming itself if the caller did not.
- Parameters:
app_key – the module this handler serves; empty falls back to the handler’s label and then to its class name, so a handler always has something to report itself as.
- deliver(screen, value: str, target) None[source]¶
Ask which table, then load it.
A CANCELLED CHOOSER IS NOT A FAILURE. The user changed their mind about a drop; loading something anyway, or raising, would both be worse than doing nothing.
- Parameters:
screen – the screen to wire the drop into.
value – the resolved path, as text.
target – the port the vocabulary matched, or
None.
- class spacr.qt.dnd_handlers.TrainingRunsDropHandler[source]¶
Bases:
spacr.qt.dnd.DropHandlerAccept a directory and asynchronously scan it for training runs.
- apply(path: pathlib.Path, screen) None[source]¶
Start the scan, and raise with the screen’s own reason if it refuses.
- Parameters:
path – the dropped file or folder.
screen – the screen to wire the drop into.
- can_accept(path: pathlib.Path) bool[source]¶
Any folder: what is in it is decided by the scan, not by the drop.
- Parameters:
path – the dropped file or folder.
- Returns:
True when this handler can use
pathas-is.
- error_message(path: pathlib.Path) str[source]¶
Say that runs live in a folder, not in a file.
- Parameters:
path – the dropped file or folder.
- Returns:
the sentence shown when the drop is refused.
- spacr.qt.dnd_handlers.active_scan_jobs(screen) int[source]¶
How many folder-scan threads
screenstill owns.- Parameters:
screen – screen whose active drop-scan jobs are counted.
- spacr.qt.dnd_handlers.forget_decisions() None[source]¶
Drop every cached drop decision, so the next one asks again.
- spacr.qt.dnd_handlers.get_handler(app_key: str) spacr.qt.dnd.DropHandler[source]¶
Return a fresh DropHandler for
app_key.Falls back to
SourceDropHandlerso every conventional AppScreen can at least receive its source folder.- Parameters:
app_key – registered built-in or plugin application key whose drop policy is requested.
- spacr.qt.dnd_handlers.plaque_inputs(paths: Sequence[pathlib.Path], *, limit: int = 20000) Tuple[List[pathlib.Path], List[pathlib.Path], List[pathlib.Path]][source]¶
What a drop or a
srcholds for each Plaque Assay mode.Only the top level of a folder is read, as the plaque run reads it, and at most
limitentries of each, so a huge folder on a slow share cannot hold the window for long.- Parameters:
paths – dropped files and folders, or
[src].limit – entries read per folder.
- Returns:
(pdfs, images, paper_folders). A paper folder – one a paper was fetched into, holding itspaper.json,legends.csvortext_layer.json– is Figure mode’s input, and its figure images are not counted as plaque images.
- spacr.qt.dnd_handlers.plaque_others(paths: Sequence[pathlib.Path], *, limit: int = 20000) int[source]¶
How many dropped files Plaque Assay leaves aside.
A file that is neither a plaque image nor a PDF, dropped or at the top of a dropped folder, is ignored rather than refused; hidden files are not counted, nor is what a paper folder holds.
- Parameters:
paths – dropped files and folders, or
[src].limit – entries read per folder.
- Returns:
the number of such files.
- spacr.qt.dnd_handlers.plaque_selection_folder(images: Sequence[pathlib.Path], stamp: str | None = None) pathlib.Path[source]¶
A folder that lists the dropped plaque images, without copying them.
A plaque run reads one folder and writes its masks beneath it, so a drop of loose files becomes a folder of links to them – symbolic, else hard – named
plaque_selection_<time>beside the first image, or in the temporary folder when that one cannot be written. Two images with the same name from different folders keep both, the second under its folder’s name.- Parameters:
images – the images, in drop order.
stamp – the time part of the name; now when omitted.
- Returns:
the folder.
- Raises:
OSError – when an image can be neither linked nor listed.
- spacr.qt.dnd_handlers.scan_folder_structure(path) Dict[str, Any][source]¶
Walk a dropped folder ONCE and return the folder-metadata report.
Worker-safe: plain data in, plain data out, nothing Qt. The single walk is the point. This replaced three walks of the same tree —
detect_folder_metadatadid one,plan_folder_extractiondid another and calleddetect_folder_metadataagain for a third — all on the GUI thread, all inside the drop event.The probe is pulled off the same lazy generator the planner then drains, so a folder whose layout is not recognisable costs 30 files, not a traversal.
- Parameters:
path – dropped directory to inspect for a recognised image layout.
- Returns:
{"labels": (...), "rows": [...], "error": ""}. Emptylabelsmeans no folder layout was recognised and there is nothing to report.
- spacr.qt.dnd_handlers.scan_is_busy(screen) bool[source]¶
True while a dropped folder is still being walked for
screen.- Parameters:
screen – screen that owns the drop scanner to query.
- spacr.qt.dnd_handlers.scan_mask_container(path) Dict[str, Any][source]¶
Read a dropped container’s header and plan its extraction. Worker-safe.
The single-file half of a mask drop:
.nd2/.czi/.lif/ multi-page.tif/.npz, described once and turned into the rows the metadata table shows. No Qt, no widgets, plain data out.It is here rather than inside
applybecause describing a container is a FILE OPEN, and the drop that started this exercise was a file open on a sleepingautofsshare that had not returned after twenty seconds. The branch used to defer itself withQTimer.singleShot(0, ...)under the comment “reads a header, not a tree” – true about the amount of data and beside the point about the wait, because a single-shot timer runs its callback ON the GUI thread with the event loop stopped. It only moved the freeze one turn later, which is why it was never traced back to here.- Parameters:
path – the dropped container file.
- Returns:
{"found": bool, "summary": str, "rows": [...], "error": str}.foundis False for a file no backend recognises.- Raises:
whatever
spacr.qt.multi_format.describe_file()raises. A caller on a worker is wrapped by_scan_then(); the synchronous caller,_report_regex_on_mask(), has always let it through.
- spacr.qt.dnd_handlers.scan_mask_drop(path) Dict[str, Any][source]¶
Everything a mask drop asks the filesystem about one path. Worker-safe.
One record, taken once: whether the path is a folder or a file, whether the module can take it, and – when it cannot – the nearby folders the “did you mean” dialog offers.
It is one record because it used to be three separate rounds of stat-ing on the GUI thread inside a single drop:
can_acceptaskedis_dir/has_images_in,suggest_alternativesthen walked the parent and the children again, andapplyaskedis_file/is_dira third time. On a sleeping/nas_mntshare the first of those had not returned after twenty seconds.- Parameters:
path – the dropped path to classify.
- Returns:
{"is_dir": bool, "is_file": bool, "accepted": bool, "alternatives": [Path, ...]}.
- spacr.qt.dnd_handlers.scan_mask_folder(path, sample: int = 20) Dict[str, Any][source]¶
List the top level of a dropped folder once. Worker-safe.
Returns the filenames the regex preview samples plus the total image count the report quotes. Both used to come from two separate listings of the same directory, taken on the GUI thread.
- Parameters:
path – dropped directory whose top-level files are inspected.
- spacr.qt.dnd_handlers.table_names(path: pathlib.Path) List[str][source]¶
Return the tables in a SQLite file, or
[]for anything else.One
sqlite_masterquery; the table screens make the same one when they load. Kept here so the drop can ask which table rather than letload_pathtake the first one silently.Opened read-only, and through a quoted URI: a folder with a
?or a#in its name would otherwise have everything after it read as query parameters, and the open would fail on a database that is perfectly fine.- Parameters:
path – candidate SQLite database path to inspect read-only.
Nested helpers¶
- _decide.run() None¶
Ask
workon a throwaway thread and cache what it answers.Outlives the wait below whenever the share is asleep, which is why
_remember()refuses an answer older than the one it holds.spacr/qt/dnd_handlers.py:573
- _open_metadata_table._on_apply(csv_path)¶
Note where the metadata map was written.
spacr/qt/dnd_handlers.py:1146
- _scan_then.guarded()¶
Run
fnon the worker, carrying a failure back as data.spacr/qt/dnd_handlers.py:323