OxfordIonTrapGroup/wand

WLM pipelineing

Closed this issue · 7 comments

WLM pipelineing

The Wavemeters have undocumented internal pipelining, that means we have to perform three frequency measurements to get "fresh" data that's actually taken after our trigger.

Discussing this with the high finesse engineers, they suggested adding 2 "dummy" measurements to flush the wlm pipeline. This is what we currently do. However, that seems to screw up the auto exposure.

Here is a log of the 423 interference peak heights (roughly scaled to lie between 0 and 1 as a fraction of full-scale). The first number is the pipeline stage.

0 [0.502, 0.9051428571428571]
1 [0.5034285714285714, 0.9054285714285715]
2 [0.502, 0.9045714285714286]
0 [0.5011428571428571, 0.9048571428571428]
1 [0.5005714285714286, 0.9048571428571428]
2 [0.49514285714285716, 0.9057142857142857]
0 [0.494, 0.9048571428571428]
1 [0.4897142857142857, 0.9045714285714286]
2 [0.48942857142857144, 0.9051428571428571]
0 [0.4948571428571429, 0.9054285714285715]
1 [0.49028571428571427, 0.9054285714285715]
2 [0.48542857142857143, 0.9051428571428571]
0 [0.4948571428571429, 0.906]
1 [0.48857142857142855, 0.9051428571428571]
2 [0.4928571428571429, 0.9062857142857143]
0 [0.5008571428571429, 0.9054285714285715]
1 [0.48142857142857143, 0.9048571428571428]
2 [0.48028571428571426, 0.9048571428571428]
0 [0.48714285714285716, 0.9048571428571428]
1 [0.49542857142857144, 0.9054285714285715]

Code is

    def _get_fresh_data(self):
        """ Gets a "fresh" wavelength measurement, guaranteed to occur after
        this method was called.

        The WLM has an (undocumented) internal measurement pipeline three
        events deep. As a result, to get fresh data we need to perform three
        measurements. To minimize the time wasted flushing the measurement
        pipeline, we set the exposure time to minimum during the "dummy"
        measurements.
        """
        self._update_exposure()  # synchronise WLM with self._exposure
        for pipeline_stage in range(3):
            self._trigger_single_measurement()
            if pipeline_stage == 0:
                pass # self._update_exposure(self._exp_min)
            for ccd in range(self._num_ccds):
                self._peaks[ccd] = self.get_fringe_peak(ccd)
            print(pipeline_stage, self._peaks)

That's as expected (the second CCD is saturated). Here is what happens when I set the exposure time to min for the second two pipeline stages as recommended by HF:

0 [0.022285714285714287, 0.030857142857142857]
1 [0.014857142857142857, 0.7405714285714285]
2 [0.5422857142857143, 0.4437142857142857]
0 [0.018857142857142857, 0.03428571428571429]
1 [0.015428571428571429, 0.73]
2 [0.544, 0.44485714285714284]
0 [0.021142857142857144, 0.03142857142857143]
1 [0.018285714285714287, 0.7377142857142858]
2 [0.554, 0.45057142857142857]
0 [0.018857142857142857, 0.031142857142857142]
1 [0.018571428571428572, 0.7428571428571429]
2 [0.55, 0.45371428571428574]
0 [0.021142857142857144, 0.03428571428571429]
1 [0.014857142857142857, 0.030857142857142857]
2 [0.5537142857142857, 0.4602857142857143]
0 [0.018571428571428572, 0.03457142857142857]
1 [0.018, 0.03457142857142857]
2 [0.5465714285714286, 0.47114285714285714]
0 [0.017142857142857144, 0.03371428571428572]
1 [0.013714285714285714, 0.7745714285714286]
2 [0.5425714285714286, 0.4745714285714286]
0 [0.019428571428571427, 0.03514285714285714]
1 [0.01742857142857143, 0.03314285714285714]
2 [0.5454285714285714, 0.4742857142857143]
0 [0.015428571428571429, 0.034]
1 [0.017714285714285714, 0.03257142857142857]
2 [0.5474285714285714, 0.4742857142857143]
0 [0.01657142857142857, 0.04371428571428571]
1 [0.018, 0.7697142857142857]
2 [0.5451428571428572, 0.4674285714285714]
0 [0.014, 0.032285714285714286]
1 [0.013714285714285714, 0.7682857142857142]
2 [0.5431428571428571, 0.46314285714285713]

This uses the same exposure times and laser powers as the previous trace. We see: (a) the peak heights are lower than in the first trace (b) the peak heights are very non-reproducible (pipeline stage 1 bounces between 3% and 75%).

aah...putting a time.sleep(100e-3) after the update exposure fixes this. So, maybe it's a race condition between the exposure update and the clear pipeline before the measurement trigger... So, let's tweak the sequence suggested by HF to see if we can fix this!

Nope, removing the self.lib.ClearWLMEvents() call has no effect...

Using self.lib.WaitForWLMEvent to wait until the exposure update has completed also has no effect

Modified the code to wait for events after changing exp and after changing switch channel. switching exposure to min for dummies I see:

0 [0.019142857142857142, 0.03685714285714286]
1 [0.019714285714285715, 0.8302857142857143]
2 [0.5325714285714286, 0.5022857142857143]
0 [0.02457142857142857, 0.037142857142857144]
1 [0.01685714285714286, 0.036571428571428574]
2 [0.5408571428571428, 0.5025714285714286]
0 [0.017714285714285714, 0.03542857142857143]
1 [0.017714285714285714, 0.8357142857142857]
2 [0.5477142857142857, 0.5128571428571429]
0 [0.022, 0.03857142857142857]
1 [0.01657142857142857, 0.036]
2 [0.5408571428571428, 0.5174285714285715]
0 [0.023142857142857142, 0.036571428571428574
1 [0.013714285714285714, 0.037142857142857144
2 [0.534, 0.5171428571428571]
0 [0.018857142857142857, 0.03571428571428571]
1 [0.01742857142857143, 0.8417142857142857]
2 [0.5205714285714286, 0.5122857142857142]

leaving it at a single value I see:

0 [0.5182857142857142, 0.9062857142857143]
1 [0.5082857142857143, 0.906]
2 [0.49114285714285716, 0.9062857142857143]
0 [0.48942857142857144, 0.9057142857142857]
1 [0.49257142857142855, 0.906]
2 [0.49885714285714283, 0.9068571428571428]
0 [0.5022857142857143, 0.906]
1 [0.5017142857142857, 0.906]
2 [0.49685714285714283, 0.9071428571428571]
0 [0.5, 0.9057142857142857]
1 [0.49714285714285716, 0.9065714285714286]
2 [0.496, 0.9062857142857143]
0 [0.506, 0.9062857142857143]
1 [0.5165714285714286, 0.906]
2 [0.5137142857142857, 0.9071428571428571]
0 [0.5117142857142857, 0.9062857142857143]
1 [0.4982857142857143, 0.9065714285714286]
2 [0.5025714285714286, 0.9062857142857143]
0 [0.49914285714285717, 0.9068571428571428]
1 [0.5042857142857143, 0.9065714285714286]
2 [0.5034285714285714, 0.9062857142857143]
0 [0.5111428571428571, 0.9062857142857143]
1 [0.5154285714285715, 0.9062857142857143]
2 [0.5154285714285715, 0.9065714285714286]
0 [0.5145714285714286, 0.9062857142857143]
1 [0.5165714285714286, 0.9071428571428571]
2 [0.5045714285714286, 0.9062857142857143]
0 [0.5114285714285715, 0.9062857142857143]
1 [0.5222857142857142, 0.9062857142857143]
2 [0.5211428571428571, 0.9062857142857143]
0 [0.5331428571428571, 0.9062857142857143]
1 [0.5342857142857143, 0.906]
2 [0.5308571428571428, 0.9057142857142857]

Increase num pipeline stages to 10 (but switch exposure to min after first):

0 [0.019428571428571427, 0.04285714285714286]
1 [0.023714285714285716, 0.03942857142857143]
2 [0.6685714285714286, 0.704]
3 [0.013428571428571429, 0.039714285714285716]
4 [0.02142857142857143, 0.05171428571428571]
5 [0.014571428571428572, 0.04285714285714286]
6 [0.012857142857142857, 0.04114285714285714]
7 [0.02057142857142857, 0.040285714285714286]
8 [0.018285714285714287, 0.041428571428571426]
9 [0.014571428571428572, 0.04171428571428572]
0 [0.015142857142857144, 0.04857142857142857]
1 [0.013428571428571429, 0.04114285714285714]
2 [0.6737142857142857, 0.7168571428571429]
3 [0.02142857142857143, 0.04]
4 [0.017142857142857144, 0.04171428571428572]
5 [0.019142857142857142, 0.04285714285714286]
6 [0.015142857142857144, 0.04057142857142857]
7 [0.014285714285714285, 0.04114285714285714]
8 [0.018, 0.04257142857142857]
9 [0.018571428571428572, 0.041428571428571426]
0 [0.02057142857142857, 0.04114285714285714]
1 [0.01685714285714286, 0.04171428571428572]
2 [0.6802857142857143, 0.732]
3 [0.018571428571428572, 0.04228571428571429]
4 [0.01685714285714286, 0.041428571428571426]
5 [0.019428571428571427, 0.04285714285714286]
6 [0.02057142857142857, 0.04228571428571429]
7 [0.024, 0.04228571428571429]
8 [0.017142857142857144, 0.04171428571428572]
9 [0.014571428571428572, 0.04257142857142857]
0 [0.02, 0.04171428571428572]
1 [0.015714285714285715, 0.04228571428571429]
2 [0.6788571428571428, 0.7434285714285714]
3 [0.022285714285714287, 0.042]
4 [0.023714285714285716, 0.04228571428571429]
5 [0.01657142857142857, 0.04342857142857143]
6 [0.016285714285714285, 0.04314285714285714]
7 [0.014285714285714285, 0.041428571428571426]
8 [0.018571428571428572, 0.04371428571428571]
9 [0.015142857142857144, 0.04228571428571429]
0 [0.015428571428571429, 0.04314285714285714]
1 [0.016285714285714285, 0.9042857142857142]
2 [0.6754285714285714, 0.7354285714285714]
3 [0.016285714285714285, 0.04257142857142857]
4 [0.017714285714285714, 0.04285714285714286]
5 [0.01657142857142857, 0.04228571428571429]
6 [0.018571428571428572, 0.040285714285714286]
7 [0.015428571428571429, 0.041428571428571426]
8 [0.015142857142857144, 0.04228571428571429]
9 [0.014857142857142857, 0.041428571428571426]
0 [0.016285714285714285, 0.04171428571428572]
1 [0.015714285714285715, 0.9051428571428571]
2 [0.6797142857142857, 0.7177142857142857]
3 [0.018285714285714287, 0.03942857142857143]
4 [0.016285714285714285, 0.041428571428571426]
5 [0.017142857142857144, 0.04285714285714286]
6 [0.025714285714285714, 0.04]
7 [0.014285714285714285, 0.039714285714285716]
8 [0.015428571428571429, 0.040857142857142856]
9 [0.015142857142857144, 0.042]

Okay, so if I hold the exposure time at its nominal for the first two stages of the three cycle pipeline (setting it to min for the final stage only) then I get consistent results with just holding it constantly at nominal.

So, we short of another conversation with HF about the "undocumented features" in their wavemeters, we have two options:

  1. Live with this odd effect and keep our current pipe lining (set exp to min for the second two pipeline stages)
  2. take a small hit in throughput and set the exp to min for the final stage only.

Let's go with 2 as it seems more roubst!