def setUp(self): # create 2 children and then combine one axis each with MultiplexActuator self.child1 = simulated.Stage("sstage1", "test", {"a", "b"}) self.child2 = simulated.Stage("sstage2", "test", {"cccc", "ddd"}) self.dev = self.actuator_type("stage", "stage", children={"x": self.child1, "y": self.child2}, axes_map={"x": "a", "y": "ddd"}, )
def setUp(self): # create 2 children and then combine one axis each with CombinedActuator self.child1 = simulated.Stage("sstage1", "test", {"a", "b"}) self.child2 = simulated.Stage("sstage2", "test", {"c", "d"}) self.dev = self.actuator_type("stage", "stage", { "x": self.child1, "y": self.child2 }, { "x": "a", "y": "d" })
def setUpClass(cls): cls.tc_act = simulated.Stage( "stage", "", ["shutter0", "shutter1"], { "shutter0": (0, 1), "shutter1": (0, 1) }, ) cls.shutter0 = actuator.MultiplexActuator("Shutter 0", "shutter0", {"x": cls.tc_act}, {"x": "shutter0"}) cls.shutter1 = actuator.MultiplexActuator("Shutter 1", "shutter1", {"x": cls.tc_act}, {"x": "shutter1"}) cls.dev = picoquant.HH400(children={ "detector0": CONFIG_SYNC, "detector1": CONFIG_DET1 }, dependencies={ "shutter0": cls.shutter0, "shutter1": cls.shutter1 }, **HH400_KWARGS) for child in cls.dev.children.value: if child.name == CONFIG_SYNC["name"]: cls.det0 = child elif child.name == CONFIG_DET1["name"]: cls.det1 = child
def test_move_update(self): child = simulated.Stage("stage", "test", axes=["z"]) # Slow speed to give some chance of the move update to work child.speed.value = {"z": 100e-6} stage = AntiBacklashActuator("absact", "abs", {"orig": child}, backlash={"z": 100e-6}) self.called = 0 orig_pos = stage.position.value stage.position.subscribe(self._on_position) for i in range(10): if i % 2: d = 1 else: d = -1 dist = d * (i + 1) * 10e-6 f = stage.moveRel({"z": dist}, update=True) time.sleep(0.05) # 50 ms for 'user update' f = stage.moveAbs(orig_pos, update=True) f.result() # If there is an antibacklash for each move against backlash, we should # see ~ 16 moves. If only an antibacklash at the last move # (or integrated in last move), we should see 11 or 12 moves. self.assertLessEqual(self.called, 12) test.assert_pos_almost_equal(child.position.value, orig_pos) stage.terminate()
def test_simple(self): child = simulated.Stage("stage", "test", axes=["x", "y"]) stage = AntiBacklashActuator("absact", "align", {"orig": child}, backlash={"x": 100e-6, "y": -80e-6}) # moves should just go the same positions # abs test.assert_pos_almost_equal(stage.position.value, {"x": 0, "y": 0}) f = stage.moveAbs({"x": 1e-06, "y": 2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 1e-06, "y": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"x": 1e-06, "y": 2e-06}) f = stage.moveAbs({"x": 0, "y": 0}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 0, "y": 0}) test.assert_pos_almost_equal(child.position.value, {"x": 0, "y": 0}) f = stage.moveAbs({"x": -23e-06, "y": -15e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x":-23e-06, "y":-15e-06}) test.assert_pos_almost_equal(child.position.value, {"x":-23e-06, "y":-15e-06}) # rel f = stage.moveAbs({"x": 0, "y": 0}) f = stage.moveRel({"x": 1e-06, "y": 2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 1e-06, "y": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"x": 1e-06, "y": 2e-06}) f = stage.moveRel({"x": 0, "y": 0}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 1e-06, "y": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"x": 1e-06, "y": 2e-06}) f = stage.moveRel({"x": -1e-06, "y": -2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 0, "y": 0}) test.assert_pos_almost_equal(child.position.value, {"x": 0, "y": 0})
def setUp(self): # create 2 children and then combine one axis each with MultiplexActuator self.child1 = simulated.Stage("sstage1", "test", {"a"}) self.dev_normal = self.actuator_type("stage", "stage", {"x": self.child1}, "a", {0: "pos0", 0.01: "pos1", 0.02: "pos2", 0.03: "pos3", 0.04: "pos4", 0.05: "pos5"}) self.dev_cycle = self.actuator_type("stage", "stage", {"x": self.child1}, "a", {0: "pos0", 0.01: "pos1", 0.02: "pos2", 0.03: "pos3", 0.04: "pos4", 0.05: "pos5"}, cycle=0.06)
def test_error(self): child = simulated.Stage("stage", "test", axes=["a", "b"]) # backlash on non-existing axis with self.assertRaises(ValueError): stage = AntiBacklashActuator("absact", "align", {"orig": child}, backlash={"a": 100e-6, "x": 50e-6}) # move on non-existing axis stage = AntiBacklashActuator("absact", "align", {"orig": child}, backlash={"a": 100e-6, "b": 50e-6}) with self.assertRaises(ValueError): stage.moveRel({"a": -5e-6, "x": 5e-6})
def test_ab_rotation(self): """ Test typical rotation stage for the SECOM v1 A/B alignment """ child = simulated.Stage("stage", "test", axes=["a", "b"]) stage = ConvertStage("inclined", "align", {"orig": child}, axes=["b", "a"], rotation=math.radians(-135)) f = stage.moveRel({"x": 1e-06, "y": 2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 1e-06, "y": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"a":-2.1213203435596424e-06, "b": 7.071067811865477e-07}) f = stage.moveRel({"x": -1e-06, "y": -2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"x": 0, "y": 0}) test.assert_pos_almost_equal(child.position.value, {"a": 0, "b": 0})
def test_limited_backlash(self): """ Test when backlash doesn't involve all axes """ child = simulated.Stage("stage", "test", axes=["a", "b"]) stage = AntiBacklashActuator("absact", "align", {"orig": child}, backlash={"a": 100e-6}) # moves should just go the same positions # abs test.assert_pos_almost_equal(stage.position.value, {"a": 0, "b": 0}) f = stage.moveAbs({"a": 1e-06, "b": 2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a": 1e-06, "b": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"a": 1e-06, "b": 2e-06}) f = stage.moveAbs({"b": 0}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a": 1e-06, "b": 0}) test.assert_pos_almost_equal(child.position.value, {"a": 1e-06, "b": 0}) f = stage.moveAbs({"a": -23e-06, "b": -15e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a":-23e-06, "b":-15e-06}) test.assert_pos_almost_equal(child.position.value, {"a":-23e-06, "b":-15e-06}) f = stage.moveAbs({"a": -20e-06}) # negative position but positive move f.result() test.assert_pos_almost_equal(stage.position.value, {"a":-20e-06, "b":-15e-06}) test.assert_pos_almost_equal(child.position.value, {"a":-20e-06, "b":-15e-06}) # rel f = stage.moveAbs({"a": 0}) f = stage.moveAbs({"b": 0}) f = stage.moveRel({"a": 1e-06, "b": 2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a": 1e-06, "b": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"a": 1e-06, "b": 2e-06}) f = stage.moveRel({"a": 0, "b": 0}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a": 1e-06, "b": 2e-06}) test.assert_pos_almost_equal(child.position.value, {"a": 1e-06, "b": 2e-06}) f = stage.moveRel({"a": -1e-06, "b": -2e-06}) f.result() test.assert_pos_almost_equal(stage.position.value, {"a": 0, "b": 0}) test.assert_pos_almost_equal(child.position.value, {"a": 0, "b": 0})
def test_move_abs(self): child = simulated.Stage("stage", "test", axes=["x", "y"]) # no transformation stage = ConvertStage("conv", "align", {"orig": child}, axes=["x", "y"]) self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) f = stage.moveAbs({"x": 1e-06, "y": 2e-06}) f.result() self.assertPosAlmostEqual(stage.position.value, { "x": 1e-06, "y": 2e-06 }) self.assertPosAlmostEqual(child.position.value, { "x": 1e-06, "y": 2e-06 }) f = stage.moveAbs({"x": 0, "y": 0}) f.result() self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) self.assertPosAlmostEqual(child.position.value, {"x": 0, "y": 0}) # scaling stage = ConvertStage("conv", "align", {"orig": child}, axes=["x", "y"], scale=(10, 10)) self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) f = stage.moveAbs({"x": 1e-06, "y": 2e-06}) f.result() self.assertPosAlmostEqual(stage.position.value, { "x": 1e-06, "y": 2e-06 }) self.assertPosAlmostEqual(child.position.value, { "x": 1e-05, "y": 2e-05 }) f = stage.moveAbs({"x": 0, "y": 0}) f.result() self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) self.assertPosAlmostEqual(child.position.value, {"x": 0, "y": 0}) # rotation stage = ConvertStage("conv", "align", {"orig": child}, axes=["x", "y"], rotation=math.pi / 2) self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) f = stage.moveAbs({"x": 1e-06, "y": 2e-06}) f.result() self.assertPosAlmostEqual(stage.position.value, { "x": 1e-06, "y": 2e-06 }) self.assertPosAlmostEqual(child.position.value, { "x": -2e-06, "y": 1e-06 }) f = stage.moveAbs({"x": 0, "y": 0}) f.result() self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) self.assertPosAlmostEqual(child.position.value, {"x": 0, "y": 0}) # offset stage = ConvertStage("conv", "align", {"orig": child}, axes=["x", "y"], translation=(1e-06, 2e-06)) self.assertPosAlmostEqual(stage.position.value, { "x": -1e-06, "y": -2e-06 }) f = stage.moveAbs({"x": 0, "y": 0}) f.result() self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) self.assertPosAlmostEqual(child.position.value, { "x": 1e-06, "y": 2e-06 }) f = stage.moveAbs({"x": -1e-06, "y": -2e-06}) f.result() self.assertPosAlmostEqual(stage.position.value, { "x": -1e-06, "y": -2e-06 }) self.assertPosAlmostEqual(child.position.value, {"x": 0, "y": 0}) # offset + scaling stage = ConvertStage("conv", "align", {"orig": child}, axes=["x", "y"], translation=(1e-06, 2e-06), scale=(10, 10)) self.assertPosAlmostEqual(stage.position.value, { "x": -1e-06, "y": -2e-06 }) f = stage.moveAbs({"x": 0, "y": 0}) f.result() self.assertPosAlmostEqual(stage.position.value, {"x": 0, "y": 0}) self.assertPosAlmostEqual(child.position.value, { "x": 1e-05, "y": 2e-05 })
def setUpClass(cls): cls.focus = simulated.Stage(**KWARGS_FOCUS) cls.camera = CLASS(dependencies={"focus": cls.focus}, **KWARGS)