From 6bc7b1cc5957c640f55661f95f90fa4597ba7670 Mon Sep 17 00:00:00 2001 From: scexao5 Date: Fri, 16 Aug 2024 23:22:13 +0000 Subject: [PATCH] add some scripts and add vampires_ to some scripts --- conf/daemons/vampires_mprocs.yml | 5 +- docs/procedures/autofocus.md | 8 +- pyproject.toml | 9 +- src/vampires_control/autofocus_fieldstop.py | 2 +- .../calibration/photon_transfer_curve.py | 107 ++++++++---------- src/vampires_control/status/healthcheck.py | 2 +- src/vampires_control/strehl.py | 13 +++ 7 files changed, 78 insertions(+), 68 deletions(-) diff --git a/conf/daemons/vampires_mprocs.yml b/conf/daemons/vampires_mprocs.yml index aad7942..f45540a 100644 --- a/conf/daemons/vampires_mprocs.yml +++ b/conf/daemons/vampires_mprocs.yml @@ -5,7 +5,7 @@ procs: qwp daemon: "sleep 5; qwp_daemon" flc temp daemon: "sleep 5; vampires_temp_daemon" healthcheck: - shell: "healthcheck" + shell: "vampires_healthcheck" autostart: false prepare config: shell: "vampires_prep" @@ -36,4 +36,7 @@ procs: autostart: false badseeing: shell: "while true; do sl; done" + autostart: false + monitor strehl: + shell: "watch 'vampires_strehl vcam1'" autostart: false \ No newline at end of file diff --git a/docs/procedures/autofocus.md b/docs/procedures/autofocus.md index 2732679..f61a592 100644 --- a/docs/procedures/autofocus.md +++ b/docs/procedures/autofocus.md @@ -20,7 +20,7 @@ sonne $ vampires_camfocus dual ``` from here run ``` -sonne $ autofocus lens -c 2 +sonne $ vampires_autofocus lens -c 2 ``` and then save the outputs if everything looks good ``` @@ -28,7 +28,7 @@ sonne $ vampires_focus --save 1 ``` and now do the same for the converse stage- ``` -sonne $ autofocus cam -c 1 +sonne $ vampires_autofocus cam -c 1 sonne $ vampires_camfocus --save 1 ``` @@ -41,7 +41,7 @@ sonne $ vampires_camfocus dual ``` In theory the differential focus should not change with the introduction of the differential narrowband filters, so only the lens stage needs optimized- the following will only use the VCAM1 image to focus the lens ``` -sonne $ autofocus lens -c 1 +sonne $ vampires_autofocus lens -c 1 sonne $ vampires_focus --save 2 ``` @@ -50,7 +50,7 @@ Similar to the narrowband filter case, if any FIRST/VisPL pickoffs are in there ``` sonne $ vampires_focus vpl sonne $ vampires_camfocus dual -sonne $ autofocus lens -c 1 +sonne $ vampires_autofocus lens -c 1 sonne $ vampires_focus --save 4 ``` diff --git a/pyproject.toml b/pyproject.toml index bd7893a..45f2a5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,10 +55,11 @@ vampires_pauselog = "vampires_control.acquisition.acquire:pause_acquisition_main # configurations vampires_prep = "vampires_control.configurations.main:main" # health -healthcheck = "vampires_control.status.healthcheck:main" +vampires_healthcheck = "vampires_control.status.healthcheck:main" # calibrations -autofocus = "vampires_control.autofocus:main" -autofocus_fieldstop = "vampires_control.autofocus_fieldstop:main" +vampires_autofocus = "vampires_control.autofocus:main" +vampires_autofocus_fieldstop = "vampires_control.autofocus_fieldstop:main" +vampires_ptc = "vampires_control.calibration.photon_transfer_curve:main" # take_cals = "vampires_control.calibration.calibs:main" vampires_autodarks = "vampires_control.calibration.nightly_darks:main" filter_sweep = "vampires_control.calibration.filter_sweep:main" @@ -68,6 +69,8 @@ bs_calib = "vampires_control.calibration.bs_throughput:main" pol_calib = "vampires_control.calibration.polarization_calibration:main" drr_calib = "vampires_control.calibration.drr_calibration:main" vampires_hotspot = "vampires_control.hotspot:hotspot" +# strehl +vampires_strehl = "vampires_control.strehl:main" [tool.setuptools.dynamic] version = {attr = "vampires_control.__version__"} diff --git a/src/vampires_control/autofocus_fieldstop.py b/src/vampires_control/autofocus_fieldstop.py index f1fdf49..b2bffbf 100644 --- a/src/vampires_control/autofocus_fieldstop.py +++ b/src/vampires_control/autofocus_fieldstop.py @@ -82,7 +82,7 @@ def fit_optimal_focus(focus, metrics) -> float: @click.command( - "autofocus_fieldstop", + "vampires_autofocus_fieldstop", help="Optimize the focus using either the objective lens stage or the VCAM1 mount stage", ) @click.option( diff --git a/src/vampires_control/calibration/photon_transfer_curve.py b/src/vampires_control/calibration/photon_transfer_curve.py index b6c4903..2fd7fc4 100644 --- a/src/vampires_control/calibration/photon_transfer_curve.py +++ b/src/vampires_control/calibration/photon_transfer_curve.py @@ -7,9 +7,9 @@ import numpy as np import tqdm.auto as tqdm from astropy.io import fits -from pyMilk.interfacing.isio_shmlib import SHM from scxconf.pyrokeys import VAMPIRES, VCAM1, VCAM2 from swmain.network.pyroclient import connect +from vampires_control.acquisition.manager import VCAMLogManager # set up logging formatter = logging.Formatter("%(asctime)s|%(name)s|%(message)s", datefmt="%Y-%m-%d %H:%M:%S") @@ -20,91 +20,82 @@ stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) -SHMS = {1: SHM("vcam1"), 2: SHM("vcam2")} +exptimes_fast = (0.05) class PTCAcquirer: """ PTCAcquirer """ + TEXP_FAST = np.geomspace(7.2e-6, 0.05, 50) # works well for 15V 3A + TEXP_SLOW = np.geomspace(95e-3) def __init__(self, base_dir: Union[str, Path, None] = None): self.cameras = {1: connect(VCAM1), 2: connect(VCAM2)} - self.diffwheel = connect(VAMPIRES.DIFF) + self.managers = {c: VCAMLogManager(c) for c in (1, 2)} self.base_dir = Path.cwd() if base_dir is None else Path(base_dir) - def acquire(self, nframes): - with mp.Pool(2) as pool: - res1 = pool.apply_async(get_cube, args=(1, nframes)) - res2 = pool.apply_async(get_cube, args=(2, nframes)) - pool.close() - cubes = res1.get(), res2.get() - - return cubes - - def take_bias(self, nframes=1000): - logger.info("Nudging diffwheel to take bias frames") - self.diffwheel.move_absolute(31) - - for cam in self.cameras.values(): - cam.set_tint(0) - logger.info("Acquiring...") - cubes = self.acquire(nframes) - logger.info("Finished taking bias frames") - - logger.info("Opening diffwheel") - self.diffwheel.move_absolute(0) - - return cubes - - def take_data(self, exptimes, nframes=30, **kwargs): + def get_exposure_times(self): + # determine if we're in fast or slow readout mode + is_fast = [cam.get_readout_mode() == "FAST" for cam in self.cameras.values()] + if all(is_fast): + texp = self.TEXP_FAST + elif not any(is_fast): + texp = self.TEXP_SLOW + else: + msg = "Both cameras have different readout modes, please make them equal" + raise RuntimeError(msg) + + ndits = [mgr.fps.get_param("cubesize") for mgr in self.maanagers.values()] + assert ndits[0] == ndits[1], "There are different cube sizes for each camera" + total_tint = np.sum(texp * ndits[0]) + click.echo(f"Total integration time: {total_tint:.01f} s") + + return texp + + def run(self): + ## prepare for PTC + ## take PTC data logger.info("Beginning PTC acquisition") - total_time = np.sum(exptimes * nframes) - click.echo( - f"{nframes} frames for {len(exptimes)} acquisitions will take {np.floor_divide(total_time, 60):02.0f}:{np.remainder(total_time, 60):02.0f}" - ) + exptimes = self.get_exposure_times() + click.confirm("Confirm if ready to proceed", abort=True, default=True) - actual_exptimes = [] - cubes = [] pbar = tqdm.tqdm(exptimes) for exptime in pbar: - pbar.desc = f"t={exptime:4.02e} s" for cam in self.cameras.values(): tint = cam.set_tint(exptime) - actual_exptimes.append(tint) - cubes.append(np.array(self.acquire(nframes=nframes))) + pbar.desc = f"t={tint:4.02e} s" + self.acquire() logger.info("Finished taking PTC data") - return np.array(actual_exptimes), np.array(cubes) - def run(self, name, exptimes, nframes=30, nbias=1000, **kwargs): - ## take bias frames - bias_cubes = np.array(self.take_bias(nframes=nbias)) - bias_path = self.base_dir / f"{name}_bias.fits" - fits.writeto(bias_path, bias_cubes, overwrite=True) - ## prepare for PTC - click.confirm("Confirm when ready to proceed", abort=True, default=True) - ## take PTC data - exptimes, cubes = self.take_data(exptimes=exptimes, nframes=nframes) - ## save to disk - cube_path = self.base_dir / f"{name}_data.fits" - fits.writeto(cube_path, cubes, overwrite=True) - logger.info(f"Saved data to {cube_path}") - texp_path = self.base_dir / f"{name}_texp.fits" - fits.writeto(texp_path, exptimes, overwrite=True) - logger.info(f"Saved exposure times to {texp_path}") - return exptimes, cubes + def acquire(self): + with mp.Pool(2) as pool: + j1 = pool.apply_async(self.managers[1].acquire_cubes, args=(1,)) + j2 = pool.apply_async(self.managers[2].acquire_cubes, args=(1,)) + pool.close() + j1.get() + j2.get() -def get_cube(shm, nframes): - return SHMS[shm].multi_recv_data(nframes, output_as_cube=True, timeout=6) + def cleanup(self): + # when exiting, make sure camera loggers have stopped + for mgr in self.managers.values(): + mgr.pause_acquisition(wait_for_cube=False) + +@click.command("vampires_ptc") def main(): - pass + ptc = PTCAcquirer() + try: + ptc.run() + except Exception: + ptc.cleanup() + if __name__ == "__main__": diff --git a/src/vampires_control/status/healthcheck.py b/src/vampires_control/status/healthcheck.py index c93ef26..bc7a8be 100644 --- a/src/vampires_control/status/healthcheck.py +++ b/src/vampires_control/status/healthcheck.py @@ -47,7 +47,7 @@ def check_device(devname): ] -@click.command("healthcheck") +@click.command("vampires_healthcheck") def main(): click.echo("Checking VAMPIRES devices are connected") with mp.Pool() as pool: diff --git a/src/vampires_control/strehl.py b/src/vampires_control/strehl.py index f59824b..ccd7e32 100644 --- a/src/vampires_control/strehl.py +++ b/src/vampires_control/strehl.py @@ -200,3 +200,16 @@ def measure_strehl_shm(shm_name: str, psf=None, nave=10, pxscale=5.9, **kwargs): if shmkwds["U_CAMERA"] == 1: psf = np.flipud(psf) return measure_strehl(image, psf, pxscale=pxscale, **kwargs) + +import click +import warnings + +@click.command("vampires_strehl") +@click.argument("stream", type=click.Choice(["vcam1", "vcam2"])) +def main(stream: str): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + result = measure_strehl_shm(stream) + +if __name__ == "__main__": + main() \ No newline at end of file