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

Measurement Routine moved to examples. Now measureme and updated the README.md

parent 06c6ad39
No related branches found
No related tags found
No related merge requests found
......@@ -35,7 +35,52 @@ To start the software, simply run the `examples/main.py` file.
python main.py
```
# Measuring using Flexsensor
# Defining a measurement routine
The measurement routine is defined in a python file. Each measurement routine must inherit from the `BaseMeasurementRoutine` class.
Note that the base class has an overloaded constructor that requires the following parameters:
- `prober`: The Prober.Controller object that is used to measure the structures
- `config`: The FlexSensorConfig object that is used to measure the structures
```python
import FlexSensor as fs
class MeasurementRoutine(fs.BaseMeasurementRoutine):
def __init__(prober: Prober.Controller,
config: fs.FlexSensorConfig):
super().__init__(prober, config)
@Slot()
def run(self):
# your code here
```
In the `run` method, the measurement routine is defined.
The `run` method is called by the `MeasurementRoutineThread` class, which is a QThread object. This allows to run the method
in a separate thread, while the GUI remains responsive.
# Measuring using FlexSensor
It is often useful to measure a large number of structures on a wafer. For this, the software allows to define a
measurement routine that is executed for each structure.
The `vas`-File allows to define a list of structures that are measured. Thede file is parsed and passed
to the `MeasurementRoutine` class.
```python
import FlexSensor as fs
# ...
def readVasFile(self):
self.parsed_file = fs.VASInputFileParser()
selected_file, self.grouped_structures, self.bookmarks = self.parsed_file.read_file(
input_file='structure_file.vas'
)
# ...
```
The `VASInputFileParser` class parses the `vas`-File and returns a list of structures that are measured.
- `selected_file`: The selected file. In case the file is not found, the user is prompted to select a file by a file dialog.
- `grouped_structures`: A list of structures that are measured. Each structure is a python dictionary that contains the
information on how to measure the structure.
- `bookmarks`: A list of bookmarks that are defined in the `vas`-File. These bookmarks are used to create a Klayout
bookmark file that can be used to navigate to the structures in Klayout.
## Input Structure File
The measuring process relies on a ```vas```-File that store the positions to the structures. in priciple
this file os a list of python dictionary in a predefined format, that allows the easy definiton
......@@ -69,7 +114,7 @@ Sometimes it is useful to define a group of measurement points that are equally
mrr1 = {'y_in' : -1845, 'x_in' : 960, 'y_out' : -2015, 'x_out' : -155, 'num' : 6, 'spacing' : 100, 'repetitons': 200}
```
## Setup bevore measuring
## Setup before measuring
1. Open the correct wafer map.
Open the wafer Map under **Velox** -> **WaferMap**. Load the correct wafer file and select or deselect dies you do not
want to capture.
......@@ -91,13 +136,12 @@ Set our fiber to the correct height. Then use the "Set Contact height". Otherwis
This step is crucial and needed to train the output positions.
# Lincence and usage
# Licence and usage
This software is licenced under the [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.de.html).
If you use this software for your work or in your papers please cite me the following:
# FAQ&Issues
This section should cover the issues that may occure during usage or development.
## Installation issues and running
......
......@@ -23,22 +23,18 @@ 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(fs.BaseMeasurementRoutine):
def __init__(self, laser: Laser, ad2device: AD2Dev, prober: Prober.Controller,
def __init__(self,
laser: Laser,
ad2device: AD2Dev,
prober: Prober.Controller,
config: fs.FlexSensorConfig):
super().__init__(laser, ad2device, prober, config)
super().__init__(prober, config)
self.ad2device: AD2Dev = ad2device
self.laser: Laser.Controller = laser
self.logger = logging.getLogger("Measurement Routine")
# The signals for connecting to the UI
......
......@@ -12,12 +12,14 @@ 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):
FlexSensor.ApplicationInit.setup_logging()
logging.info(f"Starting Velox GUI Version {FlexSensor.__version__}")
......@@ -34,26 +36,26 @@ def main(argv):
FlexSensor.ApplicationInit.set_icon(app)
# Read the inital config file
config = FlexSensor.ApplicationInit.load_config_file(f"{FlexSensor.configs_root}/init_config.yaml")
config.autosave(enable=True, path="autosave_configs/init_config.yaml")
# Start the main application
main_model = FlexSensor.MainThreadModel(config=config)
#wdg = config.view.widget()
#wdg.show()
main_controller = FlexSensor.MainThreadController(main_model, MeasurementRoutine)
main_controller = FlexSensor.MainThreadController(main_model)
# Register your measurement routine here
main_controller.load_measurement_routine(MeasurementRoutine,
ad2device=main_model.ad2_controller,
laser=main_model.laser_controller,
)
main_window = FlexSensor.MainWindow(main_model, main_controller)
# test_win = StructureSelector()
#config.save(f"{FlexSensor.configs_root}/init_config.yaml")
main_window.show()
splash_screen.finish(main_window)
sys.exit(app.exec())
if __name__ == "__main__":
if __name__ == "__main__":
main(sys.argv)
......@@ -18,7 +18,6 @@ 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__()
......@@ -57,7 +56,7 @@ class MainThreadController(FSBase, object):
self._device_initialization()
# Load the measurement routine
self.model.measurement_routine = self._load_measurement_routine(measurement_routine)
#self.model.measurement_routine = self._load_measurement_routine(measurement_routine)
# Thread for the measurement routine
self.measurement_thread = QThread()
......@@ -105,7 +104,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, measurement_routine: Type[BaseMeasurementRoutine]) -> BaseMeasurementRoutine:
def load_measurement_routine(self, measurement_routine: Type[BaseMeasurementRoutine], *args, **kwargs) -> BaseMeasurementRoutine:
"""
Loads the measurement routine and initializes it.
......@@ -115,16 +114,16 @@ class MainThreadController(FSBase, object):
Raises:
Exception: If some or all devices have not been initialized.
"""
# if not self.device_are_init:
# raise Exception("Some or all devices have not been initialized. First call `_device_initialization()`!")
_measurement_routine = measurement_routine(
self.model.laser_controller,
self.model.ad2_controller,
self.model.prober_controller,
self.model.config)
self.model.measurement_routine = measurement_routine(
prober=self.model.prober_controller,
config=self.model.config,
*args, **kwargs)
# laser=self.model.laser_controller,
# ad2device=self.model.ad2_controller,
# prober=self.model.prober_controller,
# config=self.model.config)
self.logger.debug("Initialized MeasurementRoutine.")
return _measurement_routine
#return _measurement_routine
def _device_initialization(self):
"""
......
......@@ -19,13 +19,12 @@ from FlexSensor.MeasurementRoutines.WorkerSignals import WorkerSignals
class BaseMeasurementRoutine(QObject, FSBase):
def __init__(self, laser: Laser.Controller, ad2device: CaptDevice.Controller, prober: ProberController, config: FlexSensorConfig):
def __init__(self, prober: ProberController, config: FlexSensorConfig, *args, **kwargs):
super().__init__()
self.logger = self.create_new_logger(self.name)
self.config = config
self.ad2device: CaptDevice.Controller = ad2device
self.laser: Laser.Controller = laser
self.prober: ProberController = prober
self.logger.debug(f"{self.prober.report_kernel_version()}")
print(self.prober)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment