Pr/pre audit - #205
Conversation
takkasila
left a comment
There was a problem hiding this comment.
I did not get to test all the functionality in time, so I trust that you have tested them throughly, especially the image saving and tracking. Apartfrom that I have mostly stylistic requests that I considerd good coding convention and highly recommend that you adopt them.
Important
- Always write a clear class and function description. Along with type hints for arguments and return.
- Write inline comments as much as possible to explain your intentions for the following code.
Good to have
- Consistency between camel and underscore convention.
- Add line space as often as you can. It improves reading comprehension.
It's a really big issue in a short time. You did a good job! The UI looks nice too!
|
|
||
| # Disable kivy console log | ||
| os.environ["KIVY_NO_CONSOLELOG"] = "1" | ||
| # os.environ["KIVY_NO_CONSOLELOG"] = "1" |
There was a problem hiding this comment.
Should remain disabled.
| # os.environ["KIVY_NO_CONSOLELOG"] = "1" | |
| os.environ["KIVY_NO_CONSOLELOG"] = "1" |
| return not (y < y_lim and z > z_lim) | ||
|
|
||
| def _execute_safe_moves(self, target: List[float], cur: List[float], wait_until_idle: bool) -> None: | ||
| mm = units_from_literals('mm') |
There was a problem hiding this comment.
Throughout this file, there are hardcoded unit = 'mm'. Please read them from config file or pass through function arguments.
| # def executePIDStep(self, image: np.ndarray, pos: float) -> float: | ||
| # """Perform one PID control step based on current image and lens position. | ||
|
|
||
| Returns: | ||
| relPosZ (float): estimated **relative** z-axis position to move to | ||
| """ | ||
| # Args: | ||
| # image (np.ndarray): gray-scaled image |
There was a problem hiding this comment.
Please remove this entirely.
| import tifffile | ||
|
|
||
|
|
||
| def save_worker(image_queue, save_dir, filename_format, stop_event): |
There was a problem hiding this comment.
Please add argument type hints and function description.
Feature and Algorithm Work Before the LLM-Assisted Audit
At the macro level I added experimental pipeline:
Automated Plate Scanning
Plate geometry
To fit a plate I fit a circle using:
And estimate the coefficients with least squares regression. The centre and radius are
tile generation
I use calibrated camera field of view to calculate distances between scan
positions.
Then I reaine a tile only if its centre satisfies circle
While scanning, rows alternate between left to right and right to left
Scan-to-track transition
Once a worm is centred I do following
I repeat the scan if a worm is not found
Autofocus and Focus-Plane Estimation
I changed the autofocus to be a peek seekeer rather then a PID
At each Z position it collects (B) frame-level focus scores:
And calculates the median for that Z:
Until a all B frames are available we do not move z.
The autofocus begins with a configurable big step (s_0). If focus
decreases beyond a fraction for enough evaluations
we treat it as a overshoot, reverses direction, and
reduces the step
If focus falls below a configurable fraction (\rho) of the best observed
focus,
the autofocus treats focus as lost and restores the biggest step.
Fixed the smoothing weights originally used
min(1, n - 1)as their denominator, which I corrected tomax(1, n - 1).I also added asyncio event loops for scan and autofocus workers.
Intensity-based scan Z
To get a correct Z position for scanning, I sample the mean image
intensity over a Z range:
I then smooth the estimate and calculate its first derivative.
The implementation identifies:
and the closest first-derivative zero crossing (z_0). When both are available,
the selected scan plane is
Tracking Changes
Since there is no constant 16ms delay coming from USB port, I changed fixed waiting times to:
where (d*{\max}) is the largest movement requested in the current iteration.
The tracking worker then waits until the camera reports an image retrieval
timestamp newer than (t*{\text{ready}}).
I splitted velocity and speed stage configuration into:
Since I once collided the camera with the X stage, I added a rule for the unsafe combination of low Y and high Z.
Recording pipeline
I removed image encoding and I/O with disk from the camera acquisition callback
The resulting pipeline is:
Finally, each operation now gets each own worker abd runs independently and UI is scheduled with kivy Clock: