quantnet-agent 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantnet_agent/__init__.py +1 -0
- quantnet_agent/cli.py +80 -0
- quantnet_agent/common/__init__.py +2 -0
- quantnet_agent/common/calibration_status.py +7 -0
- quantnet_agent/common/config.py +135 -0
- quantnet_agent/common/constants.py +28 -0
- quantnet_agent/common/logging.py +60 -0
- quantnet_agent/hal/HAL.py +231 -0
- quantnet_agent/hal/__init__.py +0 -0
- quantnet_agent/hal/driver/OZoptics.py +46 -0
- quantnet_agent/hal/driver/Thorlabs.py +39 -0
- quantnet_agent/hal/driver/__init__.py +0 -0
- quantnet_agent/hal/driver/artiq.py +124 -0
- quantnet_agent/hal/driver/dummy.py +373 -0
- quantnet_agent/hal/driver/overlayepc.py +27 -0
- quantnet_agent/hal/driver/overlayexpframework.py +47 -0
- quantnet_agent/hal/driver/overlaylightsrc.py +125 -0
- quantnet_agent/hal/driver/overlaymeter.py +58 -0
- quantnet_agent/hal/driver/simulator.py +345 -0
- quantnet_agent/hal/hwclasses.py +148 -0
- quantnet_agent/hal/interpreter/__init__.py +0 -0
- quantnet_agent/hal/interpreter/calibration.py +101 -0
- quantnet_agent/hal/interpreter/calibration_interpreter.py +43 -0
- quantnet_agent/hal/interpreter/dummy_cavity_calibration.py +16 -0
- quantnet_agent/hal/interpreter/dummy_lsrc_calibration.py +16 -0
- quantnet_agent/hal/interpreter/exp_framework.py +75 -0
- quantnet_agent/hal/interpreter/scheduler.py +35 -0
- quantnet_agent/hal/local_task_manager.py +249 -0
- quantnet_agent/hal/node.py +205 -0
- quantnet_agent/interpreter/test_interpreter.py +32 -0
- quantnet_agent/scheduler/__init__.py +0 -0
- quantnet_agent/scheduler/scheduler.py +483 -0
- quantnet_agent/service/__init__.py +1 -0
- quantnet_agent/service/agent.py +98 -0
- quantnet_agent/service/register.py +77 -0
- quantnet_agent-1.0.0.dist-info/METADATA +83 -0
- quantnet_agent-1.0.0.dist-info/RECORD +41 -0
- quantnet_agent-1.0.0.dist-info/WHEEL +5 -0
- quantnet_agent-1.0.0.dist-info/entry_points.txt +2 -0
- quantnet_agent-1.0.0.dist-info/licenses/LICENSE +41 -0
- quantnet_agent-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from sipyco.pc_rpc import Client
|
|
3
|
+
from sipyco.broadcast import Receiver
|
|
4
|
+
from quantnet_agent.hal.hwclasses import ExpFramework
|
|
5
|
+
import time
|
|
6
|
+
import asyncio
|
|
7
|
+
import numpy
|
|
8
|
+
|
|
9
|
+
log = logging.getLogger(__name__)
|
|
10
|
+
TIMEOUT = 10
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ArtiqClient(ExpFramework):
|
|
14
|
+
def __init__(self, property, node_config, mqhost, mqport):
|
|
15
|
+
self.expid_to_rid = {}
|
|
16
|
+
self.logs = {}
|
|
17
|
+
if "version" in property and int(property["version"]) == 7:
|
|
18
|
+
self.schedule, self.exps, self.datasets = [
|
|
19
|
+
Client(property["host"], property["port"], i) for i in "master_schedule master_experiment_db master_dataset_db".split()
|
|
20
|
+
]
|
|
21
|
+
else:
|
|
22
|
+
self.schedule, self.exps, self.datasets = [
|
|
23
|
+
Client(property["host"], property["port"], i) for i in "schedule experiment_db dataset_db".split()
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
asyncio.create_task(self._connect_and_receive_logs(property["host"], int(property["logging"])))
|
|
27
|
+
|
|
28
|
+
log.info(f"Initializing ARTIQ with {property['host']} : {property['logging']}")
|
|
29
|
+
|
|
30
|
+
async def _connect_and_receive_logs(self, host, port):
|
|
31
|
+
# Create the receiver instance
|
|
32
|
+
log_receiver = Receiver("log", [], None)
|
|
33
|
+
|
|
34
|
+
# Connect to the log service at the specified address and port
|
|
35
|
+
await log_receiver.connect(host, port)
|
|
36
|
+
|
|
37
|
+
# Register the callback function to receive log messages
|
|
38
|
+
log_receiver.notify_cbs.append(self._append_message)
|
|
39
|
+
|
|
40
|
+
while True:
|
|
41
|
+
# This loop keeps running to listen for incoming messages
|
|
42
|
+
await asyncio.sleep(1)
|
|
43
|
+
|
|
44
|
+
def _append_message(self, msg):
|
|
45
|
+
log.debug(f"Received a message from artiq: {msg}")
|
|
46
|
+
try:
|
|
47
|
+
if msg[1] == 'master':
|
|
48
|
+
rid = "master"
|
|
49
|
+
else:
|
|
50
|
+
rid = int(msg[1][msg[1].find("(") + 1: msg[1].find(",")])
|
|
51
|
+
|
|
52
|
+
if rid not in self.logs:
|
|
53
|
+
self.logs[rid] = ""
|
|
54
|
+
self.logs[rid] = self.logs[rid] + msg[3]
|
|
55
|
+
except Exception as e:
|
|
56
|
+
log.error(f"Error reading ARTIQ log: {e}")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
def reset(self):
|
|
60
|
+
log.info("Force deleting scheduled experiments")
|
|
61
|
+
for rid in self.schedule.get_status():
|
|
62
|
+
log.info(f"exp : {rid}")
|
|
63
|
+
self.schedule.delete(rid)
|
|
64
|
+
|
|
65
|
+
def stop(self):
|
|
66
|
+
log.info("Request for stopping experiments")
|
|
67
|
+
for rid in self.schedule.get_status():
|
|
68
|
+
log.info(f"exp : {rid}")
|
|
69
|
+
self.schedule.request_termination(rid)
|
|
70
|
+
|
|
71
|
+
def cleanUp(self):
|
|
72
|
+
self.stop()
|
|
73
|
+
|
|
74
|
+
def logs(self):
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
async def receive(self, *args, **kwargs):
|
|
78
|
+
exp_id = args[0]
|
|
79
|
+
rid = self.expid_to_rid[exp_id]
|
|
80
|
+
await self._wait_for_completion(rid)
|
|
81
|
+
if len(args) > 1:
|
|
82
|
+
params = args[1]
|
|
83
|
+
try:
|
|
84
|
+
results = {}
|
|
85
|
+
for param in params:
|
|
86
|
+
result = self.datasets.get(param)
|
|
87
|
+
if type(result) == numpy.ndarray:
|
|
88
|
+
result = result.tolist()
|
|
89
|
+
results[param] = result
|
|
90
|
+
return {f"status for rid {rid}": "done", "results": results}
|
|
91
|
+
except Exception as e:
|
|
92
|
+
logging.error(f"Failed to get result for exp {exp_id}: {e}")
|
|
93
|
+
return {f"status for rid {rid}": "done"}
|
|
94
|
+
else:
|
|
95
|
+
return {f"status for rid {rid}": "done"}
|
|
96
|
+
|
|
97
|
+
async def submit(self, exp_id, expName, classname, args=dict()):
|
|
98
|
+
args['use_db'] = True
|
|
99
|
+
expid = dict(
|
|
100
|
+
file=expName,
|
|
101
|
+
class_name=classname,
|
|
102
|
+
log_level=logging.WARNING,
|
|
103
|
+
arguments=args,
|
|
104
|
+
)
|
|
105
|
+
log.info(f"Submitting an experiment {expName}")
|
|
106
|
+
rid = self.schedule.submit(pipeline_name="main", expid=expid, priority=0, due_date=None, flush=False)
|
|
107
|
+
self.expid_to_rid[exp_id] = rid
|
|
108
|
+
if self._check_rid(rid):
|
|
109
|
+
log.info(f"experiment with id {rid} scheduled")
|
|
110
|
+
return 0
|
|
111
|
+
else:
|
|
112
|
+
log.error(f"submitted exp with rid {rid} not found")
|
|
113
|
+
raise Exception
|
|
114
|
+
|
|
115
|
+
async def _wait_for_completion(self, rid):
|
|
116
|
+
"""Wait for the experiment to complete."""
|
|
117
|
+
log.debug(f"Waiting for experiment {rid} to finish...")
|
|
118
|
+
while rid in self.schedule.get_status():
|
|
119
|
+
await asyncio.sleep(0.1)
|
|
120
|
+
self.logs
|
|
121
|
+
return 0
|
|
122
|
+
|
|
123
|
+
def _check_rid(self, rid):
|
|
124
|
+
return rid in self.schedule.get_status()
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
from quantnet_agent.hal.hwclasses import LightSrc, Filter, LightMeasurement, ExpFramework
|
|
2
|
+
import logging
|
|
3
|
+
import asyncio
|
|
4
|
+
import random
|
|
5
|
+
|
|
6
|
+
log = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DummyLightSrc(LightSrc):
|
|
10
|
+
|
|
11
|
+
def __init__(self, *args, **kwargs):
|
|
12
|
+
super().__init__(args, kwargs)
|
|
13
|
+
self._power = 0
|
|
14
|
+
self._wavelength = 0
|
|
15
|
+
self._status = 0
|
|
16
|
+
self._failrate = float(args[0].get("failrate", 0))
|
|
17
|
+
log.info("Initializing Dummy Lightsource")
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def wavelength(self):
|
|
22
|
+
return self._wavelength
|
|
23
|
+
|
|
24
|
+
@wavelength.setter
|
|
25
|
+
def wavelength(self, freq):
|
|
26
|
+
log.info(f"Setting wavelength to {freq}")
|
|
27
|
+
self._wavelength = freq
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def power(self):
|
|
31
|
+
return self._power
|
|
32
|
+
|
|
33
|
+
@power.setter
|
|
34
|
+
def power(self, power):
|
|
35
|
+
log.info(f"Setting power to {power}")
|
|
36
|
+
self._power = power
|
|
37
|
+
|
|
38
|
+
async def generate(self, pol):
|
|
39
|
+
log.info(f"Generating {pol} light with to power = {self._power}, wavelength = {self._wavelength}")
|
|
40
|
+
if random.random() < self._failrate:
|
|
41
|
+
log.error("Light source failed")
|
|
42
|
+
return 1
|
|
43
|
+
else:
|
|
44
|
+
log.info("Calibrating for 10 sec")
|
|
45
|
+
await asyncio.sleep(10)
|
|
46
|
+
return 0
|
|
47
|
+
|
|
48
|
+
async def cleanUp(self):
|
|
49
|
+
self._status = 0
|
|
50
|
+
log.info("Cleaning up for 10 sec")
|
|
51
|
+
await asyncio.sleep(10)
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def status(self):
|
|
56
|
+
return self._status
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DummyEPC(Filter):
|
|
60
|
+
|
|
61
|
+
def __init__(self, *args, **kwargs):
|
|
62
|
+
super().__init__(args, kwargs)
|
|
63
|
+
log.info("EPC initialized")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
async def polarize(self, _):
|
|
67
|
+
log.info("Calibrating link using EPC")
|
|
68
|
+
await asyncio.sleep(5)
|
|
69
|
+
log.info("Link calibrate")
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
async def attenuate(self, _):
|
|
73
|
+
log.info("Attenuate link using EPC")
|
|
74
|
+
await asyncio.sleep(5)
|
|
75
|
+
log.info("Link attenuated")
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
async def cleanUp(self):
|
|
79
|
+
self._status = 0
|
|
80
|
+
return 0
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class DummyPolarimeter(LightMeasurement):
|
|
84
|
+
|
|
85
|
+
def __init__(self, *args, **kwargs):
|
|
86
|
+
super().__init__(args, kwargs)
|
|
87
|
+
self._wavelength = 0
|
|
88
|
+
log.info(f"Initializing LightMeasurement with wavelength={self._wavelength}")
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def wavelength(self):
|
|
93
|
+
return self._wavelength
|
|
94
|
+
|
|
95
|
+
@wavelength.setter
|
|
96
|
+
def wavelength(self, freq):
|
|
97
|
+
log.info(f"Setting wavelength to {freq}")
|
|
98
|
+
self._wavelength = freq
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def power(self):
|
|
102
|
+
return self._power
|
|
103
|
+
|
|
104
|
+
def sweep(self):
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
async def measure(self):
|
|
108
|
+
log.info("Measuring SOP")
|
|
109
|
+
for i in range(5):
|
|
110
|
+
log.info(f"Generating random SOPs :[{random.random()},{random.random()},{random.random()}]")
|
|
111
|
+
await asyncio.sleep(1)
|
|
112
|
+
log.info("reached threashold SOP :[0.995, 0.995, 0.995]")
|
|
113
|
+
return 0
|
|
114
|
+
|
|
115
|
+
async def cleanUp(self):
|
|
116
|
+
self._status = 0
|
|
117
|
+
return 0
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class DummyExpFramework(ExpFramework):
|
|
121
|
+
|
|
122
|
+
def __init__(self, *args, **kwargs):
|
|
123
|
+
super().__init__(args, kwargs)
|
|
124
|
+
log.info("Initializing ExpFramework")
|
|
125
|
+
self.result_ind = 0
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
async def submit(self, exp_id, expName, classname, args=dict()):
|
|
129
|
+
log.info(f"Submitting exp:{expName} with id {id} with args:{args} for 10 sec")
|
|
130
|
+
# await asyncio.sleep(10)
|
|
131
|
+
return 0
|
|
132
|
+
|
|
133
|
+
async def receive(self, *args, **kwargs):
|
|
134
|
+
exp_id = args[0]
|
|
135
|
+
log.info(f"Receiving result from exp:{exp_id}")
|
|
136
|
+
results = [
|
|
137
|
+
{
|
|
138
|
+
"current_scan.plots.x": [
|
|
139
|
+
170000000.0,
|
|
140
|
+
172068965.5172414,
|
|
141
|
+
174137931.03448275,
|
|
142
|
+
176206896.55172414,
|
|
143
|
+
178275862.06896552,
|
|
144
|
+
180344827.58620688,
|
|
145
|
+
182413793.10344827,
|
|
146
|
+
184482758.62068966,
|
|
147
|
+
186551724.13793105,
|
|
148
|
+
188620689.6551724,
|
|
149
|
+
190689655.1724138,
|
|
150
|
+
192758620.68965518,
|
|
151
|
+
194827586.20689654,
|
|
152
|
+
196896551.72413793,
|
|
153
|
+
198965517.24137932,
|
|
154
|
+
201034482.75862068,
|
|
155
|
+
203103448.27586207,
|
|
156
|
+
205172413.79310346,
|
|
157
|
+
207241379.31034482,
|
|
158
|
+
209310344.8275862,
|
|
159
|
+
211379310.3448276,
|
|
160
|
+
213448275.86206895,
|
|
161
|
+
215517241.37931034,
|
|
162
|
+
217586206.89655173,
|
|
163
|
+
219655172.4137931,
|
|
164
|
+
221724137.93103448,
|
|
165
|
+
223793103.44827586,
|
|
166
|
+
225862068.96551722,
|
|
167
|
+
227931034.4827586,
|
|
168
|
+
230000000.0,
|
|
169
|
+
],
|
|
170
|
+
"current_scan.plots.y": [
|
|
171
|
+
[1896.0],
|
|
172
|
+
[1715.0],
|
|
173
|
+
[1913.0],
|
|
174
|
+
[1844.0],
|
|
175
|
+
[2061.0],
|
|
176
|
+
[1977.0],
|
|
177
|
+
[1936.0],
|
|
178
|
+
[2039.0],
|
|
179
|
+
[1937.0],
|
|
180
|
+
[2319.0],
|
|
181
|
+
[2458.0],
|
|
182
|
+
[2743.0],
|
|
183
|
+
[2943.0],
|
|
184
|
+
[3469.0],
|
|
185
|
+
[4059.0],
|
|
186
|
+
[4817.0],
|
|
187
|
+
[5377.0],
|
|
188
|
+
[5807.0],
|
|
189
|
+
[6039.0],
|
|
190
|
+
[6113.0],
|
|
191
|
+
[4882.0],
|
|
192
|
+
[3784.0],
|
|
193
|
+
[3607.0],
|
|
194
|
+
[4132.0],
|
|
195
|
+
[4200.0],
|
|
196
|
+
[4517.0],
|
|
197
|
+
[4693.0],
|
|
198
|
+
[5064.0],
|
|
199
|
+
[5146.0],
|
|
200
|
+
[2963.0],
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"current_scan.plots.x": [
|
|
205
|
+
30.0,
|
|
206
|
+
28.94736842105263,
|
|
207
|
+
27.894736842105264,
|
|
208
|
+
26.842105263157894,
|
|
209
|
+
25.789473684210527,
|
|
210
|
+
24.736842105263158,
|
|
211
|
+
23.684210526315788,
|
|
212
|
+
22.63157894736842,
|
|
213
|
+
21.578947368421055,
|
|
214
|
+
20.526315789473685,
|
|
215
|
+
19.473684210526315,
|
|
216
|
+
18.42105263157895,
|
|
217
|
+
17.36842105263158,
|
|
218
|
+
16.315789473684212,
|
|
219
|
+
15.263157894736842,
|
|
220
|
+
14.210526315789474,
|
|
221
|
+
13.157894736842106,
|
|
222
|
+
12.105263157894736,
|
|
223
|
+
11.05263157894737,
|
|
224
|
+
10.0,
|
|
225
|
+
],
|
|
226
|
+
"current_scan.plots.y": [
|
|
227
|
+
[-2.0],
|
|
228
|
+
[-26.0],
|
|
229
|
+
[15.0],
|
|
230
|
+
[4.0],
|
|
231
|
+
[-31.0],
|
|
232
|
+
[-14.0],
|
|
233
|
+
[69.0],
|
|
234
|
+
[63.0],
|
|
235
|
+
[149.0],
|
|
236
|
+
[177.0],
|
|
237
|
+
[494.0],
|
|
238
|
+
[576.0],
|
|
239
|
+
[1112.0],
|
|
240
|
+
[2253.0],
|
|
241
|
+
[2947.0],
|
|
242
|
+
[3776.0],
|
|
243
|
+
[4876.0],
|
|
244
|
+
[5963.0],
|
|
245
|
+
[7261.0],
|
|
246
|
+
[8522.0],
|
|
247
|
+
],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"current_scan.plots.x": [
|
|
251
|
+
60000000.0,
|
|
252
|
+
61379310.344827585,
|
|
253
|
+
62758620.68965517,
|
|
254
|
+
64137931.03448276,
|
|
255
|
+
65517241.37931035,
|
|
256
|
+
66896551.72413793,
|
|
257
|
+
68275862.06896552,
|
|
258
|
+
69655172.4137931,
|
|
259
|
+
71034482.7586207,
|
|
260
|
+
72413793.10344827,
|
|
261
|
+
73793103.44827586,
|
|
262
|
+
75172413.79310346,
|
|
263
|
+
76551724.13793103,
|
|
264
|
+
77931034.48275863,
|
|
265
|
+
79310344.8275862,
|
|
266
|
+
80689655.1724138,
|
|
267
|
+
82068965.51724139,
|
|
268
|
+
83448275.86206897,
|
|
269
|
+
84827586.20689656,
|
|
270
|
+
86206896.55172414,
|
|
271
|
+
87586206.89655173,
|
|
272
|
+
88965517.24137932,
|
|
273
|
+
90344827.5862069,
|
|
274
|
+
91724137.93103449,
|
|
275
|
+
93103448.27586207,
|
|
276
|
+
94482758.62068966,
|
|
277
|
+
95862068.96551725,
|
|
278
|
+
97241379.31034483,
|
|
279
|
+
98620689.65517241,
|
|
280
|
+
100000000.0,
|
|
281
|
+
],
|
|
282
|
+
"current_scan.plots.y": [
|
|
283
|
+
[3034.0],
|
|
284
|
+
[3063.0],
|
|
285
|
+
[3198.0],
|
|
286
|
+
[3290.0],
|
|
287
|
+
[3017.0],
|
|
288
|
+
[3097.0],
|
|
289
|
+
[3066.0],
|
|
290
|
+
[3188.0],
|
|
291
|
+
[3201.0],
|
|
292
|
+
[3348.0],
|
|
293
|
+
[3278.0],
|
|
294
|
+
[3243.0],
|
|
295
|
+
[3223.0],
|
|
296
|
+
[3145.0],
|
|
297
|
+
[3238.0],
|
|
298
|
+
[3159.0],
|
|
299
|
+
[3193.0],
|
|
300
|
+
[3328.0],
|
|
301
|
+
[3227.0],
|
|
302
|
+
[3342.0],
|
|
303
|
+
[3338.0],
|
|
304
|
+
[3433.0],
|
|
305
|
+
[3293.0],
|
|
306
|
+
[3261.0],
|
|
307
|
+
[3205.0],
|
|
308
|
+
[3437.0],
|
|
309
|
+
[3306.0],
|
|
310
|
+
[3325.0],
|
|
311
|
+
[3359.0],
|
|
312
|
+
[3394.0],
|
|
313
|
+
],
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"current_scan.plots.x": [
|
|
317
|
+
30.0,
|
|
318
|
+
28.94736842105263,
|
|
319
|
+
27.894736842105264,
|
|
320
|
+
26.842105263157894,
|
|
321
|
+
25.789473684210527,
|
|
322
|
+
24.736842105263158,
|
|
323
|
+
23.684210526315788,
|
|
324
|
+
22.63157894736842,
|
|
325
|
+
21.578947368421055,
|
|
326
|
+
20.526315789473685,
|
|
327
|
+
19.473684210526315,
|
|
328
|
+
18.42105263157895,
|
|
329
|
+
17.36842105263158,
|
|
330
|
+
16.315789473684212,
|
|
331
|
+
15.263157894736842,
|
|
332
|
+
14.210526315789474,
|
|
333
|
+
13.157894736842106,
|
|
334
|
+
12.105263157894736,
|
|
335
|
+
11.05263157894737,
|
|
336
|
+
10.0,
|
|
337
|
+
],
|
|
338
|
+
"current_scan.plots.y": [
|
|
339
|
+
[3514.0],
|
|
340
|
+
[3372.0],
|
|
341
|
+
[3508.0],
|
|
342
|
+
[3575.0],
|
|
343
|
+
[3508.0],
|
|
344
|
+
[3536.0],
|
|
345
|
+
[3671.0],
|
|
346
|
+
[3489.0],
|
|
347
|
+
[3597.0],
|
|
348
|
+
[3494.0],
|
|
349
|
+
[3596.0],
|
|
350
|
+
[3576.0],
|
|
351
|
+
[3661.0],
|
|
352
|
+
[3721.0],
|
|
353
|
+
[3531.0],
|
|
354
|
+
[3609.0],
|
|
355
|
+
[3596.0],
|
|
356
|
+
[3626.0],
|
|
357
|
+
[3681.0],
|
|
358
|
+
[3543.0],
|
|
359
|
+
],
|
|
360
|
+
},
|
|
361
|
+
]
|
|
362
|
+
index = self.result_ind % 4
|
|
363
|
+
self.result_ind += 1
|
|
364
|
+
return {"dummy status": "done", "results": results[index]}
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def logs(self):
|
|
368
|
+
log.info("Getting log from ExpFramework")
|
|
369
|
+
return "Dummy logs"
|
|
370
|
+
|
|
371
|
+
async def cleanUp(self):
|
|
372
|
+
self._status = 0
|
|
373
|
+
return 0
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from quantnet_agent.hal.hwclasses import Filter
|
|
2
|
+
import logging
|
|
3
|
+
import socket
|
|
4
|
+
|
|
5
|
+
log = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OverlayEPC(Filter):
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
log.info("Initializing EPC hardware")
|
|
12
|
+
return 0
|
|
13
|
+
|
|
14
|
+
def polarize(self, _):
|
|
15
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
16
|
+
s.connect(("10.0.0.7", 5006))
|
|
17
|
+
s.send(b"calibrate")
|
|
18
|
+
result = s.recv(1024)
|
|
19
|
+
if result == b"OK":
|
|
20
|
+
return
|
|
21
|
+
elif result == b"Not OK":
|
|
22
|
+
raise Exception
|
|
23
|
+
else:
|
|
24
|
+
raise Exception
|
|
25
|
+
|
|
26
|
+
def attenuate(self, strength):
|
|
27
|
+
return super().attenuate(strength)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from quantnet_agent.hal.hwclasses import ExpFramework
|
|
2
|
+
import logging
|
|
3
|
+
import socket
|
|
4
|
+
import asyncio
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
log = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class OverlayExpFramework(ExpFramework):
|
|
11
|
+
|
|
12
|
+
def __init__(self, *args, **kwargs):
|
|
13
|
+
props = args[0]
|
|
14
|
+
self.bsm_ip = props['bsm_ip']
|
|
15
|
+
self.bsm_port = int(props['bsm_port'])
|
|
16
|
+
super().__init__(*args, **kwargs)
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def status(self):
|
|
20
|
+
return self._status
|
|
21
|
+
|
|
22
|
+
async def submit(self, exp_id, expName, classname, args=dict()):
|
|
23
|
+
log.info(f"submitting bsm to {self.bsm_ip}")
|
|
24
|
+
await self._send_message_async(self.bsm_ip, self.bsm_port, b'bsm')
|
|
25
|
+
|
|
26
|
+
def receive(self, exp_id):
|
|
27
|
+
return {"result": ""}
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def logs(self):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
async def cleanUp(self):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
async def _send_message_async(self, ip, port, msg):
|
|
37
|
+
loop = asyncio.get_event_loop()
|
|
38
|
+
await loop.run_in_executor(None, self._send_message, ip, port, msg)
|
|
39
|
+
|
|
40
|
+
def _send_message(self, ip, port, msg):
|
|
41
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
42
|
+
s.connect((ip, port))
|
|
43
|
+
s.sendall(msg)
|
|
44
|
+
result = s.recv(1024)
|
|
45
|
+
if result != b'0':
|
|
46
|
+
raise Exception(f"Failed to handle {msg}")
|
|
47
|
+
s.close()
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
from quantnet_agent.hal.hwclasses import LightSrc
|
|
2
|
+
|
|
3
|
+
import serial
|
|
4
|
+
import time
|
|
5
|
+
import socket
|
|
6
|
+
import asyncio
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
polH = "S 4\n"
|
|
13
|
+
polD = "S 5\n"
|
|
14
|
+
polV = "S 6\n"
|
|
15
|
+
polA = "S 7\n"
|
|
16
|
+
polLCP = "S 2\n"
|
|
17
|
+
polRCP = "S 13\n"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OverlayLightSrc(LightSrc):
|
|
21
|
+
def __init__(self, *args, **kwargs):
|
|
22
|
+
log.info("Initializing overlay LightSource")
|
|
23
|
+
props = args[0]
|
|
24
|
+
self.serial_dev = props['device']
|
|
25
|
+
self.baud_rate = props['baud_rate']
|
|
26
|
+
self.bsm_ip = props['bsm_ip']
|
|
27
|
+
self.bsm_port = int(props['bsm_port'])
|
|
28
|
+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
29
|
+
self.sock.bind(("0.0.0.0", 5005))
|
|
30
|
+
self.sock.setblocking(False)
|
|
31
|
+
asyncio.create_task(self.serve())
|
|
32
|
+
super().__init__(args, kwargs)
|
|
33
|
+
|
|
34
|
+
def src_init(self, request):
|
|
35
|
+
return 0
|
|
36
|
+
|
|
37
|
+
async def serve(self):
|
|
38
|
+
loop = asyncio.get_running_loop()
|
|
39
|
+
self.dev_PSG, self.msg_device = self._connect()
|
|
40
|
+
while True:
|
|
41
|
+
log.info("Waiting for data")
|
|
42
|
+
data = await loop.sock_recv(self.sock, 1024)
|
|
43
|
+
log.info(data)
|
|
44
|
+
msg_devflag, msg_write, msg_read, polset_error = self._polSET(data.decode())
|
|
45
|
+
complete_msg = msg_devflag + "\n" + msg_write + "\n" + msg_read + "\n" + polset_error
|
|
46
|
+
log.info(complete_msg)
|
|
47
|
+
self.sock.sendto(complete_msg.encode(), (self.bsm_ip, self.bsm_port))
|
|
48
|
+
|
|
49
|
+
async def generate(self, _):
|
|
50
|
+
return 0
|
|
51
|
+
|
|
52
|
+
def is_device_connected(self, port_name):
|
|
53
|
+
try:
|
|
54
|
+
ser = serial.Serial(port_name)
|
|
55
|
+
ser.close()
|
|
56
|
+
return True
|
|
57
|
+
except serial.SerialException:
|
|
58
|
+
return False
|
|
59
|
+
|
|
60
|
+
def _connect(self):
|
|
61
|
+
try:
|
|
62
|
+
dev = serial.Serial(port=self.serial_dev, baudrate=self.baud_rate, timeout=0.1)
|
|
63
|
+
except Exception as e:
|
|
64
|
+
log.error(f"Could not connect to serial port {self.serial_dev}: {e}")
|
|
65
|
+
return None, ""
|
|
66
|
+
log.info(dev.name)
|
|
67
|
+
msg_device = "####### PSG is connected ############# "
|
|
68
|
+
log.info(msg_device)
|
|
69
|
+
return dev, msg_device
|
|
70
|
+
|
|
71
|
+
def _polSET(self, PSGpol):
|
|
72
|
+
try:
|
|
73
|
+
dev_connected_flag = self.is_device_connected(self.serial_dev)
|
|
74
|
+
|
|
75
|
+
if dev_connected_flag:
|
|
76
|
+
msg_devflag = "device connected flag:1, PSG is already connected"
|
|
77
|
+
log.info(msg_devflag)
|
|
78
|
+
else:
|
|
79
|
+
msg_devflag = "device connected flag:0, PSG was not connected. Connecting now"
|
|
80
|
+
log.info(msg_devflag)
|
|
81
|
+
self.dev_PSG, self.msg_device = self._connect()
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
self.dev_PSG.write(PSGpol.encode())
|
|
85
|
+
msg_write = "Written: Ok"
|
|
86
|
+
log.info(msg_write)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
log.info(e)
|
|
89
|
+
msg_write = "Write ISSUE"
|
|
90
|
+
log.info(msg_write)
|
|
91
|
+
|
|
92
|
+
time.sleep(1)
|
|
93
|
+
try:
|
|
94
|
+
self.dev_PSG.read(20)
|
|
95
|
+
msg_read = "Read: Ok"
|
|
96
|
+
log.info(msg_read)
|
|
97
|
+
except Exception as e:
|
|
98
|
+
log.info(e)
|
|
99
|
+
msg_read = "Read Issue"
|
|
100
|
+
polset_error = "Polset error None"
|
|
101
|
+
log.info(polset_error)
|
|
102
|
+
except Exception as e:
|
|
103
|
+
polset_error = f"Polarization: Could NOT set: {e}"
|
|
104
|
+
log.info(polset_error)
|
|
105
|
+
|
|
106
|
+
return msg_devflag, msg_write, msg_read, polset_error
|
|
107
|
+
|
|
108
|
+
def _disconnect(self, dev):
|
|
109
|
+
try:
|
|
110
|
+
msg_disconnect = "####### PSG is disconnected ############# "
|
|
111
|
+
log.info(msg_disconnect)
|
|
112
|
+
dev.close
|
|
113
|
+
except Exception:
|
|
114
|
+
msg_disconnect = "PSG: Could NOT disconnect"
|
|
115
|
+
|
|
116
|
+
return msg_disconnect
|
|
117
|
+
|
|
118
|
+
def wavelength(self, freq):
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
def power(self, power):
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
async def cleanUp(self):
|
|
125
|
+
return 0
|