Skip to content

Moving from Calibration to Volume mode loses focus #142

@fedem-p

Description

@fedem-p

I know this is probably related to #103 and #104, But I though it would have been good to have a single thread to discuss this specific problem.

Expected Behavior

After correctly calibrating the scanners, if mode is switched to planar or volume the preview should remain in focus.

Actual behavior

After correctly calibrating the scanners, if switching mode to planar the live view is in focus as expected.
However, the focus is lost in the volumetric mode.

Exploration of exact behavior of the scanners

I've spent quite some time reading the commands sent to piezo and lateral scanner to further understand what caused this problem.
focus_bug
In this image there are plotted the piezo values against the lateral scanning.
The legend is explained as follows:

  • 0.5 Hz acquisition frequency
  • 1 Hz acquisition frequency
  • 2 Hz acquisition frequency
  • 4 Hz acquisition frequency
  • test is the same as 4 Hz but with an hard-coded offset to try fixing the curve
  • planar is the line fitted taking a couple of points in planar mode

Ideally the part of the wave of the piezo vs lateral where we send the camera pulses should match in planar and volumetric mode.

Where is this in the code?

The main place of divergence from planar mode and volumetric mode is inside the scanloops module.
In particular, there are a couple of functions which seem to impact the reading and writing of the piezo.

So far I've mostly looked into the fill_arrays function:

   def fill_arrays(self):
        super().fill_arrays()
        self.board.z_piezo = self.z_waveform.values(self.shifted_time)
        i_sample = self.i_sample % len(self.recorded_signal.buffer)

        if self.recorded_signal.is_complete():
            wave_part = self.recorded_signal.read(i_sample, self.n_samples)
            max_wave, min_wave = (np.max(wave_part), np.min(wave_part))
            if (
                -2 < calc_sync(min_wave, self.parameters.z.lateral_sync) < 2
                and -2 < calc_sync(max_wave, self.parameters.z.lateral_sync) < 2
            ):
                self.board.z_lateral = calc_sync(
                    wave_part, self.parameters.z.lateral_sync
                )
            if (
                -2 < calc_sync(min_wave, self.parameters.z.frontal_sync) < 2
                and -2 < calc_sync(max_wave, self.parameters.z.frontal_sync) < 2
            ):
                self.board.z_frontal = calc_sync(
                    wave_part, self.parameters.z.frontal_sync
                )

        camera_pulses = 0
        if self.camera_on:
            self.logger.log_message("I")
            if self.camera_was_off:
                self.logger.log_message("Camera was off")
                # calculate how many samples are remaining until we are in a new period
                if i_sample == 0:
                    camera_pulses = self.camera_pulses.read(i_sample, self.n_samples)
                    self.camera_was_off = False
                    self.wait_signal.clear()
                else:
                    n_to_next_start = self.n_samples_period() - i_sample
                    if n_to_next_start < self.n_samples:
                        camera_pulses = self.camera_pulses.read(
                            i_sample, self.n_samples
                        ).copy()
                        camera_pulses[:n_to_next_start] = 0
                        self.camera_was_off = False
                        self.wait_signal.clear()
            else:
                camera_pulses = self.camera_pulses.read(i_sample, self.n_samples)

        self.board.camera_trigger = camera_pulses

Here there's a thing that's not totally clear to me:
The way the values are written on the piezo (self.board.z_piezo = self.z_waveform.values(self.shifted_time)) and then read to get the wave_part (wave_part = self.recorded_signal.read(i_sample, self.n_samples))

I'm not fully sure of how this two lines relate to each other.

What I found so far is that adding an arbitrary offset to the wavepart seems to get closer to fix the problem,
i.e.
wave_part = self.recorded_signal.read(i_sample, self.n_samples) + 10

Furthermore, the way the waveform for the piezo is generated seems totally correct to me.

Speculation

An hypothesis that I have is that we may need to readjust the minimum/maximum piezo values to account for the part of the wave which is declining towards the minimum. (I haven't manage to test this yet)

Help

I would appreciate any input and clarification in the functioning of the volumetric mode, since maybe I'm missing something that could cause the issue in question.

I'll try to update this thread with what I find next week.

Let me know if you have any ideas regarding this @vilim, @diegoasua and, @vigji

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghelp wantedExtra attention is needed

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions