-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase.py
More file actions
194 lines (176 loc) · 7.67 KB
/
Copy pathbase.py
File metadata and controls
194 lines (176 loc) · 7.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#coding: utf8
import plscripts.links
import os
import time
from pyMilk.interfacing.fps import FPS
from swmain import redis
import glob
from astropy.io import fits
from pyMilk.interfacing.isio_shmlib import SHM as shm
# defines some shell commands to interact with other processes
SET_TIMEOUT_COMMAND = "setval streamFITSlog-firstpl.procinfo.triggertimeout {timeout}"
# helper to remake proper filename from truncated/compressed stuff in the shm
def _remake_filename(truncated):
filename = "firstpl_"+truncated[0:2]+":"+truncated[2:4]+":"+truncated[4:]+".fits"
return filename
class Base(object):
def __init__(self):
self._cam = None
self._fcam = None
self._ld = None
self._scripts = None
self._db = None
self._config = None
self._zab = None
self.logger_firstpl = FPS('streamFITSlog-firstpl')
#self.logger_fpupcam = FPS('streamFITSlog-fpupcam')
self._shm_var = shm("firstpl_merger_status")
def _linkit(self):
self._cam = plscripts.links.cam
# self._fcam = plscripts.links.fcam
self._ld = plscripts.links.ld
self._scripts = plscripts.links.scripts
self._db = plscripts.links.db
self._config = plscripts.links.config
self._zab = plscripts.links.zab
def _set_with_check(self, key, value, timeout = 5, fpupcam=False):
"""
attempt to set given key with given value in fits logger multiple times until
the logger returns the correct state
"""
logger = self.logger_fpupcam if fpupcam else self.logger_firstpl
logger.set_param(key, value)
t0 = time.time()
while (logger.get_param(key) != value):
time.sleep(0.1)
if time.time() - t0 > timeout:
camera_string = "fpupcam" if fpupcam else "firstpl"
raise Exception("timeout when setting {} to {} in logger {}".format(key, value, camera_string))
logger.set_param(key, value)
time.sleep(0.1)
return None
@staticmethod
def get_keyword(keyword):
"""
retrieve a telescope keyword from the redis server
"""
return redis.get_values([keyword])[keyword]
def update_keywords(self, keywords):
"""
update the keywords given as a dict {"keyword": value}, both in redis and in camera
"""
redis.update_keys(**keywords)
for key in keywords.keys():
self._cam.set_keyword(key, keywords[key])
return None
def prepare_fitslogger(self, nimages = None, ncubes = None, fpupcam=False):
"""
send shell command to the fits logger to prepare for saving ncubes with nimages in each
"""
if (nimages is None) or (ncubes is None):
return None
self.switch_fitslogger(False, fpupcam=fpupcam)
self._set_with_check("cubesize", nimages, fpupcam=fpupcam)
self._set_with_check("maxfilecnt", ncubes, fpupcam=fpupcam)
# remove any existing shm logbuffers
if fpupcam:
shm_prefix = "fpupcam"
else:
shm_prefix = "firstpl"
if os.path.isfile(f'/milk/shm/{shm_prefix}_logbuff0.im.shm') is True:
os.system(f'rm /milk/shm/{shm_prefix}_logbuff0.im.shm')
if os.path.isfile(f'/milk/shm/{shm_prefix}_logbuff1.im.shm') is True:
os.system(f'rm /milk/shm/{shm_prefix}_logbuff1.im.shm')
self.switch_fitslogger(True, fpupcam=fpupcam)
time.sleep(3) # to give it enough time to build the 2 logbuffers
self._set_with_check("saveON", True, fpupcam=fpupcam)
return None
def _send_command_fitslogger(self, command):
"""
send the given string command to the fifo of the fits logger
"""
os.system('echo "{}" > {}'.format(command, self._config["fitslogger_fifo"]))
return None
def set_fitslogger_timeout(self, timeout):
"""
change the timeout for the loop of the fits logger to avoid exiting without doing anything
"""
# self._send_command_fitslogger(SET_TIMEOUT_COMMAND.format(timeout = timeout))
self._set_with_check("procinfo.triggertimeout", timeout)
return None
def set_fitslogger_logdir(self, dirname, fpupcam=False):
"""
change the dirname where FITS are saved in the fits logger
"""
if not os.path.exists(dirname):
os.makedirs(dirname)
self._set_with_check("dirname", dirname, fpupcam=fpupcam)
return None
def get_fitslogger_logdir(self, fpupcam=False):
"""
interacts with the fits logger to get the path where data are currently saved
"""
logger = self.logger_fpupcam if fpupcam else self.logger_firstpl
dirname = logger.get_param("dirname")
return dirname
def switch_fitslogger(self, state, timeout = 10, fpupcam=False):
"""
Turn on/off the fits logger
"""
logger = self.logger_fpupcam if fpupcam else self.logger_firstpl
t0 = time.time()
while (logger.run_isrunning() != state):
time.sleep(0.1)
if time.time() - t0 > timeout:
raise Exception("Timeout while switching the fitslogger to {}".format(state))
if state:
logger.run_start()
else:
logger.run_stop()
time.sleep(0.1)
if not(state):
self._set_with_check("saveON", False, fpupcam=fpupcam)
return None
def wait_for_file_ready(self, validate_file = True, timeout = 10):
"""
pool the content of a directory (by default from the logger) until a new file appears.
Can also wait until the new file as a valid content
"""
self._shm_var._attempt_autorelink_if_needed()
status = self._shm_var.get_keywords()
nfiles_processed_before = status["nfiles_done"]
nfiles_processed = nfiles_processed_before
t0 = time.time()
while not(nfiles_processed > nfiles_processed_before):
time.sleep(0.1)
status = self._shm_var.get_keywords()
nfiles_processed = status["nfiles_done"]
if (time.time() - t0) > timeout:
raise Exception("Timeout!")
if validate_file:
return status["last_done"]
else:
return True
# def _verify_files_are_done(self, folder, expected_number_of_files, expected_time_taken=10, verbose=False):
# """
# Verify in a folder is all the expected cubes have been created. Timeout after expected_time_taken in seconds.
# """
# folder = str(folder)
# filenames_start = glob.glob(folder + "/*.fits")
# filenames = glob.glob(folder + "/*.fits")
# t0 = time.time()
# timeout = expected_time_taken * expected_number_of_files
# if verbose:
# print(len(filenames_start), " files detected in the save_to folder, we expect to find ",expected_number_of_files," more after this call.")
# print("We will timeout after ", timeout, " seconds.")
# while len(filenames) < len(filenames_start) + expected_number_of_files:
# time.sleep(0.1)
# filenames = glob.glob(folder + "/*.fits")
# if (time.time() - t0) > timeout:
# continue
# nb_files_done = len(filenames) - len(filenames_start)
# if nb_files_done == expected_number_of_files:
# return True
# else :
# print(f"Timeout, {nb_files_done} created instead of {expected_number_of_files}")
# return False