Closed philipstarkey closed 6 years ago
Original comment by Chris Billington (Bitbucket: cbillington, GitHub: chrisjbillington).
After labscript generates lists of output values, devices tend to quantise these as well (in their generate_code method) before storing them in the h5 file. I am not sure if any checks are performed after the output values are quantised here, so bad quantisation code could be to blame.
Happy to debug a minimum working example.
Original comment by Jan Werkmann (Bitbucket: PhyNerd, GitHub: PhyNerd).
Here is a minimal example:
#!python
from labscript import *
from labscript_devices.PulseBlaster_SP2_24_100_32k import PulseBlaster_SP2_24_100_32k
from labscript_devices.NI_PCIe_6363 import NI_PCIe_6363
# Connection Table
PulseBlaster_SP2_24_100_32k( name='pulse_blaster')
ClockLine( name='A1_clockline', pseudoclock=pulse_blaster.pseudoclock, connection='flag 0')
NI_PCIe_6363(name='ni_card_0', parent_device=A1_clockline, clock_terminal='ni_pcie_6363_0/PFI0', MAX_name='ni_pcie_6363_0', acquisition_rate=100e3)
AnalogOut( name='Pushout_Frequency', parent_device=ni_card_0, connection='ao2', limits=(0,10), default_value=5.67)
AnalogOut( name='Pushout_Amplitude', parent_device=ni_card_0, connection='ao3', limits=(0,10), default_value=0.0)
start()
t=1.8061896326530613
ramp_samplerate = 16000.0
Pushout_Amplitude. ramp(t, duration=0.25, initial=5.00, final=0, samplerate=ramp_samplerate)
t += 0.25 + 0.01
stop(t)
This should result in
#!
Traceback (most recent call last):
File "script.py", line 18, in <module>
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 2143, in stop
generate_code()
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 2045, in generate_code
device.generate_code(hdf5_file)
File "/Users/janwerkmann/labscript_suite/labscript_devices/PulseBlaster_No_DDS.py", line 73, in generate_code
PseudoclockDevice.generate_code(self, hdf5_file)
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 963, in generate_code
self.do_checks(outputs)
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 943, in do_checks
output.do_checks(self.trigger_times)
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 1128, in do_checks
self.add_instruction(instruction['end time'], instruction['function'](instruction['end time']-instruction['initial time']), instruction['units'])
File "/Users/janwerkmann/labscript_suite/labscript/labscript.py", line 1107, in add_instruction
raise LabscriptError('You cannot program the value %s (base units) to %s as it falls outside the limits (%d to %d)'%(str(instruction), self.name, self.limits[0], self.limits[1]))
LabscriptError: You cannot program the value -4.4408920985e-15 (base units) to Pushout_Amplitude as it falls outside the limits (0 to 10)
Compilation aborted.
Original comment by Philip Starkey (Bitbucket: pstarkey, GitHub: pstarkey).
So this is not an issue with the quantised times code. It actually happens before any of the code for quantised times runs. I'm pretty sure it's an issue with the floating point calculation error (to do with the time) inside the ramp function because. Specifically, if you set t=1.806189632
you see the crash, but if you set t=1.80618963
then you don't. All this does is offset the initial
parameter in the ramp function (the duration stays the same which is the only argument used to evaluate the value at the end time point (so it's agnostic of the end time point). Similarly, using t=1.8061896327
works fine but t=1.8061896326
does not.
Investigating further, this error is due to the fact that we directly use the duration when parameterising the ramp (aka, when we create the lambda function
in labscript.functions.ramp
) but then use a calculated duration when evaluating the end point. The solution should be to instead use a duration internally in AnalogQuantity.ramp
that is calculated as t + truncation * duration -t
. In a terminal, this works for me and successfully returns 0.0
when you evaluate the function at the end point. However, in labscript I still see the crash (and the error is now twice the size it was before)....
Not sure why that is, I'll keep digging!
In the meantime, a quick solution for you would be to just work out why you have 17 digits of precision in your time and quantise that away manually in your script.
Original comment by Philip Starkey (Bitbucket: pstarkey, GitHub: pstarkey).
Ok, got the solution. This line should have the function
key be changed to: 'function': functions.ramp(round(t + truncation * duration, 10) - round(t, 10), initial, final)
Can you test and confirm it fixes the issue on your actual script and doesn't introduce other issues?
Original comment by Chris Billington (Bitbucket: cbillington, GitHub: chrisjbillington).
Fixes issue #46
→ \<\<cset 0e7173a806d220409583bc5e954cfc1e345ee8a5>>
Original comment by Chris Billington (Bitbucket: cbillington, GitHub: chrisjbillington).
fixed bug in last commit (fixing issue #46) where we included truncation
in the duration calculation used to determine the duration used as a parameter of the function.
This was incorrect, since the function should be defined over the original duration, but evaluated over the truncated duration.
The fix was also applied to all ramping functions of AnalogQuantity.
→ \<\<cset 033d8685eb7f3b0ab0738857970c65c19fdebb17>>
Original report (archived issue) by Jan Werkmann (Bitbucket: PhyNerd, GitHub: PhyNerd).
Today in the lab we ran into the problem where a script would not compile due to the fact that a ramp exceeded the outputs limits. The output had the limits (0, 10) and the initial values was something like 4 and final value of the ramp was 0 the invalid value was something like -4e-14. My guess is that the quantized times might have caused this though I'm not sure.
I'll try to make a minimal working example tomorrow. The script we used in the lab is quite complex and contains devices that are not in mainline labscript.