Skip to content
Snippets Groups Projects
Commit 06c6ad39 authored by Christoph Schmidt's avatar Christoph Schmidt
Browse files

Measurement Routine moved to examples

parent 77221126
Branches
No related tags found
No related merge requests found
Showing
with 246 additions and 226 deletions
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.venv" />
<excludeFolder url="file://$MODULE_DIR$/src/FlexSensor/MeasurementEvaluation" />
<excludeFolder url="file://$MODULE_DIR$/src/FlexSensor/MeasurementEvaluationTool" />
</content>
<orderEntry type="jdk" jdkName="Python 3.10 (flexsensor)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PackageRequirementsSettings">
<option name="versionSpecifier" value="Don't specify version" />
<option name="removeUnused" value="true" />
</component>
<module version="4">
<component name="PyDocumentationSettings">
<option name="format" value="GOOGLE" />
<option name="myDocStringFormat" value="Google" />
</component>
<component name="PyNamespacePackagesService">
<option name="namespacePackageFolders">
<list>
<option value="$MODULE_DIR$/src/FlexSensor" />
<option value="$MODULE_DIR$/src/FlexSensor/Prober" />
<option value="$MODULE_DIR$/src/FlexSensor/MainWindow" />
<option value="$MODULE_DIR$/src/FlexSensor/MeasurementData" />
<option value="$MODULE_DIR$/src/FlexSensor/MeasurementRoutines" />
</list>
</option>
</component>
</module>
\ No newline at end of file
import logging
import sys
import time
import traceback
from datetime import datetime
......@@ -8,31 +9,41 @@ import LaserControl as Laser
import mcpy
import pandas as pd
from PySide6.QtCore import Slot
from constants.FlexsensorConstants import Probe
from generics.generics import pch
import FlexSensor.Prober as Prober
from FlexSensor.FlexSensorConfig import FlexSensorConfig
import FlexSensor as fs
from FlexSensor import Prober
from FlexSensor.MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
from FlexSensor.MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
from FlexSensor.MeasurementData.Properties.LaserProperties import LaserProperties
from FlexSensor.MeasurementData.Properties.MeasurementProperties import MPropertiesFindPeaks, \
MeasurementProperties, WaveguidePropertiesMZI
from FlexSensor.MeasurementData.Properties.WaferProperties import WaferProperties
from FlexSensor.MeasurementRoutines.BasemeasurementRoutine import BaseMeasurementRoutine
from FlexSensor.generics.VASInputFileParser import VASInputFileParser, Structure
from FlexSensor.Prober.controller.OpticalInterface import Probe
from Properties import AD2CaptDeviceProperties
from Properties import LaserProperties
from Properties.MeasurementProperties import WaveguidePropertiesMZI, MeasurementProperties, \
MPropertiesFindPeaks
from Properties.WaferProperties import WaferProperties
sys.path.append('./src')
# from FlexSensor.FlexSensorConfig import FlexSensorConfig
# from FlexSensor.MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
# from FlexSensor.MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
# from FlexSensor.MeasurementData.Properties.LaserProperties import LaserProperties
# from FlexSensor.MeasurementData.Properties.MeasurementProperties import MPropertiesFindPeaks, \
# MeasurementProperties, WaveguidePropertiesMZI
# from FlexSensor.MeasurementData.Properties.WaferProperties import WaferProperties
# from FlexSensor.MeasurementRoutines.BasemeasurementRoutine import BaseMeasurementRoutine
# from FlexSensor.generics.VASInputFileParser import VASInputFileParser, Structure
class MeasurementRoutine(BaseMeasurementRoutine):
class MeasurementRoutine(fs.BaseMeasurementRoutine):
def __init__(self, laser: Laser, ad2device: AD2Dev, prober: Prober.Controller,
config: FlexSensorConfig):
config: fs.FlexSensorConfig):
super().__init__(laser, ad2device, prober, config)
self.logger = logging.getLogger("Measurement Routine")
# The signals for connecting to the UI
self.parsed_file = VASInputFileParser()
self.parsed_file = fs.VASInputFileParser()
selected_file, self.grouped_structures, self.bookmarks = self.parsed_file.read_file(
input_file=self.config.wafer_config.structure_file.get()
......@@ -92,7 +103,7 @@ class MeasurementRoutine(BaseMeasurementRoutine):
# self._init_ad2device_signals()
self._write_info(
f"{pch('=', 50)} Starting measurement {pch('=', 50)}")
f"{self.pch('=', 50)} Starting measurement {self.pch('=', 50)}")
# === Check contact height
print(self.prober)
......@@ -139,7 +150,7 @@ class MeasurementRoutine(BaseMeasurementRoutine):
# If implementing multiple routines, and the steps may occure multiple times, move them to
# the base class instead of reimplementing/copying!
# ==================================================================================================================
def _step_place_input_probe(self, structure: Structure, fmt):
def _step_place_input_probe(self, structure: fs.Structure, fmt):
"""
Places the chuck, thus the input probe, such that the probe is on the correct position.
Move the chuck to the given position. Since the input probe stays on the same position,
......@@ -296,11 +307,11 @@ class MeasurementRoutine(BaseMeasurementRoutine):
raise e
# Routine for measuring one structure
def _measure_structure(self, die_no: int, structure: Structure, structure_idx: int):
def _measure_structure(self, die_no: int, structure: fs.Structure, structure_idx: int):
"""Routine for measuring one structure
"""
self.structure: Structure = structure
self.structure: fs.Structure = structure
self.formatter = f"[Measurement. Die {die_no}]: {self.structure.name} |"
timestamp = datetime.now().strftime('%d/%m/%Y %H:%M:%S.%f')
......
import pandas as pd
from MeasurementData.Properties.GenericProperties import GenericProperties
from FlexSensor.generics.GenericProperties import GenericProperties
class AD2CaptDeviceProperties(GenericProperties):
......
import sys
from MeasurementData.Properties.GenericProperties import GenericProperties
#import mcpy
#sys.path.append('../mcpy/mcpy')
import mcpy
from FlexSensor.generics.GenericProperties import GenericProperties
class LaserProperties(GenericProperties):
......
......@@ -4,7 +4,7 @@ from PySide6.QtCore import Signal
import mcpy
from mcpy import Uncertainty, MCSamples
from MeasurementData.Properties.GenericProperties import GenericProperties
from FlexSensor.generics.GenericProperties import GenericProperties
class MPropertiesFindPeaks(GenericProperties):
......
from MeasurementData.Properties.GenericProperties import GenericProperties
from FlexSensor.generics.GenericProperties import GenericProperties
class WaferProperties(GenericProperties):
......
......@@ -9,8 +9,13 @@ import sys
import time
from PySide6.QtWidgets import QApplication
# set env variable VELOX_SIM=TRUE
# to use the simulator instead of the real hardware
import os
os.environ["VELOX_SIM"] = "TRUE"
sys.path.append('./src')
from MeasurementRoutine import MeasurementRoutine
import FlexSensor
def main(argv):
......@@ -37,7 +42,7 @@ def main(argv):
main_model = FlexSensor.MainThreadModel(config=config)
#wdg = config.view.widget()
#wdg.show()
main_controller = FlexSensor.MainThreadController(main_model)
main_controller = FlexSensor.MainThreadController(main_model, MeasurementRoutine)
main_window = FlexSensor.MainWindow(main_model, main_controller)
# test_win = StructureSelector()
......
......@@ -4,6 +4,8 @@ import Prober as Prober
from InitialSetupWizard.pages.ForthPage import ForthWizardPage
from InitialSetupWizard.pages.WizardPage import WizardPage
import FlexSensor.Prober.controller.OpticalInterface
class FifthWizardPage(WizardPage):
def __init__(self, prober: Prober.Controller, page_input_distance: ForthWizardPage, parent: QWizard = None):
......@@ -59,15 +61,15 @@ class FifthWizardPage(WizardPage):
def train(self, distance, safe_move_distance):
# First read out both positions
x_in, y_in, z_in, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=Prober.Probe.INPUT)
x_out, y_out, z_out, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=Prober.Probe.OUTPUT)
x_in, y_in, z_in, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=FlexSensor.Prober.controller.OpticalInterface.Probe.INPUT)
x_out, y_out, z_out, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=FlexSensor.Prober.controller.OpticalInterface.Probe.OUTPUT)
pos = Prober.ProbePosition(input=(x_in, y_in, z_in), output=(x_out, y_out, z_out))
print(pos)
# Now move the input probe away from the position
# INPUT -safe_move_distance #===================================================================================
self.logger.info(f"Moving input probe {-safe_move_distance}um.")
self.prober.opt_if.move_optical_probe(Prober.Probe.INPUT, -safe_move_distance, '0', 'R')
self.prober.opt_if.move_optical_probe(FlexSensor.Prober.controller.OpticalInterface.Probe.INPUT, -safe_move_distance, '0', 'R')
self.logger.info(f"Moved input probe {-safe_move_distance}um.")
# ==============================================================================================================
......@@ -78,7 +80,7 @@ class FifthWizardPage(WizardPage):
f"Make sure that the output probe has been moved!",
title="Optical output probe are about to move",
):
self.prober.opt_if.move_optical_probe(Prober.Probe.OUTPUT, -distance, '0', 'R')
self.prober.opt_if.move_optical_probe(FlexSensor.Prober.controller.OpticalInterface.Probe.OUTPUT, -distance, '0', 'R')
self.logger.info(f"Moved output probe {-distance}um.")
else:
self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
......@@ -86,13 +88,13 @@ class FifthWizardPage(WizardPage):
# ==============================================================================================================
# ==============================================================================================================
self.prober.opt_if.set_optical_probe_home(Prober.Probe.OUTPUT)
self.prober.opt_if.set_optical_probe_home(FlexSensor.Prober.controller.OpticalInterface.Probe.OUTPUT)
self.logger.info(f"Set optical output home to current position")
# ==============================================================================================================
# OUTPUT distance ==============================================================================================
self.logger.info(f"Moving output probe {distance}um back to initial position ")
self.prober.opt_if.move_optical_probe(Prober.Probe.OUTPUT, distance, '0', 'R')
self.prober.opt_if.move_optical_probe(FlexSensor.Prober.controller.OpticalInterface.Probe.OUTPUT, distance, '0', 'R')
# ==============================================================================================================
# INPUT safe_move_distance =====================================================================================
......@@ -102,7 +104,7 @@ class FifthWizardPage(WizardPage):
f"Make sure that the output probe position has been reset!",
title="Optical output probe are about to move"
):
self.prober.opt_if.move_optical_probe(Prober.Probe.INPUT, safe_move_distance, '0', 'R')
self.prober.opt_if.move_optical_probe(FlexSensor.Prober.controller.OpticalInterface.Probe.INPUT, safe_move_distance, '0', 'R')
self.logger.info(f"Moved input probe {safe_move_distance}.")
else:
self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
......
import logging
from typing import Type
from PySide6.QtCore import QThread, Signal
import confighandler
import LaserControl as Laser
import CaptDeviceControl as AD2Dev
import Prober as Prober
import MeasurementEvaluationTool
from ..model.MainThreadModel import MainThreadModel
from FlexSensor.MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
from Prober.controller.ProberController import ProberController
from ... import Prober
from ...FSBase import FSBase
from ...MeasurementRoutines.BaseMeasurementRoutine import BaseMeasurementRoutine
class MainThreadController(FSBase, object):
......@@ -21,6 +18,7 @@ class MainThreadController(FSBase, object):
on_start_laser_sweep = Signal(name='on_start_laser_sweep')
def __init__(self, model: MainThreadModel,
measurement_routine: Type[BaseMeasurementRoutine],
enable_log: bool = True, log_level: int = logging.DEBUG, log_file: str = "flexsensor.log"):
super().__init__()
......@@ -59,7 +57,7 @@ class MainThreadController(FSBase, object):
self._device_initialization()
# Load the measurement routine
self.model.measurement_routine = self._load_measurement_routine()
self.model.measurement_routine = self._load_measurement_routine(measurement_routine)
# Thread for the measurement routine
self.measurement_thread = QThread()
......@@ -107,7 +105,7 @@ class MainThreadController(FSBase, object):
self.measurement_thread.started.connect(measurement_routine.run)
self.logger.debug("Moved worker/measurement routine to thread and connected the signals.")
def _load_measurement_routine(self) -> MeasurementRoutine:
def _load_measurement_routine(self, measurement_routine: Type[BaseMeasurementRoutine]) -> BaseMeasurementRoutine:
"""
Loads the measurement routine and initializes it.
......@@ -120,13 +118,13 @@ class MainThreadController(FSBase, object):
# if not self.device_are_init:
# raise Exception("Some or all devices have not been initialized. First call `_device_initialization()`!")
measurement_routine = MeasurementRoutine(
_measurement_routine = measurement_routine(
self.model.laser_controller,
self.model.ad2_controller,
self.model.prober_controller,
self.model.config)
self.logger.debug("Initialized MeasurementRoutine.")
return measurement_routine
return _measurement_routine
def _device_initialization(self):
"""
......
......@@ -9,8 +9,9 @@ import confighandler as Config
import MeasurementEvaluationTool as met
# import ConfigHandler as Config
from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
#from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
from FlexSensor.FlexSensorConfig import FlexSensorConfig
from FlexSensor.MeasurementRoutines.BaseMeasurementRoutine import BaseMeasurementRoutine
class MainThreadSignals(QObject):
......@@ -20,7 +21,7 @@ class MainThreadSignals(QObject):
ad2_changed = Signal(AD2Dev.Model, AD2Dev.Controller, AD2Dev.View)
prober_changed = Signal(Prober.Model, Prober.Controller, Prober.ControlWindow)
measurement_routine_changed = Signal(MeasurementRoutine)
measurement_routine_changed = Signal(BaseMeasurementRoutine)
class MainThreadModel(QObject):
......@@ -32,7 +33,7 @@ class MainThreadModel(QObject):
self._config: FlexSensorConfig = config
self._measurement_routine: MeasurementRoutine = None
self._measurement_routine: BaseMeasurementRoutine = None
self.start_capture_flag: Value = Value('i', 0)
self._ad2_model: AD2Dev.Model = None
......@@ -146,10 +147,10 @@ class MainThreadModel(QObject):
self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
@property
def measurement_routine(self) -> MeasurementRoutine:
def measurement_routine(self) -> BaseMeasurementRoutine:
return self._measurement_routine
@measurement_routine.setter
def measurement_routine(self, value: MeasurementRoutine):
def measurement_routine(self, value: BaseMeasurementRoutine):
self._measurement_routine = value
self.signals.measurement_routine_changed.emit(self.measurement_routine)
......@@ -7,7 +7,7 @@ from PySide6.QtGui import QIcon
import FlexSensor.Prober as Prober
from FlexSensor.Prober.controller.ProberController import ProberController
from FlexSensor.constants.FlexsensorConstants import Probe
from FlexSensor.Prober.controller.OpticalInterface import Probe
class StepThroughView(QMainWindow):
......
......@@ -8,20 +8,24 @@ import pandas as pd
import scipy
from numpy import ndarray
from MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
from MeasurementData.Properties.LaserProperties import LaserProperties
from MeasurementData.MeasuredData.SupportClasses.MeasurementDataTables import MeasurementDataTables
from MeasurementData.Properties.MeasurementProperties import MeasurementProperties, \
MPropertiesFindPeaks, WaveguideProperties
from MeasurementData.Properties.WaferProperties import WaferProperties
from FlexSensor.MeasurementData.MeasuredData.SupportClasses.MeasurementDataTables import MeasurementDataTables
from FlexSensor.generics.GenericProperties import GenericProperties
#from MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
#from MeasurementData.Properties.LaserProperties import LaserProperties
#from MeasurementData.MeasuredData.SupportClasses.MeasurementDataTables import MeasurementDataTables
#from MeasurementData.Properties.MeasurementProperties import MeasurementProperties, \
# MPropertiesFindPeaks, WaveguideProperties
#from MeasurementData.Properties.WaferProperties import WaferProperties
class MeasuredData:
def __init__(self, laser_properties: LaserProperties, ad2_properties: AD2CaptDeviceProperties,
wafer_properties: WaferProperties, waveguide_properties: WaveguideProperties,
measurement_properties: MeasurementProperties):
def __init__(self, laser_properties: GenericProperties, ad2_properties: GenericProperties,
wafer_properties: GenericProperties, waveguide_properties: GenericProperties,
measurement_properties: GenericProperties):
#super().__init__()
self.logger = logging.getLogger("MeasuredSignal")
# ==============================================================================================================
......
import sys
from FlexSensor.MeasurementData.MeasuredData.MeasuredData import MeasuredData
from FlexSensor.generics.GenericProperties import GenericProperties
#from examples.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
#from examples.Properties.LaserProperties import LaserProperties
#from examples.Properties.MeasurementProperties import WaveguideProperties, MeasurementProperties
#from examples.Properties.WaferProperties import WaferProperties
sys.path.append("../flexsensorpy")
sys.path.append("../mcpy")
import pathlib
......@@ -19,16 +28,6 @@ from scipy.io import matlab
from scipy.signal import find_peaks
import scipy
from MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
from MeasurementData.Properties.LaserProperties import LaserProperties
from MeasurementData.MeasuredData.MeasuredData import MeasuredData
from MeasurementData.Properties.MeasurementProperties import (WaveguideProperties,
MeasurementProperties,
WaveguidePropertiesMZI,
MPropertiesFindPeaks)
from MeasurementData.Properties.WaferProperties import WaferProperties
import mcpy
......@@ -39,112 +38,113 @@ class SingleMeasuredData(MeasuredData):
# ==================================================================================================================
# Load a Measurement data from a matlab mat-file
# ==================================================================================================================
@classmethod
def from_mat(cls, mat_file: Path | str) -> 'SingleMeasuredData':
"""
This allows to open "old" mat files, that do not have some data.
"""
mat_file = pathlib.Path(mat_file)
logging.info(f"Loading {mat_file.name}")
matf = scipy.io.loadmat(mat_file)
inst = cls(
laser_properties=LaserProperties(
mcpy.Rectangular(2, 0.01, unit='nm/s'),
mcpy.Rectangular(2, 0.01, unit='nm/s'),
mcpy.Rectangular(0.5, 0.01, unit='nm/s^2'),
(mcpy.Rectangular(835, 0.01, unit='nm'), mcpy.Rectangular(870, 0.01, unit='nm'))
),
ad2_properties=AD2CaptDeviceProperties(
0, 0, matf['ad2_sample_rate'], matf['ad2_total_samples'], matf['measure_time']
),
wafer_properties=WaferProperties(
matf['wafer_nr'],
matf['structure_name'],
matf['die_nr'],
matf['chuck_col'],
matf['chuck_row'],
(int(matf['structure_x_in']), int(matf['structure_y_in'])),
(int(matf['structure_x_out']), int(matf['structure_y_out'])),
int(mat_file.name.split('_')[9].replace('.mat', ''))
),
waveguide_properties=WaveguidePropertiesMZI(
length1=mcpy.Rectangular(10e6, 20, unit='nm'),
length2=mcpy.Rectangular(10.38e6, 20, unit='nm'),
width=mcpy.Rectangular(550, 20, unit='nm'),
height=mcpy.Rectangular(625, 2.405, unit='nm')),
measurement_properties=MeasurementProperties(
MPropertiesFindPeaks(0.1, 10000, None)
),
timestamp=matf['timestamp'],
measurement_file=None,
measurement_data=matf['amplitude'][0]
)
"""
date_format = '%a %b %d %H:%M:%S %Y'
x = datetime. strptime(
re.search('(?<=Created on: ).*', matf['__header__'].decode('UTF-8')).group(0),
date_format)"""
return inst
@classmethod
def from_mat_v2(cls, mat_file: Path | str):
def loadmat(filename):
'''
this function should be called instead of direct spio.loadmat
as it cures the problem of not properly recovering python dictionaries
from mat files. It calls the function check keys to cure all entries
which are still mat-objects
'''
data = scipy.io.loadmat(filename, struct_as_record=False, squeeze_me=True)
return _check_keys(data)
def _check_keys(dict):
'''
checks if entries in dictionary are mat-objects. If yes
todict is called to change them to nested dictionaries
'''
for key in dict:
if isinstance(dict[key], matlab.mio5_params.mat_struct):
dict[key] = _todict(dict[key])
return dict
def _todict(matobj):
'''
A recursive function which constructs from matobjects nested dictionaries
'''
dict = {}
for strg in matobj._fieldnames:
elem = matobj.__dict__[strg]
if isinstance(elem, matlab.mio5_params.mat_struct):
dict[strg] = _todict(elem)
else:
dict[strg] = elem
return dict
if isinstance(mat_file, str):
mat_file = Path(mat_file)
logging.info(f"Loading {mat_file.name}")
matf = loadmat(mat_file)
# mcpy.Uncertainty.from_tuple(matf['laser_properties']['laser_wavelength'])
inst = cls(
laser_properties=LaserProperties.from_dict(matf['laser_properties']),
ad2_properties=AD2CaptDeviceProperties.from_dict(matf['ad2_properties']),
wafer_properties=WaferProperties.from_dict(matf['wafer_properties']),
waveguide_properties=WaveguidePropertiesMZI.from_dict(matf['waveguide_properties']),
measurement_properties=MeasurementProperties.from_dict(matf['measurement_properties']),
timestamp=matf['timestamp'],
measurement_data=pd.DataFrame({
'wavelength': matf['wavelength'],
'amplitude': matf['amplitude'],
'amplitude_detrended': matf['amplitude_detrended']}),
#measurement_file=Path(f"{mat_file.absolute().parent}/{matf['measurement_file']}").absolute()
)
return inst
# @classmethod
# def from_mat(cls, mat_file: Path | str) -> 'SingleMeasuredData':
# """
# This allows to open "old" mat files, that do not have some data.
# """
# mat_file = pathlib.Path(mat_file)
# logging.info(f"Loading {mat_file.name}")
# matf = scipy.io.loadmat(mat_file)
#
# inst = cls(
# laser_properties=
# #LaserProperties(
# # mcpy.Rectangular(2, 0.01, unit='nm/s'),
# # mcpy.Rectangular(2, 0.01, unit='nm/s'),
# # mcpy.Rectangular(0.5, 0.01, unit='nm/s^2'),
# # (mcpy.Rectangular(835, 0.01, unit='nm'), mcpy.Rectangular(870, 0.01, unit='nm'))
# #),
# ad2_properties=AD2CaptDeviceProperties(
# 0, 0, matf['ad2_sample_rate'], matf['ad2_total_samples'], matf['measure_time']
# ),
# wafer_properties=WaferProperties(
# matf['wafer_nr'],
# matf['structure_name'],
# matf['die_nr'],
# matf['chuck_col'],
# matf['chuck_row'],
# (int(matf['structure_x_in']), int(matf['structure_y_in'])),
# (int(matf['structure_x_out']), int(matf['structure_y_out'])),
# int(mat_file.name.split('_')[9].replace('.mat', ''))
# ),
# waveguide_properties=WaveguidePropertiesMZI(
# length1=mcpy.Rectangular(10e6, 20, unit='nm'),
# length2=mcpy.Rectangular(10.38e6, 20, unit='nm'),
# width=mcpy.Rectangular(550, 20, unit='nm'),
# height=mcpy.Rectangular(625, 2.405, unit='nm')),
# measurement_properties=MeasurementProperties(
# MPropertiesFindPeaks(0.1, 10000, None)
# ),
# timestamp=matf['timestamp'],
# measurement_file=None,
# measurement_data=matf['amplitude'][0]
# )
# """
# date_format = '%a %b %d %H:%M:%S %Y'
# x = datetime. strptime(
# re.search('(?<=Created on: ).*', matf['__header__'].decode('UTF-8')).group(0),
# date_format)"""
#
# return inst
#
# @classmethod
# def from_mat_v2(cls, mat_file: Path | str):
# def loadmat(filename):
# '''
# this function should be called instead of direct spio.loadmat
# as it cures the problem of not properly recovering python dictionaries
# from mat files. It calls the function check keys to cure all entries
# which are still mat-objects
# '''
# data = scipy.io.loadmat(filename, struct_as_record=False, squeeze_me=True)
# return _check_keys(data)
#
# def _check_keys(dict):
# '''
# checks if entries in dictionary are mat-objects. If yes
# todict is called to change them to nested dictionaries
# '''
# for key in dict:
# if isinstance(dict[key], matlab.mio5_params.mat_struct):
# dict[key] = _todict(dict[key])
# return dict
#
# def _todict(matobj):
# '''
# A recursive function which constructs from matobjects nested dictionaries
# '''
# dict = {}
# for strg in matobj._fieldnames:
# elem = matobj.__dict__[strg]
# if isinstance(elem, matlab.mio5_params.mat_struct):
# dict[strg] = _todict(elem)
# else:
# dict[strg] = elem
# return dict
#
# if isinstance(mat_file, str):
# mat_file = Path(mat_file)
#
# logging.info(f"Loading {mat_file.name}")
# matf = loadmat(mat_file)
# # mcpy.Uncertainty.from_tuple(matf['laser_properties']['laser_wavelength'])
# inst = cls(
# laser_properties=LaserProperties.from_dict(matf['laser_properties']),
# ad2_properties=AD2CaptDeviceProperties.from_dict(matf['ad2_properties']),
# wafer_properties=WaferProperties.from_dict(matf['wafer_properties']),
# waveguide_properties=WaveguidePropertiesMZI.from_dict(matf['waveguide_properties']),
# measurement_properties=MeasurementProperties.from_dict(matf['measurement_properties']),
# timestamp=matf['timestamp'],
# measurement_data=pd.DataFrame({
# 'wavelength': matf['wavelength'],
# 'amplitude': matf['amplitude'],
# 'amplitude_detrended': matf['amplitude_detrended']}),
#
# #measurement_file=Path(f"{mat_file.absolute().parent}/{matf['measurement_file']}").absolute()
# )
# return inst
#
@staticmethod
def convert(mat_file):
"""Reads the mat file and converts the new format to the old format"""
......@@ -157,11 +157,11 @@ class SingleMeasuredData(MeasuredData):
def __init__(self,
laser_properties: LaserProperties,
ad2_properties: AD2CaptDeviceProperties,
wafer_properties: WaferProperties,
waveguide_properties: WaveguideProperties,
measurement_properties: MeasurementProperties,
laser_properties: GenericProperties,
ad2_properties: GenericProperties,
wafer_properties: GenericProperties,
waveguide_properties: GenericProperties,
measurement_properties: GenericProperties,
timestamp: datetime,
measurement_file: Path | str = None,
measurement_data = None,
......
......@@ -34,6 +34,9 @@ class BaseMeasurementRoutine(QObject, FSBase):
self.signals = WorkerSignals()
def pch(self, c, num):
return ''.join([str(c) for i in range(0, num)])
@Slot()
def run(self):
raise NotImplementedError()
......
......@@ -7,9 +7,17 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '../'))
from .model.ProberModel import ProberModel as Model
from .model.ProberModel import ProberSignals as Signals
from .view.ProberControlWindow import ProberControlWindow as ControlWindow
from .controller.ProberController import ProberController as Controller
from .controller.OpticalProbesPosition import OpticalProbesPosition as ProbePosition
from .controller.OpticalInterface import OpticalInterface
from .controller.ProberController import ProberController as Controller
from .view.ProberControlWindow import ProberControlWindow as ControlWindow
if os.getenv("VELOX_SIM") == "TRUE":
try:
......@@ -36,3 +44,4 @@ else:
ReadChuckPosition, ReadChuckHeights, MoveChuck,
SnapImage, GetDieDataAsColRow, StepToDie,
ReportKernelVersion)
......@@ -2,8 +2,8 @@ import logging
from Prober.model.OpticalInterfaceModel import OpticalInterfaceModel
from Prober.model.OpticalInterfaceStoredData import OpticalInterfaceStoredData
from constants.FlexsensorConstants import Probe
from generics.generics import pch
#from constants.FlexsensorConstants import Probe
#from generics.generics import pch
from FlexSensor.FSBase import FSBase
......@@ -22,6 +22,8 @@ class OpticalInterface(FSBase):
# ==================================================================================================================
# pythonized api calls
# ==================================================================================================================
def pch(self, c, num):
return ''.join([str(c) for i in range(0, num)])
def enable_flight_height_control(self, enable_in=True, enable_out=True):
# Disable Flight Height Control
......@@ -189,7 +191,7 @@ class OpticalInterface(FSBase):
output_power)
def search_for_light(self, threshold: float = -70, threshold_areascan: float = -60, retries: float = 3):
self.logger.debug(f"[OptIF Task] - {pch('*', 20)} Search for light {pch('*', 20)}")
self.logger.debug(f"[OptIF Task] - {self.pch('*', 20)} Search for light {self.pch('*', 20)}")
self.signals.log_debug.emit("OptIF Task", f"*** Search for light ***", None)
# Recenter the probes, perform an area scan, recenter again.
......@@ -221,7 +223,7 @@ class OpticalInterface(FSBase):
x_1, x_2, y_1, y_2, input_power, output_power = self._recenter_and_scan()
retries -= 1
self.logger.debug(f"[OptIF Task] - {pch('*', 20)} Search for light completed {pch('*', 20)}")
self.logger.debug(f"[OptIF Task] - {self.pch('*', 20)} Search for light completed {self.pch('*', 20)}")
self.signals.log_debug.emit("OptIF Task", f"*** Search for light completed***", None)
return input_power, output_power
......@@ -268,3 +270,7 @@ class OpticalInterface(FSBase):
# Store and load functions
# ==================================================================================================================
class Probe:
INPUT = 0
OUTPUT = 1
......@@ -4,14 +4,14 @@ import confighandler as Config
#from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
import FlexSensor.Prober as Prober
from FlexSensor.FSBase import FSBase
from FlexSensor.Prober.controller.OpticalInterface import OpticalInterface
from FlexSensor.Prober.model.ProberModel import ProberModel
from FlexSensor.constants.FlexsensorConstants import Probe
from FlexSensor.Prober.controller import OpticalInterface
#from FlexSensor.Prober.controller.OpticalInterface import OpticalInterface, Probe
#from FlexSensor.Prober.model.ProberModel import ProberModel
from FlexSensor.generics.generics import pch
class ProberController(FSBase):
def __init__(self, model: ProberModel,
def __init__(self, model: Prober.Model,
enable_log=True, log_level=logging.DEBUG, log_file=None,
*args, **kwargs):
super().__init__()
......@@ -22,7 +22,7 @@ class ProberController(FSBase):
self.msg_server = Prober.MessageServerInterface()
# Optical Interface Control hexapods and piezos
self.opt_if = OpticalInterface(self.signals, self.msg_server)
self.opt_if = Prober.OpticalInterface(self.signals, self.msg_server)
self.logger.info("Prober initialized")
self.model.version = self.report_kernel_version()
......@@ -217,8 +217,8 @@ class ProberController(FSBase):
# Move hexapod and nano to height 50 um
height = 80
self.opt_if.set_probe_height(Probe.INPUT, height)
self.opt_if.set_probe_height(Probe.OUTPUT, height)
self.opt_if.set_probe_height(OpticalInterface.Probe.INPUT, height)
self.opt_if.set_probe_height(OpticalInterface.Probe.OUTPUT, height)
# Read the die data: die number, col, row
self.model.die, self.model.die_col, self.model.die_row = self.get_die_as_col_row()
......@@ -299,7 +299,7 @@ class ProberController(FSBase):
self.write_log("warning", "No light found.")
return False
def store_hexapod_position():
def store_hexapod_position(self):
"""
Stores the hexpods and nanocube position for later retrieval
"""
......
......@@ -2,7 +2,6 @@ from pathlib import Path
from PySide6.QtCore import QObject, Signal
from MeasurementData.Properties.WaferProperties import WaferProperties
from FlexSensor.FlexSensorConfig import FlexSensorConfig
......@@ -62,12 +61,12 @@ class ProberModel:
#self._wafer_map = self.config.
@property
def laser_properties(self) -> WaferProperties:
return WaferProperties(self.acceleration,
self.deceleration,
self.velocity,
(self.sweep_start_wavelength, self.sweep_stop_wavelength))
#@property
#def laser_properties(self) -> WaferProperties:
# return WaferProperties(self.acceleration,
# self.deceleration,
# self.velocity,
# (self.sweep_start_wavelength, self.sweep_stop_wavelength))
@property
def connected(self) -> bool:
return self._connected
......
......@@ -6,14 +6,22 @@ from PySide6.QtWidgets import QGridLayout, QApplication, QMainWindow, QWidget, Q
import confighandler as Config
#from MapFileParser import MapFileParser
from FlexSensor.Prober.controller.ProberController import ProberController
from FlexSensor.Prober.model.ProberModel import ProberModel
#from MapFileParser import MapFileParser
#from FlexSensor import Prober
from FlexSensor.Prober.view.widgets.DieGridWidget import DieGridWidget
from FlexSensor.Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
from FlexSensor.Prober.view.widgets.ProberStatusWidget import ProberStatusWidget
#from FlexSensor.Prober.controller.ProberController import ProberController
#from FlexSensor.Prober.model.ProberModel import ProberModel
#from FlexSensor.Prober.view.widgets.DieGridWidget import DieGridWidget
#from FlexSensor.Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
#from FlexSensor.Prober.view.widgets.ProberStatusWidget import ProberStatusWidget
class ProberControlWindow(QMainWindow):
def __init__(self, model: ProberModel, controller: ProberController):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment