Repository navigation
feat: acquisition tracks (sequential vs. simultaneous channels) - #165
Merged
Merged
Conversation
- New `Simulation.tracks`: "sequential" (default, each channel excited only by its own light sources, as before), "simultaneous", or a list of `Track`s (bare lists of channel indices or names are cast, e.g. [[0, 2], [1, 3]]). All light sources of a track excite every fluorophore, so fluorophores can bleed into every channel of their track; saturation uses the total. - A light source used by several channels of a track is counted once; those channels must agree on its power and excitation filters (ValueError otherwise, or if they share only some light sources). Lights and filters are identified by their spectra (so e.g. `laser(488)` and `laser(488.0)` match, in any order); channels without lights (a lamp) by their excitation filters. - Point scanners: channels in a track must share one pixel dwell time. - New `Confocal.shared_pinhole` (default True): channels in a track share one pinhole, with `pinhole_au` at the average of their emission band centers. - `ChannelFluorescence` gets an optional `track` (None: acquired on its own, e.g. with its own pinhole), and `create(..., absorption_rate=, track=)`. - A rejected `Simulation` field assignment no longer leaves the new value set. - `Track` is exported from `microsim.schema`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #165 +/- ##
==========================================
+ Coverage 89.06% 89.99% +0.93%
==========================================
Files 51 51
Lines 3483 3579 +96
==========================================
+ Hits 3102 3221 +119
+ Misses 381 358 -23 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Last piece of the #160 split (after #161, #162, #163 and #164). This adds acquisition tracks: which channels are acquired at the same time, as on a point scanner.
Until now every channel was implicitly acquired on its own (excited only by its own light sources), and that's still the default (
tracks="sequential", which gives identical results to main). But a lot of real bleedthrough comes from having several lasers on at once, so in a track all light sources of all its channels excite every fluorophore, and every fluorophore can show up in every channel of the track. Saturation is computed from the total excitation, since the fluorophore sees all of the lasers at once.examples/multi_channel_confocal.pyis a decent demo of this (EGFP/EYFP with 488 + 515... with both lasers on, EYFP actually outshines EGFP in the 488 channel).Some rules that fall out of this:
laser(488)andlaser(488.0)are the same laser. Sharing only some light sources between channels is an error.Confocal.shared_pinhole(default True): channels in a track go through one pinhole, withpinhole_auin Airy units at the average of their emission band centers.shared_pinhole=Falsegives each channel its own pinhole, matched to its band, as before. (Averaging is a convention I picked... open to other ideas)ChannelFluorescencegets an optionaltrack(None means "on its own"), so a custom modality can tell which channels were acquired togetherUnrelated-ish fix along the way: a
Simulationfield assignment that fails validation used to leave the new (invalid) value set. It's now undone.A few things I'm leaving for later:
sim.channels[0].exposure_ms = ...) skips the track checkschannelsandtrackstogether needstracks="sequential"first (the error message says so)plot_summarystill only shows each channel's own lights, while the absorption row shows the whole trackCloses #160