-
Yb Tweezer authoredYb Tweezer authored
daily.py 28.45 KiB
from lib import *
from lib import CONNECTIONS as C
import numpy as np
from itertools import product
import sys
import time
from pathlib import Path
timestamp = get_timestamp()
print(timestamp)
outdir = DATADIRS.daily.joinpath(timestamp)
comments = """
"""[1:-1]
# FLIR OPTIONS
flir_config = dict(
exposure_time = 300, # us
gain = 47.99, # dB
)
# use `t_<...>` for definite times
# use `tau_<...>` for durations and relative timings
# use `B_<...>` for MOT coil servo settings
# use `shims_<direction>` for shim coil settings
# use `det_<...>` for detunings
# use `f_<...>` for absolute frequencies
# use `delta_<name>` for small steps in corresponding parameters
# use ALL_CAPS for arrays
# add a comment for any literal numbers used
## GLOBAL PARAMETERS
reps = 1 # repeat shots for statistics
take_background = False # include a background shot in frame capture
flir_prerelease = True # use the Flir to take a pre-release image
probe_image = True # use the probe beams for recapture imaging, else CMOT beams
## TIMINGS
# timeline (with concurrencies)
# | tau_all |
# start | t0 | tau_ncool | tau_tof | tau_image | end
# | | |
# <tau_comp> | tau_comp_dur | |
# | <tau_flir_pre> <tau_flir>
# | | <tau_andor>
# | t_ramp | tau_ramp | <idle> | <off> | <CMOT on if not probe_image>
# |
# <tau_ref>
# general sequence timings
t0 = 300e-3 # blue MOT loading time
tau_flux_block = -15e-3 # time relative to t0 to stop atom flux; s
tau_blue_overlap = 2e-3 # overlap time of blue and green beams relative to t0; s
tau_ncool = 100e-3 # narrow cooling/compression time; s
tau_comp = 46e-3 # start compression ramping relative to t0; s
tau_comp_dur = 4e-3 # duration of coil ramp
tau_image = 1.5e-3 # imaging time; s
tau_freqpow = 20e-3 # start of frequency/power ramp after t0; s
tau_freqpow_dur = 30e-3 # frequency/power ramp duration; s
# camera timings
tau_flir_pre = -20e-3 # Flir pre-release image time rel. to end of narrow_cooling; s
tau_flir = +0.05e-3 # Flir post-tof image time rel. to end of tof; s
# tau_flir = -20e-3 # Flir post-tof image time rel. to end of tof; s # used for debugging CMOT
tau_andor = +0e-3 # EMCCD post-tof image time rel. to end of tof; s
# coil settings
B_blue = int(441815) # blue MOT gradient setting
B_green = int(55227) # green MOT gradient setting; 174: 48600
B_comp = 1.8 # compression ramp endpoint multiplier (= B_comp * B_green)
shim_fb = +1.255 # front/back shim; 174: 1.2
shim_lr = +0.165 # left/right shim; 174: -0.2
shim_ud = +0.565 # up/down shim; 174: 0.4
# CMOT AOM settings
f_freqpow = 90.0 # start of frequency ramp; MHz
p_freqpow_beg = 29.0 # start of power ramp; dBm
p_freqpow_end = 0.0 # end of ramp; dBm
p_image = 23.0 # power for imaging; dBm
p_image_cmot = 20.0 # power for imaging with CMOT beams; dBm
# PARAMETERS
nu_freqpow0 = 3.58 # extent of CMOT frequency ramp; MHz
NU_FREQPOW = np.linspace(3.3, 3.775, 20) # ^
det_image0 = 0.18 # detuning for imaging rel. to AOM-fiber optimal 93.5; MHz
DET_IMAGE = np.arange(-2.2, +3.8, 150e-3) # ^
tau_tof0 = 0.0e-3 # time of flight for free-space imaging; s
TAU_TOF = np.array([0.1e-3, 0.5e-3, 1.0e-3, 2.0e-3, 3.0e-3, 4.0e-3]) # ^
# TAU_TOF = np.array([0.1e-3])
## CONSTANTS AND DERIVED QUANTITIES
freespace_res = 93.68 # AOM RF-equivalent to guessed free-space resonance; MHz
aom_fiber_optim = 93.5 # RF frequency used for AOM+fiber optimization
T_COMP = t0 + tau_comp + np.linspace(0.0, tau_comp_dur, 101) # compression ramp times; s
B_COMP = np.linspace(B_green, B_green * 1.8, T_COMP.shape[0]) # compression ramp coil vals; s
bits_Bset = int(20) # number of bits to send in a servo setting
bits_DACset = int(4) # number of bits to send in a DAC-mode setting
det_block = 10.0 # shift the RF on the MOT beams to decouple the fiber; MHz
f_image0 = aom_fiber_optim + det_image0 # (nominal) CMOT final AOM frequency; MHz
mogramp_N = 1000 # number of steps in the frequency/power ramp
dailies_config = dict(
probe_image = probe_image,
CMOT_freq = f_image0,
CMOT_pow = p_freqpow_end,
)
def make_sequences(meas_type: DailyMeasType, name: str,
tau_tof: float, det_image: float, nu_freqpow: float) \
-> (SuperSequence, MOGTable):
if meas_type in {
DailyMeasType.TOF,
DailyMeasType.DET,
DailyMeasType.CMOT_DET,
}:
tau_all = tau_ncool + tau_tof + tau_image # main sequence time; s
sseq = SuperSequence(
outdir.joinpath("sequences"),
name,
{
"Scope": (Sequence()
+ Sequence.digital_pulse(
*C.scope_trig,
t0,
tau_ncool,
)
).with_color("k"),
"Load blue MOT": load_blue_mot(
outdir,
0.0, # start at sequence beginning
t0,
tau_all,
tau_flux_block,
).to_sequence().with_color("C0"),
"Load green MOT": (Sequence()
+ Sequence.digital_hilo(
*C.mot3_green_aom,
t0 - 5e-3, # the mogtable is triggered on a falling edge
t0
)
+ Sequence([
Event.digital1(
**C.mot3_green_sh, s=1)
@ (t0 - 5e-3) # open shutter ahead of AOM
])
+ Sequence.serial_bits_c(
C.mot3_coils_sig,
t0,
B_green, bits_Bset,
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
)
+ Sequence([
Event.digital1(**c, s=not c.default)
@ (t0 - 4.5e-3 + k * 1e-16) # 4.5ms delay with offset from simultaneity
for k, (c, v) in enumerate([
(C.shim_coils_p_fb, shim_fb),
(C.shim_coils_p_lr, shim_lr),
(C.shim_coils_p_ud, shim_ud)
])
if v < 0.0
])
+ Sequence([
Event.analog(**c, s=abs(s))
@ (t0 + k * 1e-16) # have to offset times from e/o
for k, (c, s) in enumerate([
(C.shim_coils_fb, shim_fb),
(C.shim_coils_lr, shim_lr),
(C.shim_coils_ud, shim_ud)
])
])
).with_color("C6"),
"CMOT servo ramp": (Sequence.joinall(*[
Sequence.serial_bits_c(
C.mot3_coils_sig,
t_comp,
int(b_comp), bits_Bset,
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
) for t_comp, b_comp in zip(T_COMP, B_COMP)
])).with_color("C1"),
"Free space": (Sequence()
+ Sequence.serial_bits_c(
C.mot3_coils_sig,
t0 + tau_ncool,
0, bits_Bset, # turn off to disperse MOT before imaging
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
)
+ Sequence([
Event.analog(**c, s=0.0)
@ (t0 + tau_ncool + k * 1e-16) # have to offset times from e/o
for k, c in enumerate([
C.shim_coils_fb, C.shim_coils_lr, C.shim_coils_ud
])
])
).with_color("C8"),
"Imaging": (Sequence()
+ (
(
Sequence.digital_pulse(
*C.probe_green_aom,
t0 + tau_ncool + tau_tof,
tau_image,
invert=True
)
+ Sequence.digital_pulse(
*C.probe_green_sh,
0.0,
t0 + tau_all
)
) if probe_image else Sequence()
)
+ (
Sequence.digital_pulse(
*C.flir_trig,
# Flir needs ~20ms between shots
t0 + tau_ncool + min(tau_flir_pre, tau_flir - 20e-3),
flir_config["exposure_time"] * 1e-6 # convert us -> s
) if flir_prerelease else Sequence()
)
+ Sequence.digital_pulse(
*C.flir_trig,
t0 + tau_ncool + tau_tof + tau_flir,
flir_config["exposure_time"] * 1e-6 # convert us -> s
)
+ Sequence.digital_pulse(
*C.andor_trig,
t0 + tau_ncool + tau_tof + tau_andor - 27e-3, # shutter time
1e-3 # exposure time is controlled separately
)
).with_color("C2"),
"Reset": (Sequence()
+ Sequence.serial_bits_c(
C.mot3_coils_sig,
t0 + tau_all,
B_blue, bits_Bset,
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
)
+ Sequence([
Event.analog(**c, s=c.default)
@ (t0 + tau_all + k * 1e-16) # have to offset times from e/o
for k, c in enumerate([
C.shim_coils_fb, C.shim_coils_lr, C.shim_coils_ud
])
])
+ Sequence([
Event.digital1(**c, s=c.default)
@ (t0 + tau_all - 4.5e-3 + k * 1e-16) # 4.5ms delay with offset from simultaneity
for k, (c, v) in enumerate([
(C.shim_coils_p_fb, shim_fb),
(C.shim_coils_p_lr, shim_lr),
(C.shim_coils_p_ud, shim_ud)
])
if v < 0.0
])
).with_color("C7"),
},
CONNECTIONS
)
elif meas_type in {
DailyMeasType.BMOT_NUM,
DailyMeasType.BMOT_DET,
}:
tau_all = flir_config["exposure_time"] * 1e-6 + tau_image
sseq = SuperSequence(
outdir.joinpath("sequences"),
name,
{
"Scope": (Sequence()
+ Sequence.digital_pulse(
*C.scope_trig,
t0,
1e-3, # arbitrary
)
).with_color("k"),
"Load blue MOT": load_blue_mot(
outdir,
0.0, # start at sequence beginning
t0,
tau_all,
tau_flux_block,
).to_sequence().with_color("C0"),
"Free space": (Sequence()
+ Sequence.serial_bits_c(
C.mot3_coils_sig,
t0,
0, bits_Bset,
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
)
+ Sequence([
Event.analog(**c, s=0.0)
@ (t0 + k * 1e-16) # have to offset times from e/o
for k, c in enumerate([
C.shim_coils_fb, C.shim_coils_lr, C.shim_coils_ud
])
])
).with_color("C8"),
"Imaging": (Sequence()
+ Sequence.digital_pulse(
*C.probe_green_aom,
t0 + tau_flir - tau_image / 2.0,
tau_all, # account for exposure delay
invert=True
)
+ Sequence.digital_pulse(
*C.probe_green_sh,
0.0,
t0 + tau_all
)
+ Sequence.digital_pulse(
*C.flir_trig,
t0 + tau_flir, # minimal TOF to allow everything to turn off
flir_config["exposure_time"] * 1e-6 # convert us -> s
)
).with_color("C2"),
"Reset": (Sequence()
+ Sequence.serial_bits_c(
C.mot3_coils_sig,
t0 + tau_all,
B_blue, bits_Bset,
AD5791_DAC, bits_DACset,
C.mot3_coils_clk, C.mot3_coils_sync
)
+ Sequence([
Event.analog(**c, s=c.default)
@ (t0 + tau_all + k * 1e-16) # have to offset times from e/o
for k, c in enumerate([
C.shim_coils_fb, C.shim_coils_lr, C.shim_coils_ud
])
])
+ Sequence([
Event.digital1(**c, s=c.default)
@ (t0 + tau_all - 4.5e-3 + k * 1e-16) # 4.5ms delay with offset from simultaneity
for k, (c, v) in enumerate([
(C.shim_coils_p_fb, shim_fb),
(C.shim_coils_p_lr, shim_lr),
(C.shim_coils_p_ud, shim_ud)
])
if v < 0.0
])
).with_color("C7"),
},
CONNECTIONS
)
sseq["Sequence"] = Sequence.digital_hilo(*C.dummy, 0.0, sseq.max_time() + 10e-3).with_color("0.25")
# mogramp_N is the number of steps, not points, so use mogramp_N + 1 for number of points
MOGRAMP_T = np.linspace(tau_freqpow, tau_freqpow + tau_freqpow_dur, mogramp_N + 1)
MOGRAMP_F = np.linspace(f_freqpow, f_freqpow + nu_freqpow, mogramp_N + 1)
MOGRAMP_P = np.linspace(p_freqpow_beg, p_freqpow_end, mogramp_N + 1)
tab = MOGTable()
# make sure the frequency/power is right at t0
tab << MOGEvent(frequency=MOGRAMP_F[0], power=MOGRAMP_P[0]) @ (0.0)
for t, f, p in zip(MOGRAMP_T, MOGRAMP_F, MOGRAMP_P):
tab << MOGEvent(frequency=f, power=p) @ t
# detune and depower the MOT beams for TOF after the CMOT hold
tab << MOGEvent(frequency=MOGRAMP_F[-1] + det_block, power=-50.0) \
@ (tau_ncool + 1.7e-3) # unknown source of timing errors
if not probe_image:
(tab
<< MOGEvent(frequency=aom_fiber_optim + det_image, power=p_image_cmot)
@ (tau_ncool + tau_tof + 1.7e-3) # unknown source of timing errors
<< MOGEvent(frequency=aom_fiber_optim + det_image + det_block, power=-50.0)
@ (tau_ncool + tau_tof + tau_image + 1.7e-3) # unknown source of timing errors
)
return sseq, tab
## SCRIPT CONTROLLER
class DailyMeasurement(Controller):
def precmd(self, *args):
self.comp = MAIN.connect()
self.comp.set_defaults()
if probe_image:
self.comp.def_digital(*C.probe_green_sh, 1)
# self.cam = FLIR.connect()
# self.cam.configure_capture(**flir_config).configure_trigger()
self.mog = MOGRF.connect()
self.tb = TIMEBASE.connect()
if probe_image:
self.tb.set_frequency(aom_fiber_optim + det_image0).set_amplitude(p_image)
# pre-construct all unique sequences and mogtables so we con't have to
# do it in the main loop
if self.mode == DailyMeasType.TOF:
# if doing TOF temperature
self.names = [
f"tau-tof={tau_tof:.5f}"
f"_det-image={det_image0:+.5f}"
f"_nu-freqpow={nu_freqpow0:+.5f}"
f"_{rep}"
for rep, tau_tof in product(range(reps), TAU_TOF)
]
self.ssequences, self.mogtables \
= zip(*[
make_sequences(
self.mode,
f"tau_tof={tau_tof:.5f}"
f"_det-image={det_image0:+.5f}"
f"_nu-freqpow={nu_freqpow0:+.5f}",
tau_tof,
det_image0,
nu_freqpow0,
) for tau_tof in TAU_TOF
])
self.sequences = [sseq.to_sequence() for sseq in self.ssequences]
elif self.mode == DailyMeasType.DET:
# if doing free-space resonance via CMOT release
self.names = [
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image:+.5f}"
f"_nu-freqpow={nu_freqpow0:+.5f}"
f"_{rep}"
for rep, det_image in product(range(reps), DET_IMAGE)
]
self.ssequences, self.mogtables \
= zip(*[
make_sequences(
self.mode,
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image:+.5f}"
f"_nu-freqpow={nu_freqpow0:+.5f}",
tau_tof0,
det_image,
nu_freqpow0,
) for det_image in DET_IMAGE
])
self.sequences = [sseq.to_sequence() for sseq in self.ssequences]
elif self.mode == DailyMeasType.CMOT_DET:
# if doing free-space resonance via CMOT detuning
self.names = [
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image0:+.5f}"
f"_nu-freqpow={nu_freqpow:+.5f}"
f"_{rep}"
for rep, nu_freqpow in product(range(reps), NU_FREQPOW)
]
self.ssequences, self.mogtables \
= zip(*[
make_sequences(
self.mode,
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image0:+.5f}"
f"_nu-freqpow={nu_freqpow:+.5f}",
tau_tof0,
det_image0,
nu_freqpow,
) for nu_freqpow in NU_FREQPOW
])
self.sequences = [sseq.to_sequence() for sseq in self.ssequences]
elif self.mode == DailyMeasType.BMOT_NUM:
# if measuring the blue MOT number
self.names = [
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image0:+.5f}"
f"_{rep}"
for rep in range(reps)
]
self.ssequences, self.mogtables \
= zip(*[
make_sequences(
self.mode,
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image0:+.5f}",
tau_tof0,
det_image0,
nu_freqpow0
)
])
self.sequences = [sseq.to_sequence() for sseq in self.ssequences]
elif self.mode == DailyMeasType.BMOT_DET:
# if doing free-space resonance via blue MOT release
self.names = [
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image:+.5f}"
f"_{rep}"
for rep, det_image in product(range(reps), DET_IMAGE)
]
self.ssequences, self.mogtables \
= zip(*[
make_sequences(
self.mode,
f"tau-tof={tau_tof0:.5f}"
f"_det-image={det_image:+.5f}",
tau_tof0,
det_image,
nu_freqpow0,
) for det_image in DET_IMAGE
])
self.sequences = [sseq.to_sequence() for sseq in self.ssequences]
else:
raise Exception
def run_sequence(self, *args):
for rep in range(reps):
for k, (seq, tab) in enumerate(zip(self.sequences, self.mogtables)):
if self.mode in {DailyMeasType.DET, DailyMeasType.BMOT_DET}:
self.tb.set_frequency(aom_fiber_optim + DET_IMAGE[k])
(self.mog
.set_frequency(1, 90.0).set_power(1, -50.0) # make sure CMOT AOM is off
.set_mode(1, "TSB")
.table_load(1, tab)
.table_arm(1)
.set_table_rearm(1, True)
)
self.comp.enqueue(seq).run().clear()
self.mog.table_stop(1).table_clear(1)
if take_background:
time.sleep(0.5)
sseq_bkgd = background_flir(
outdir.joinpath("sequences"),
exposure_time=flir_config["exposure_time"] * 1e-6, # convert us -> s
free_time=100e-3, # no trapping for 100ms
with_blue_beams=False,
with_green_beams=False,
with_probe_beams=False,
)
(self.comp
.enqueue(sseq_bkgd.to_sequence())
.run()
.clear()
)
self.comp.clear().set_defaults().disconnect()
(self.mog
.table_stop(1)
.table_clear(1)
.set_frequency(1, 90.0).set_power(1, 29.04)
.set_frequency(3, aom_fiber_optim + det_image0).set_power(3, p_image)
.set_frequency(4, aom_fiber_optim + det_image0).set_power(4, p_image)
.set_mode(1, "NSB")
.set_output(1, True)
.disconnect()
)
# def run_camera(self, *args):
# self.frames = self.cam.acquire_frames(
# num_frames=(
# len(self.names)
# + int(flir_prerelease) * len(self.names)
# + int(take_background)
# ),
# timeout=5, # s
# roi=[976, 740, 40, 40]
# )
# self.cam.disconnect()
def cmd_run(self, *args):
run_modes = {
"temperature": DailyMeasType.TOF,
"resonance": DailyMeasType.DET,
"tof_resonance": DailyMeasType.CMOT_DET,
"blue_mot_number": DailyMeasType.BMOT_NUM,
"blue_mot_resonance": DailyMeasType.BMOT_DET,
}
if len(args) < 1 or args[0] not in run_modes.keys():
print(
"Must provide subcommand"
f"\n one of {set(run_modes.keys())}"
)
sys.exit(0)
self.mode = run_modes[args[0]]
global dailies_config
dailies_config["mode"] = self.mode.name
self._perform_actions("run_", args[1:])
def on_error(self, ERR: Exception, *args):
# try to exit gracefully on error, even if it means this part is
# rather dirty
try:
self.comp.clear().disconnect()
except BaseException as err:
print(f"couldn't disconnect from computer"
f"\n{type(err).__name__}: {err}")
# try:
# self.cam.disconnect()
# except AttributeError:
# pass
# except BaseException as err:
# print(f"couldn't disconnect from Flir camera"
# f"\n{type(err).__name__}: {err}")
try:
(self.mog
.table_stop(1)
.table_clear(1)
.set_frequency(1, 90.0).set_power(1, 29.04)
.set_frequency(3, aom_fiber_optim + det_image0).set_power(3, p_image)
.set_frequency(4, aom_fiber_optim + det_image0).set_power(4, p_image)
.set_mode(1, "NSB")
.set_output(1, True)
.disconnect()
)
except BaseException as err:
print(f"couldn't reset MOGRF"
f"\n{type(err).__name__}: {err}")
def postcmd(self, *args):
pass
# names = list()
# for name in self.names:
# if flir_prerelease:
# avgimgdir = outdir.joinpath("images").joinpath("averages")
# avgimgdir_pre = avgimgdir.joinpath("pre")
# avgimgdir_pre.mkdir(parents=True, exist_ok=True)
# avgimgdir_post = avgimgdir.joinpath("post")
# avgimgdir_post.mkdir(parents=True, exist_ok=True)
# name_split = name.split("_")
# names.append(str(
# Path(avgimgdir_pre.name).joinpath(
# "_".join(name_split[:-1]) + "_pre_" + name_split[-1])
# ))
# names.append(str(
# Path(avgimgdir_post.name).joinpath(
# "_".join(name_split[:-1]) + "_post_" + name_split[-1])
# ))
# else:
# names.append(name)
# if take_background:
# names.append("background")
# arrays = { name: frame for name, frame in zip(names, self.frames) }
# data = DailyMeasurementData(
# outdir=outdir,
# arrays=arrays,
# config={ **flir_config, **dailies_config },
# comments=comments
# )
# try:
# data.compute_results(
# measurement_type=self.mode,
# size_fit=True,
# subtract_bkgd=take_background,
# debug=False,
# mot_number_params={ # for pre-release image
# # from measurement on 02.21.22
# "intensity_parameter": 2.0 * 3.55 * 10**(p_freqpow_end / 10.0),
# # from measurement on 02.15.22
# "detuning": abs(f_image0 - freespace_res) * 1e6 * 2.0 * np.pi,
# },
# N_det_peaks=4,
# )
# data.save(arrays=True)
# except Exception as err:
# print(
# f"[postcmd] encountered exception {type(err).__name__} while processing data:"
# f"\n{err}"
# )
# print("[postcmd] emergency-saving data")
# data.save(arrays=True)
# #data.render_arrays()
def cmd_visualize(self, *args):
run_modes = {
"temperature": DailyMeasType.TOF,
"resonance": DailyMeasType.DET,
"tof_resonance": DailyMeasType.CMOT_DET,
"blue_mot_number": DailyMeasType.BMOT_NUM,
"blue_mot_resonance": DailyMeasType.BMOT_DET,
}
if len(args) < 1 or args[0] not in run_modes.keys():
print(
"Must provide subcommand"
f"\n one of {set(run_modes.keys())}"
)
sys.exit(0)
self.mode = run_modes[args[0]]
if self.mode == DailyMeasType.TOF:
sseq, tab = make_sequences(self.mode, "", TAU_TOF.max(), det_image0, nu_freqpow0)
elif self.mode == DailyMeasType.DET:
sseq, tab = make_sequences(self.mode, "", tau_tof0, DET_IMAGE.max(), nu_freqpow0)
elif self.mode == DailyMeasType.CMOT_DET:
sseq, tab = make_sequences(self.mode, "", tau_tof0, det_image0, NU_FREQPOW.max())
elif self.mode == DailyMeasType.BMOT_NUM:
sseq, tab = make_sequences(self.mode, "", tau_tof0, det_image0, nu_freqpow0)
elif self.mode == DailyMeasType.BMOT_DET:
sseq, tab = make_sequences(self.mode, "", tau_tof0, DET_IMAGE.max(), nu_freqpow0)
try:
tmin, tmax = float(args[1]), float(args[2])
except IndexError:
tmin, tmax = sseq.min_time(), sseq.max_time()
sseq.draw_detailed(
mogtables=[
( tab.with_color("C6"), dict(name="Green MOT AOM", offset=t0) ),
] if self.mode not in {
DailyMeasType.BMOT_NUM,
DailyMeasType.BMOT_DET,
} else list()
).set_xlim(tmin, tmax).show()
sys.exit(0)
if __name__ == "__main__":
DailyMeasurement().RUN()