Skip to content

Commit

Permalink
add some scripts and add vampires_ to some scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
scexao5 committed Aug 16, 2024
1 parent 47bd5ae commit 6bc7b1c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 68 deletions.
5 changes: 4 additions & 1 deletion conf/daemons/vampires_mprocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
8 changes: 4 additions & 4 deletions docs/procedures/autofocus.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ 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
```
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
```

Expand All @@ -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
```

Expand All @@ -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
```

Expand Down
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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__"}
Expand Down
2 changes: 1 addition & 1 deletion src/vampires_control/autofocus_fieldstop.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
107 changes: 49 additions & 58 deletions src/vampires_control/calibration/photon_transfer_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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__":
Expand Down
2 changes: 1 addition & 1 deletion src/vampires_control/status/healthcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
13 changes: 13 additions & 0 deletions src/vampires_control/strehl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 6bc7b1c

Please sign in to comment.