diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2605fb84392a054428d4f4579b752d169ecd2876
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,192 @@
+## MATLAB ##
+# Windows default autosave extension
+*.asv
+
+# OSX / *nix default autosave extension
+*.m~
+
+# Compiled MEX binaries (all platforms)
+*.mex*
+
+# Packaged app and toolbox files
+*.mlappinstall
+*.mltbx
+
+# Generated helpsearch folders
+helpsearch*/
+
+# Simulink code generation folders
+slprj/
+sccprj/
+
+# Matlab code generation folders
+codegen/
+
+# Simulink autosave extension
+*.autosave
+
+# Simulink cache files
+*.slxc
+
+# Octave session info
+octave-workspace
+
+## PYTHON ##
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+Sacher_Lasertechnik/
+
+measurements/
+flexsensorpy/measurements/
+.venv-waffel-untersucher/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/flexsensor.iml b/.idea/flexsensor.iml
new file mode 100644
index 0000000000000000000000000000000000000000..8a05c6ed5f0c89c2998d9aee8978f53136f7649a
--- /dev/null
+++ b/.idea/flexsensor.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+ <component name="PyDocumentationSettings">
+ <option name="format" value="GOOGLE" />
+ <option name="myDocStringFormat" value="Google" />
+ </component>
+</module>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1030d7352b2f9c4feee0960cd1f81183a0144165
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,14 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoredPackages">
+ <value>
+ <list size="1">
+ <item index="0" class="java.lang.String" itemvalue="PySide6" />
+ </list>
+ </value>
+ </option>
+ </inspection_tool>
+ </profile>
+</component>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..105ce2da2d6447d11dfe32bfb846c3d5b199fc99
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="USE_PROJECT_PROFILE" value="false" />
+ <version value="1.0" />
+ </settings>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..67388a2ac340ca6c17e649492b707758f6f04016
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Black">
+ <option name="sdkName" value="Python 3.11 (pythonProject1)" />
+ </component>
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (pythonProject1)" project-jdk-type="Python SDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..706538a9e64a579a2518d6b4f085ca54bd24db07
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/flexsensor.iml" filepath="$PROJECT_DIR$/.idea/flexsensor.iml" />
+ </modules>
+ </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="Git" />
+ </component>
+</project>
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6323e499d2e6d7a5807f773ef99ea0cc72c8dc7b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,101 @@
+## Still under construction
+
+
+*This repository is under construction*. It will be restructured after all individual parts are updated.
+You can find the dependencies in the gitlab parent folder of this repo.
+
+# Flexsensor
+
+
+An automation software for [FormFactor Cascade Summit200](https://www.formfactor.com/product/probe-systems/200-mm-systems/summit200/) Probe Stations.
+*FlexSensor* is a software that allows to automate measurements using the FormFactor Wafer Prober.
+
+*FlexSensor* is a standalone Python application. Its versatility allows for immediate deployment, without prior programming knowledge. Particularly noteworthy are its post-processing capabilities, however, the software's core functionality is the use of the automated measurement routine to acquire the resonant spectra of photonic devices, integrated within a specialized measurement system, as detailed in Section
+
+# Installation
+Create a virtual environment (highly recommended)
+```python
+python -m venv .venv
+source .venv/Scripts/Activate
+```
+Prior to using the software, these packages need to be installed.
+```
+pip install rich PySide6 pyyaml matplotlib pyqtgraph pandas scipy numpy
+```
+
+# Measuring using Flexsensor
+## 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
+on how to measure the structures.
+The file allows python-style line comments using the ```#```-sign
+### Comments and Bookmarks
+```python
+# First structure to measure
+# group="mrr1"
+```
+Sometimes it is useful to have the Klayout-positions bookmarked. Using the Klayout-Coordinates, the
+software creates a readable Bookmark file that can be used in Klayout.
+```python
+# Bookmark this view
+mrr1_bookmark = { 'x_left': 19012, 'x_right' : 20708, 'y_bottom' : 20185, 'y_top': 21866 }
+```
+### Defining a measurement point
+Defining a measurement point requires the input position (`x_in`, `y_in`) and the output
+position (`x_out`, `y_out`). The keyword `repetitions` allows to define the number of repeated measurements of the same
+structure (e.g., for statistical evaluation, etc.)
+<br>
+**These positions are relative and measured from a predefined point (See Sec ...) on how
+to select this point which can be chosen arbitrarily.**
+```python
+mrr1_ref = {'y_in' : -2120, 'x_in' : 960, 'y_out' : -2120, 'x_out' : -155, 'repetitions': 2}
+```
+Sometimes it is useful to define a group of measurement points that are equally spaced in x-direction. For this, the
+`spacing` and `num`-keyword can be used. Using these values, the software will automatically generate a list of
+`num` structures, equally spaced in x-direction using the `spacing` value.
+```python
+mrr1 = {'y_in' : -1845, 'x_in' : 960, 'y_out' : -2015, 'x_out' : -155, 'num' : 6, 'spacing' : 100, 'repetitons': 200}
+```
+
+## Setup bevore 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.
+
+ **Note**: Make sure that the die and wafer size is correct.
+2. Auto-Align the Wafer
+ For this open the "AutoAlign" Wizard and find a suitable alignment structure.
+
+3. Place at "your" origin
+The structure file relies on "relative" positions to a point you
+find a suitable structur which is defined as the "die" origin. This is used to measure the distance to the to/be measured strcutures. Use the same mark in zour Klayout file and on the wafer.
+
+If you have not yet created a list for measuring your structure, you can use
+- the wafer prober find the right coordinates.
+- the KLayout-File for measuring the structures
+5. Set contact height
+Set our fiber to the correct height. Then use the "Set Contact height". Otherwise the measurement routine will fail!
+6. Train the Home Positions
+This step is crucial and needed to train the output positions.
+
+
+# Lincence 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
+There are some combinations of pyside6 and pyqtgraph that may lead to incompatibility
+issues. Especially `PySide 6.5.0` and `pyqtgraph 0.13.2` installation lead to
+```python
+TypeError: GraphicsWidgetAnchor.__init__() takes 1 positional argument but 2 were given
+```
+[Solution](https://stackoverflow.com/questions/76005506/pyqtgraphs-graphicswidgetanchor-class-incomplatible-with-pyside6?noredirect=1#comment134055507_76005506):
+Remove your current installed pyqtgraph and install the latest version:
+```python
+pip install git+https://github.com/pyqtgraph/pyqtgraph@master
+```
\ No newline at end of file
diff --git a/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..67df7de70e1f9c87f604ef83675bca77306071db
--- /dev/null
+++ b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>569</width>
+ <height>573</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Quantity Data</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QFrame" name="horizontalFrame">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox_2"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QFrame" name="horizontalFrame_2">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Uncertainty Distribution</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox_3"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <layout class="QGridLayout" name="gridLayout_2"/>
+ </item>
+ <item row="4" column="0">
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Unit</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Unit</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Definition</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lineEdit_2"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Description</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_8">
+ <item row="1" column="0">
+ <widget class="QPlainTextEdit" name="plainTextEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertainyControlWidget.py b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertainyControlWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py b/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7ae53e34c048b54a25fe902a7093a87342bc401
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py
@@ -0,0 +1,40 @@
+import sys
+
+from PySide6.QtWidgets import QWizard, QApplication
+
+import Prober as Prober
+from InitialSetupWizard.pages.FifthPage import FifthWizardPage
+from InitialSetupWizard.pages.ForthPage import ForthWizardPage
+from InitialSetupWizard.pages.ThirdPage import ThirdWizardPage
+from InitialSetupWizard.pages.SecondPage import SecondWizardPage
+from InitialSetupWizard.pages.FirstPage import FirstWizardPage
+from generics.logger import setup_logging
+
+
+class InitialSetupWizard(QWizard):
+
+ def __init__(self, prober: Prober.Controller, parent=None):
+ super().__init__(parent)
+ self.prober = prober
+ self.addPage(FirstWizardPage(self.prober, self))
+ self.addPage(SecondWizardPage(self.prober, self))
+ p3 = ThirdWizardPage(self.prober, self)
+ self.addPage(p3)
+ p4 = ForthWizardPage(self.prober, p3, parent=self)
+ self.addPage(p4)
+ self.addPage(FifthWizardPage(self.prober, p4, self))
+
+ self.setWindowTitle("Wizard Example")
+
+
+if __name__ == "__main__":
+ setup_logging()
+
+ app = QApplication()
+ prober = Prober.Controller()
+ wizard = InitialSetupWizard(prober)
+
+ wizard.show()
+
+ sys.exit(app.exec())
+
diff --git a/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py b/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..69a77e60cdb79f970e9786da1b4072fb3e040af3
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py
@@ -0,0 +1,112 @@
+from PySide6.QtWidgets import QWizard, QGridLayout, QLabel, QPushButton
+
+import Prober as Prober
+from InitialSetupWizard.pages.ForthPage import ForthWizardPage
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class FifthWizardPage(WizardPage):
+ def __init__(self, prober: Prober.Controller, page_input_distance: ForthWizardPage, parent: QWizard = None):
+ super().__init__(prober, parent)
+ self.setMaximumHeight(450)
+ self.setMinimumHeight(450)
+
+ self.setTitle("Train Output Home Position")
+ layout = QGridLayout()
+ self.distance = 0
+ # p_3: ThirdPage = parent.page(2)
+ page_input_distance.input_distance.textChanged.connect(self._on_distance_changed)
+ self.label_intro = QLabel(
+ f"To train the output home Position the Prober will move both probes in the direction given in the previous"
+ f"step. \n"
+ f"First it will move the input probe 500um to the left, then the output probe the given distance "
+ f"d={self.distance}um so it is placed at the input position. \n"
+ f"Afterwards the Home position is set to the current "
+ f"position and both probes are moved back to it's initial position.")
+ self.label_intro.setWordWrap(True)
+ layout.addWidget(self.label_intro, 0, 0, 1, 2)
+
+ self.btn_train = QPushButton('Set Home Position')
+ self.btn_train.clicked.connect(lambda: self.train_warn(self.distance))
+ layout.addWidget(self.btn_train, 1, 0, 1, 2)
+
+ self.setLayout(layout)
+
+ def _on_distance_changed(self, distance):
+ self.distance = int(distance)
+ self.label_intro.setText(
+ f"To train the output home Position the Prober will move both probes in the direction given in the previous"
+ f"step. \n"
+ f"First it will move the input probe 500um to the left, then the output probe the given distance "
+ f"d={self.distance}um so it is placed at the input position. \n"
+ f"Afterwards the Home position is set to the current "
+ f"position and both probes are moved back to it's initial position.")
+
+ # NO pressed
+
+ def train_warn(self, distance, safe_move_distance=500):
+ # Bevor continuning display a warning as a dialog box to the user
+ if self.display_mbox_warning(
+ text=f"The output optical probes are about to move {distance} towards the input probe. The"
+ f" input probe will be moved away {safe_move_distance}."
+ f"Make sure that no obstacles are in the way and the distance is safe to move.",
+ title="Optical probe are about to move"
+ ):
+ self.train(distance, safe_move_distance)
+ else:
+ self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+ return
+
+ 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)
+ 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.logger.info(f"Moved input probe {-safe_move_distance}um.")
+ # ==============================================================================================================
+
+ # OUTPUT -distance =============================================================================================
+ self.logger.info(f"Moving output probe {-distance}um.")
+ if self.display_mbox_warning(
+ text=f"The optical output probe is about to move {-distance}um towards the input probe. "
+ 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.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.")
+ return
+ # ==============================================================================================================
+
+ # ==============================================================================================================
+ self.prober.opt_if.set_optical_probe_home(Prober.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')
+ # ==============================================================================================================
+
+ # INPUT safe_move_distance =====================================================================================
+ self.logger.info(f"Moving input probe {safe_move_distance}um back to initial position.")
+ if self.display_mbox_warning(
+ text=f"The optical input probe is about to move {safe_move_distance}um towards the output probe. "
+ 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.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.")
+ return
+ # ==============================================================================================================
+ self.display_mbox_ok(text="The home position has been set successfully!",
+ title="Home position set")
diff --git a/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py b/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad7b2688bfe6ac7f06141d46b38e804a810e433d
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py
@@ -0,0 +1,33 @@
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QWizard, QVBoxLayout, QLabel
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class FirstWizardPage(WizardPage):
+ def __init__(self, prober: Prober.Controller, parent=None):
+ super().__init__(prober, parent)
+
+ self.setPixmap(QWizard.WizardPixmap.WatermarkPixmap, QPixmap())
+
+ layout = QVBoxLayout()
+
+ self.setTitle("Train Output Home Position")
+
+ label = QLabel("This wizard will guide you trough the calibration step. \n"
+ "During the process the Prober (Chuck, etc.) and the Optical Interface (Hexapods, etc.) will "
+ "move! The wizard won't start the movement automatically and each step "
+ "must be verified by the user and started manually.\n"
+ "\n"
+ "To prevent damage, the setup process are designed to check each steps. Thus,"
+ "checking the individual steps is required to continue the calibration.\n\n "
+ "Click 'Next' to start the wizard.")
+ label.setWordWrap(True)
+ label.setAlignment(Qt.AlignLeft)
+
+ # Add an image to the QWizardPage
+ layout.addWidget(label)
+
+ self.setLayout(layout)
diff --git a/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py b/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6fe8a47352728f4617669cc3b64de4000a02c01
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py
@@ -0,0 +1,74 @@
+from PySide6.QtWidgets import QGridLayout, QPushButton, QLabel, QLineEdit, QCheckBox
+
+import Prober as Prober
+from InitialSetupWizard.pages.ThirdPage import ThirdWizardPage
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class ForthWizardPage(WizardPage):
+ def __init__(self, prober: Prober.Controller, third_page: ThirdWizardPage, parent=None):
+ super().__init__(prober, parent)
+ self.third_page = third_page
+ self.setTitle("Positioning of the Probes")
+ layout = QGridLayout()
+
+ task_set_chuck_home_position, _ = self.add_task(
+ "1. Move to the calibration structure",
+ "Click on the next button 'Move to calibration structure' to move the chuck back to the calibration structure.\n"
+ "Warning: The probes will be moved 250um away from the selected position to ease the next step.",
+ "task_move_back_to_cal_structure*")
+ layout.addWidget(task_set_chuck_home_position, 1, 0, 1, 4)
+
+ # ==============================================================================================================
+ # layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'), 10, 0, 1, 4)
+ self.btn_move_back_to_cal_structure = QPushButton('Move to calibration structure')
+ layout.addWidget(self.btn_move_back_to_cal_structure, 2, 0, 1, 4)
+ self.btn_move_back_to_cal_structure.clicked.connect(lambda: self.move_back_to_cal_structure(probe_movement=250))
+
+ task_measure_distance, _ = self.add_task(
+ "2. Measure the distance between the input and the output.",
+ "For calibrating the position of the input probe to the output probe, "
+ "the difference of the input and the output must be determined. If the "
+ "distance is not known, Velox's Measurement Tool can be used. \n"
+ "Note: If using layout values make sure to include a distance which "
+ "corresponds to the position of input and the output probes",
+ "measure_distance*")
+ layout.addWidget(task_measure_distance, 3, 0, 1, 4)
+
+ graphics1 = self.add_graphics(f'{self.imgf}/Step4_2.png')
+ layout.addWidget(graphics1, 4, 0, 1, 4)
+
+ self.task_enter_distance, self.cb_distance_enterd = self.add_task(
+ "3. Enter the (measured) distance between input and output.",
+ "Enter the measured distance below and press 'Apply' to move the chuck half the given distance",
+ "task_measure_distance*")
+ layout.addWidget(self.task_enter_distance, 5, 0, 1, 4)
+ self.cb_distance_enterd.setCheckable(False)
+
+ lbl_distance = QLabel("Distance (d)")
+ self.input_distance = QLineEdit()
+
+ # self.btn_apply = QPushButton('Move chuck')
+ layout.addWidget(lbl_distance, 6, 0, 1, 1)
+ layout.addWidget(self.input_distance, 6, 1, 1, 1)
+ self.btn_measurement_done = QPushButton("Apply")
+ layout.addWidget(self.btn_measurement_done, 6, 2, 1, 2)
+ self.btn_measurement_done.clicked.connect(lambda: self.move_probes_back(probe_movement=250))
+ self.registerField('distance*', self.input_distance)
+
+ self.setLayout(layout)
+
+
+
+ def move_back_to_cal_structure(self, probe_movement=250):
+ self.move_chuck_x_y(-int(self.third_page.input_movement_x.text()), -int(self.third_page.lbl_movement_y.text()) )
+ self.move_input_probes_x_y(-probe_movement, 0)
+ self.move_output_probes_x_y(probe_movement, 0)
+
+ def move_probes_back(self, probe_movement=250):
+ self.move_input_probes_x_y(probe_movement, 0)
+ self.move_output_probes_x_y(-probe_movement, 0)
+ self.cb_distance_enterd: QCheckBox
+ self.cb_distance_enterd.setCheckable(True)
+ self.cb_distance_enterd.setChecked(True)
+ self.completeChanged.emit()
\ No newline at end of file
diff --git a/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py b/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..e65cd134badd553202ef305f81cc5211378acced
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py
@@ -0,0 +1,50 @@
+from PySide6.QtWidgets import QVBoxLayout, QLabel, QPushButton
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class SecondWizardPage(WizardPage):
+
+ def __init__(self, prober: Prober.Controller, parent=None):
+ super().__init__(prober, parent)
+ self.setTitle("Initial Setup")
+ self.setSubTitle("In this step, the home position will be set.")
+
+ layout = QVBoxLayout()
+ labeli = QLabel("The structure file relies on 'relative' positions to a 'zero' point. Usually such a suitable"
+ "structure can be chosen as the 'die' origin. From this 'zero' position, "
+ "every coordinates (x, y) is used to measure the distance to"
+ "the to/be measured structures.")
+ labeli.setWordWrap(True)
+ layout.addWidget(labeli)
+
+ label1 = QLabel("Use the same 'mark' in the Klayout file and on the wafer. Usually the die's edge is a good"
+ "point.\n")
+ layout.addWidget(label1)
+
+ # ==============================================================================================================
+ task_move_chuck, _ = self.add_task(
+ "1. Manually move chuck to the calibration structure",
+ "Manually move the Chuck to the calibration structure using the the Velox Chuck Control. "
+ "Then move the Probes using the FFI Photonic Interface to place it exaclty above the grating couplers.",
+ "task_move_chuck*")
+ layout.addWidget(task_move_chuck)
+ layout.addWidget(self.add_graphics(path=f'{self.imgf}/Step2_1.png'))
+
+ # ==============================================================================================================
+ task_area_scan, self.cb_area_scan = self.add_task(
+ "2. Perform an 'Area Scan'",
+ "If the Probes are moved, perform an 'Area Scan' to find the best position of the probes."
+ "The program may freez during the area scan.",
+ "task_area_scan*")
+ self.cb_area_scan.setCheckable(True)
+ layout.addWidget(task_area_scan)
+ self.btn_area_scan = QPushButton('Perform Area Scan (Input/Output)')
+ self.txt_coupled_power = QLabel('In: N/A, Out:N/A - Not performed.')
+ layout.addWidget(self.btn_area_scan)
+ layout.addWidget(self.txt_coupled_power)
+ self.btn_area_scan.clicked.connect(lambda: self.area_scan(self.txt_coupled_power, self.cb_area_scan))
+
+ self.setLayout(layout)
+
diff --git a/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py b/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..52982499b43fc5f72998ba6e7200994eb4f0dbce
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py
@@ -0,0 +1,76 @@
+from PySide6.QtWidgets import QGridLayout, QLabel, QLineEdit, QPushButton, QLineEdit
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class ThirdWizardPage(WizardPage):
+ def __init__(self, prober: Prober.Controller, parent=None):
+ super().__init__(prober, parent)
+
+ self.setTitle("Selecting the reference structure.")
+ layout = QGridLayout()
+ # ==============================================================================================================
+ task_moved_to_ref_structure, _ = self.add_task(
+ "1. Place the Scope over the Input Probe.",
+ "Try to match the center point using the scope's cross. It is useful to set the scope home position to the"
+ "current position.", "task_moved_scope*")
+
+ layout.addWidget(task_moved_to_ref_structure, 0, 0, 1, 4)
+ graphics1 = self.add_graphics(f'{self.imgf}/Step2_1.png')
+ layout.addWidget(graphics1, 1, 0, 1, 4)
+
+ # ==============================================================================================================
+ task_move_to_home, _ = self.add_task(
+ "2. Move back to the zero position",
+ "Move back to the 'zero' point. This point is your arbitrarily chosen reference point and must be the same "
+ "in your layout file and the prober. Usually a mark or the die's corner is used, however not mandatory.\n"
+ "Input the X and y distance from the calibration structure to the 'zero' point. Make sure to have the "
+ "signs correct.",
+ "task_set_chuck_home_position*")
+ layout.addWidget(task_move_to_home, 2, 0, 1, 4)
+ # Input the X and y distance from the calibration structure to the Home Position
+ graphics1 = self.add_graphics(f'{self.imgf}/Step2_2.png', max_width=400)
+ layout.addWidget(graphics1, 3, 0, 1, 4)
+ self.lbl_movement_x = QLabel("X Movement: ")
+ self.input_movement_x = QLineEdit("-950")
+
+ layout.addWidget(self.lbl_movement_x, 4, 0)
+ layout.addWidget(self.input_movement_x, 4, 1)
+
+ self.input_movement_y = QLabel("Y Movement: ")
+ self.lbl_movement_y = QLineEdit("2120")
+ layout.addWidget(self.input_movement_y, 4, 2)
+ layout.addWidget(self.lbl_movement_y, 4, 3)
+
+ self.btn_move_to_home = QPushButton('Move chuck')
+ layout.addWidget(self.btn_move_to_home, 5, 0, 1, 4)
+ self.btn_move_to_home.clicked.connect(
+ lambda: self.move_chuck_x_y(int(self.input_movement_x.text()), int(self.lbl_movement_y.text())))
+
+ # ==============================================================================================================
+ task_set_chuck_home_position, _ = self.add_task(
+ "3. Set Chuck Home position",
+ "Use the 'Set to Current Position' to the left to reset the prober's coordinates to (0,0,Z)",
+ "task_set_chuck_home_position*")
+ layout.addWidget(task_set_chuck_home_position, 6, 0, 1, 4)
+ # layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'), 7, 0, 1, 4)
+ self.btn_move_to_home = QPushButton('Set chuck Home')
+ layout.addWidget(self.btn_move_to_home, 7, 0, 1, 4)
+ self.btn_move_to_home.clicked.connect(lambda: self.prober.set_chuck_home())
+
+ self.setLayout(layout)
+
+ # def get_distance(self) -> float:
+ # value = self.input_distance.text()
+ # try:
+ # distance = int(value)
+ # except Exception as e:
+ # self.logger.error(f"Can't convert {value} to int!")
+ # raise e
+ # return distance
+ #
+ # def move_chuck(self):
+ # distance = self.get_distance()
+ # distance_half = int(distance / 2)
+ # self.move_chuck_x_y(x=-distance_half, y=0)
diff --git a/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py b/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..46e10f4d14401a3e1ff9ffeed9ef3d73169663df
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py
@@ -0,0 +1,146 @@
+import logging
+import pathlib
+
+import numpy as np
+from PySide6 import QtGui
+from PySide6.QtCore import QSize, Qt
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QWizardPage, QLabel, QWidget, QCheckBox, QVBoxLayout, QMessageBox, QSizePolicy
+
+import Prober as Prober
+from pathes import image_root
+
+
+class WizardPage(QWizardPage):
+ def __init__(self, prober: Prober.Controller, parent=None):
+ super().__init__(parent)
+ self.parent = parent
+ self.prober = prober
+ self.logger = logging.getLogger('Wizard')
+
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ #self.parent.setMinimumWidth(780)
+ self.parent.setMaximumHeight(900)
+ self.parent.setMinimumHeight(900)
+
+ self.imgf = f"{image_root}/wizard_img"
+
+ # Stores all included graphics for later accessing via the resize Event
+ self.graphics = []
+
+ # ==================================================================================================================
+ # For adding UI Elements
+ # ==================================================================================================================
+ def add_graphics(self, path, max_width=None):
+ print(f"Added {path}")
+ graphics = QLabel(self)
+ pixmap = QPixmap(str(pathlib.PurePosixPath(path)))
+ self._resize_graphics_on_resize_event(graphics, pixmap, max_width=max_width)
+ self.graphics.append({"graphics": graphics, "pixmap": pixmap})
+ return graphics
+
+ def add_task(self, title, description, task_desc) -> (QWidget, QCheckBox):
+ widget = QWidget()
+ layout = QVBoxLayout()
+ widget.setLayout(layout)
+
+ task = QCheckBox(title)
+ task.setStyleSheet(
+ "QCheckBox:unchecked{ color: red; }QCheckBox:checked{ color: black; }")
+ label = QLabel(description)
+ label.setWordWrap(True)
+ layout.addWidget(task)
+ layout.addWidget(label)
+ self.registerField(task_desc, task)
+ return widget, task
+
+ # ==================================================================================================================
+ # Message Boxes
+ # ==================================================================================================================
+ def display_mbox_warning(self, text, title):
+ self.logger.warning(text)
+ warning_dialog = QMessageBox()
+ warning_dialog.setText(text)
+ warning_dialog.setIcon(QMessageBox.Warning)
+ warning_dialog.setWindowTitle(title)
+ warning_dialog.show()
+ warning_dialog.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Abort)
+ btn_ok = warning_dialog.button(QMessageBox.StandardButton.Ok)
+ btn_abort = warning_dialog.button(QMessageBox.StandardButton.Abort)
+ warning_dialog.exec()
+ if warning_dialog.clickedButton() == btn_ok:
+ return True
+ elif warning_dialog.clickedButton() == btn_abort:
+ return False
+
+ def display_mbox_error(self, text, title):
+ self.logger.error(text)
+ warning_dialog = QMessageBox()
+ warning_dialog.setText(text)
+ warning_dialog.setIcon(QMessageBox.Critical)
+ warning_dialog.setWindowTitle(title)
+ warning_dialog.show()
+ warning_dialog.exec()
+
+ def display_mbox_ok(self, text, title):
+ self.logger.error(text)
+ warning_dialog = QMessageBox()
+ warning_dialog.setText(text)
+ warning_dialog.setIcon(QMessageBox.Information)
+ warning_dialog.setWindowTitle(title)
+ warning_dialog.show()
+ warning_dialog.exec()
+
+ # ==================================================================================================================
+ # Prober Controls
+ # ==================================================================================================================
+ def move_chuck_x_y(self, x, y):
+ if self.display_mbox_warning(f"The chuck is about to move relatively {x} in x-direction und {y} y-direction. "
+ f"Continue?",
+ "Move chuck"):
+ self.prober.move_chuck(x_value=x, y_value=y, pos_ref="R")
+ # Enable the next button when the user has entered a non-empty
+ # string.
+ # self.cb_distance_enterd.setCheckable(True)
+ # self.cb_distance_enterd.setChecked(True)
+ self.completeChanged.emit()
+ else:
+ self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+ return
+
+ def area_scan(self, txt_coupled_power: QLabel, checkbox: QCheckBox, threshold: float = -70):
+ x_1, x_2, y_1, y_2, input_power, output_power = self.prober.opt_if.area_scan(True, True)
+ if input_power > threshold and output_power > threshold:
+ checkbox.setCheckable(True)
+ checkbox.setChecked(True)
+ # self.distance_task.setCheckable(False)
+ txt_coupled_power.setText(f'In: {input_power}, Out: {output_power} - Passed/Threshold < -70dB.')
+ self.completeChanged.emit()
+ else:
+ txt_coupled_power.setText(f'In: {input_power}, Out: {output_power} - Not passed/Threshold < -70dB.')
+
+ def move_input_probes_x_y(self, x: float, y: float):
+ self.prober.opt_if.move_optical_probe(0, x, y, pos_ref='R')
+
+ def move_output_probes_x_y(self, x: float, y: float):
+ self.prober.opt_if.move_optical_probe(1, x, y, pos_ref='R')
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def _resize_graphics_on_resize_event(self, graphics, pixmap, max_width=None):
+
+ aspect_ratio = pixmap.height() / pixmap.width()
+ if max_width is None:
+ max_width = int(self.parent.width()*0.95)
+ max_height = np.floor(aspect_ratio * max_width)
+ # print(f"{aspect_ratio}: {max_width}x{max_height} - {max_height / max_width}")
+
+ graphics.setPixmap(pixmap.scaled(QSize(max_width, max_height),
+ Qt.AspectRatioMode.KeepAspectRatio,
+ Qt.SmoothTransformation))
+
+ def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
+ # print(self.graphics)
+ for ele in self.graphics:
+ self._resize_graphics_on_resize_event(ele['graphics'], ele['pixmap'])
diff --git a/src/FlexSensor/InitialSetupWizard/pages/tmp.txt b/src/FlexSensor/InitialSetupWizard/pages/tmp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..24c71afe88dd6af291a554f0974f24ced2974318
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/tmp.txt
@@ -0,0 +1,25 @@
+task_move_chuck, _ = self.add_task(
+ "1. Move chuck to the 'mark'",
+ "Use the same 'mark' in the Klayout file and on the wafer. Usually the die's edge is "
+ "a good point. Move your chuck, thus the yellow cross precisely matches "
+ "the selected mark.", "task_move_chuck*")
+layout.addWidget(task_move_chuck)
+
+
+
+
+
+
+task_set_chuck_home_position, _ = self.add_task(
+ "2. Set Chuck Home position",
+ "Use the 'Set to Current Position' to the left to reset the "
+ "prober's coordinates to (0,0,Z)",
+ "task_set_chuck_home_position*")
+layout.addWidget(task_set_chuck_home_position)
+layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'))
+
+
+
+label2 = QLabel("The Prober's coordinates are now at zero.")
+label2.setWordWrap(True)
+layout.addWidget(label2)
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/__init__.py b/src/FlexSensor/MainWindow/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/controller/MainThreadController.py b/src/FlexSensor/MainWindow/controller/MainThreadController.py
new file mode 100644
index 0000000000000000000000000000000000000000..47a94951948b33be77f76d7a86bf3829c8b509b7
--- /dev/null
+++ b/src/FlexSensor/MainWindow/controller/MainThreadController.py
@@ -0,0 +1,99 @@
+import logging
+
+from PySide6.QtCore import QThread
+
+import ConfigHandler as Config
+import Laser as Laser
+import AD2CaptDevice as AD2Dev
+import Prober as Prober
+import MeasurementEvaluationTool
+
+from MainWindow.model.MainThreadModel import MainThreadModel
+from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
+from Prober.controller.ProberController import ProberController
+
+
+class MainThreadController(object):
+ def __init__(self, model: MainThreadModel):
+ self.logger = logging.getLogger("MainThread")
+ self._model = model
+
+ # self.model._laser_controller.connect_device(self._vaut_config.laser_config.get_port())
+
+ mypath = (
+ r'F:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement')
+
+ # Device init: Connect signals and slots
+ self._device_initialization()
+
+ # Load the measurement routine
+ self.model.measurement_routine = self._load_measurement_routine()
+
+ # Thread for the measurement routine
+ self.measurement_thread = QThread()
+
+ # Create the working folders
+ self._create_working_folders()
+
+ @property
+ def model(self) -> MainThreadModel:
+ return self._model
+
+ def start_measurement_routine(self):
+ # 1. Create all working folders
+ self._create_working_folders()
+ self._move_measurement_routine_thread(self.model.measurement_routine)
+ self.measurement_thread.start()
+ self.logger.info("Started worker thread for running the measurement routine.")
+
+ if self.measurement_thread.isRunning():
+ self.logger.debug("Thread is running.")
+
+ def _create_working_folders(self):
+ """Creates all working folders to store the measurement data.
+ """
+ self.model.vaut_config.setup_folders()
+
+ def _move_measurement_routine_thread(self, measurement_routine):
+ measurement_routine.moveToThread(self.measurement_thread)
+ 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:
+ """
+ Loads the measurement routine and initializes it.
+
+ Returns:
+ MeasurementRoutine: The measurement routine.
+
+ 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 = MeasurementRoutine(
+ self.model.laser_controller,
+ self.model.ad2_controller,
+ self.model.prober_controller,
+ self.model.vaut_config)
+ self.logger.debug("Initialized MeasurementRoutine.")
+ return measurement_routine
+
+ def _device_initialization(self):
+ """
+ Initializes all devices and connects the signals and slots.
+ """
+ self.model.ad2_controller.connect_device(0)
+ # # Connect the required signals and slots
+ # self.model.laser_model.signals.laser_ready_for_sweep_changed.connect(
+ # self.model.ad2_controller.start_capture_flag)
+ #
+ # self.model.ad2_model.signals.device_ready_changed.connect(
+ # self.model.laser_controller.start_wavelength_sweep)
+ #
+ # self.model.laser_model.signals.wavelength_sweep_running_changed.connect(
+ # self.model.ad2_controller.set_ad2_acq_status)
+
+ self.device_are_init = True
diff --git a/src/FlexSensor/MainWindow/controller/__init__.py b/src/FlexSensor/MainWindow/controller/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/model/MainThreadModel.py b/src/FlexSensor/MainWindow/model/MainThreadModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c4a7c9aace1588fe6bd8d7dac3de035088606df
--- /dev/null
+++ b/src/FlexSensor/MainWindow/model/MainThreadModel.py
@@ -0,0 +1,170 @@
+from PySide6.QtCore import QObject, Signal
+
+import Laser as Laser
+import AD2CaptDevice as AD2Dev
+import Prober as Prober
+import MeasurementEvaluationTool as met
+import ConfigHandler as Config
+from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
+
+
+class MainThreadSignals(QObject):
+ # Signals for the main thread
+ vaut_config_changed = Signal(Config.VAutomatorConfig)
+ laser_changed = Signal(Laser.Model, Laser.Controller, Laser.ControlWindow)
+ ad2_changed = Signal(AD2Dev.Model, AD2Dev.Controller, AD2Dev.ControlWindow)
+ prober_changed = Signal(Prober.Model, Prober.Controller, Prober.ControlWindow)
+
+ measurement_routine_changed = Signal(MeasurementRoutine)
+
+class MainThreadModel(QObject):
+
+ def __init__(self, vaut_config: Config.VAutomatorConfig):
+ super().__init__()
+
+ self.signals = MainThreadSignals()
+
+ self._vaut_config: Config.VAutomatorConfig = vaut_config
+
+ self._measurement_routine: MeasurementRoutine = None
+
+
+
+ self._ad2_model: AD2Dev.Model = AD2Dev.Model(self.vaut_config.ad2_device_config)
+ self._ad2_controller: AD2Dev.Controller = AD2Dev.Controller(
+ self._ad2_model)
+ self._ad2_window: AD2Dev.ControlWindow = AD2Dev.ControlWindow(
+ self._ad2_model, self._ad2_controller)
+
+ # Devices
+ self._laser_model: Laser.Model = Laser.Model(self.vaut_config.laser_config)
+ self._laser_controller: Laser.Controller = Laser.Controller(self._laser_model, self._ad2_controller)
+
+ self._laser_window: Laser.ControlWindow = Laser.ControlWindow(
+ self._laser_model,
+ self._laser_controller)
+
+ self._prober_model: Prober.Model = Prober.Model()
+ self._prober_controller: Prober.Controller = Prober.Controller(
+ self._prober_model,
+ self.vaut_config)
+ self._prober_window: Prober.ControlWindow = Prober.ControlWindow(
+ self._prober_model,
+ self._prober_controller)
+
+ # Widgets
+ self.mea_eval_tool_model: met.Model = met.Model()
+ self.mea_eval_tool_controller: met.Controller = met.Controller(
+ self.mea_eval_tool_model)
+ self.mea_eval_tool_window: met.View = met.View(
+ self.mea_eval_tool_model,
+ self.mea_eval_tool_controller)
+
+ # Implement all getter and setter methods for the model here
+ @property
+ def vaut_config(self) -> Config.VAutomatorConfig:
+ return self._vaut_config
+
+ @vaut_config.setter
+ def vaut_config(self, value: Config.VAutomatorConfig):
+ self._vaut_config = value
+ self.signals.vaut_config_changed.emit(self.vaut_config)
+
+ @property
+ def laser_model(self) -> Laser.Model:
+ return self._laser_model
+
+ @laser_model.setter
+ def laser_model(self, value: Laser.Model):
+ self._laser_model = value
+ self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+
+ @property
+ def laser_controller(self) -> Laser.Controller:
+ return self._laser_controller
+
+ @laser_controller.setter
+ def laser_controller(self, value: Laser.Controller):
+ self._laser_controller = value
+ self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+ @property
+ def laser_window(self) -> Laser.ControlWindow:
+ return self._laser_window
+
+ @laser_window.setter
+ def laser_window(self, value: Laser.ControlWindow):
+ self._laser_window = value
+ self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+
+ @property
+ def ad2_model(self) -> AD2Dev.Model:
+ return self._ad2_model
+
+ @ad2_model.setter
+ def ad2_model(self, value: AD2Dev.Model):
+ self._ad2_model = value
+ self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+ @property
+ def ad2_controller(self) -> AD2Dev.Controller:
+ return self._ad2_controller
+
+ @ad2_controller.setter
+ def ad2_controller(self, value: AD2Dev.Controller):
+ self._ad2_controller = value
+ self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+ @property
+ def ad2_window(self) -> AD2Dev.ControlWindow:
+ return self._ad2_window
+
+ @ad2_window.setter
+ def ad2_window(self, value: AD2Dev.ControlWindow):
+ self._ad2_window = value
+ self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+ @property
+ def prober_model(self) -> Prober.Model:
+ return self._prober_model
+
+ @prober_model.setter
+ def prober_model(self, value: Prober.Model):
+ self._prober_model = value
+ self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+ @property
+ def prober_controller(self) -> Prober.Controller:
+ return self._prober_controller
+
+ @prober_controller.setter
+ def prober_controller(self, value: Prober.Controller):
+ self._prober_controller = value
+ self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+ @property
+ def prober_window(self) -> Prober.ControlWindow:
+ return self._prober_window
+
+ @prober_window.setter
+ def prober_window(self, value: Prober.ControlWindow):
+ self._prober_window = value
+ self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+
+ @property
+ def measurement_routine(self) -> MeasurementRoutine:
+ return self._measurement_routine
+
+ @measurement_routine.setter
+ def measurement_routine(self, value: MeasurementRoutine):
+ self._measurement_routine = value
+ self.signals.measurement_routine_changed.emit(self.measurement_routine)
+
+
+
+
+
+
diff --git a/src/FlexSensor/MainWindow/model/__init__.py b/src/FlexSensor/MainWindow/model/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/resources/MainView.ui b/src/FlexSensor/MainWindow/resources/MainView.ui
new file mode 100644
index 0000000000000000000000000000000000000000..3cb89cb8e02edb91db7c753b193dfc886fd4d7a0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/MainView.ui
@@ -0,0 +1,2608 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <author>Wanderson M. Pimenta</author>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1085</width>
+ <height>753</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>940</width>
+ <height>560</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <property name="toolTipDuration">
+ <number>-9</number>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <widget class="QWidget" name="styleSheet">
+ <property name="maximumSize">
+ <size>
+ <width>16777214</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTipDuration">
+ <number>0</number>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">/* /////////////////////////////////////////////////////////////////////////////////////////////////
+
+SET APP STYLESHEET - FULL STYLES HERE
+DARK THEME - DRACULA COLOR BASED
+
+///////////////////////////////////////////////////////////////////////////////////////////////// */
+
+QWidget{
+ color: rgb(221, 221, 221);
+ font: 10pt "Segoe UI";
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Tooltip */
+QToolTip {
+ color: #ffffff;
+ background-color: rgba(33, 37, 43, 180);
+ border: 1px solid rgb(44, 49, 58);
+ background-image: none;
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 2px solid rgb(255, 121, 198);
+ text-align: left;
+ padding-left: 8px;
+ margin: 0px;
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Bg App */
+#bgApp {
+ background-color: rgb(40, 44, 52);
+ border: 1px solid rgb(44, 49, 58);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Left Menu */
+#leftMenuBg {
+ background-color: rgb(33, 37, 43);
+}
+#topLogo {
+ background-color: rgb(33, 37, 43);
+ border-image: url(:/images/images/images/FlexSensorIcon.png) 10 0 0 0 strech strech;
+ background-position: centered;
+ background-repeat: no-repeat;
+}
+#titleLeftApp { font: 63 12pt "Segoe UI Semibold"; }
+#titleLeftDescription { font: 8pt "Segoe UI"; color: rgb(189, 147, 249); }
+
+/* MENUS */
+
+
+
+#topMenu .QPushButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 22px solid transparent;
+ background-color: transparent;
+ text-align: left;
+ padding-left: 44px;
+}
+#topMenu .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#topMenu .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+#bottomMenu .QPushButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 20px solid transparent;
+ background-color:transparent;
+ text-align: left;
+ padding-left: 44px;
+}
+#bottomMenu .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#bottomMenu .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+#leftMenuFrame{
+ border-top: 3px solid rgb(44, 49, 58);
+}
+
+/* Toggle Button */
+#toggleButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 20px solid transparent;
+ background-color: rgb(37, 41, 48);
+ text-align: left;
+ padding-left: 44px;
+ color: rgb(113, 126, 149);
+}
+#toggleButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#toggleButton:pressed {
+ background-color: rgb(189, 147, 249);
+}
+
+/* Title Menu */
+/*#titleRightInfo { padding-left: 10px; }*/
+
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Extra Tab */
+#extraLeftBox {
+ background-color: rgb(44, 49, 58);
+}
+#extraTopBg{
+ background-color: rgb(189, 147, 249)
+}
+
+/* Icon */
+#extraIcon {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-image: url(:/icons/images/icons/icon_settings.png);
+}
+
+/* Label */
+#extraLabel { color: rgb(255, 255, 255); }
+
+/* Btn Close */
+#extraCloseColumnBtn { background-color: rgba(255, 255, 255, 0); border: none; border-radius: 5px; }
+#extraCloseColumnBtn:hover { background-color: rgb(196, 161, 249); border-style: solid; border-radius: 4px; }
+#extraCloseColumnBtn:pressed { background-color: rgb(180, 141, 238); border-style: solid; border-radius: 4px; }
+
+/* Extra Content */
+#extraContent{
+ border-top: 3px solid rgb(40, 44, 52);
+}
+
+/* Extra Top Menus */
+#extraTopMenu .QPushButton {
+ /*background-position: left center;*/
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 22px solid transparent;
+ background-color:transparent;
+ text-align: left;
+ padding-left: 44px;
+}
+#extraTopMenu .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#extraTopMenu .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Content App */
+#contentTopBg{
+ background-color: rgb(33, 37, 43);
+}
+#contentBottom{
+ border-top: 3px solid rgb(44, 49, 58);
+}
+
+/* Top Buttons */
+#rightButtons .QPushButton { background-color: rgba(255, 255, 255, 0); border: none; border-radius: 5px; }
+#rightButtons .QPushButton:hover { background-color: rgb(44, 49, 57); border-style: solid; border-radius: 4px; }
+#rightButtons .QPushButton:pressed { background-color: rgb(23, 26, 30); border-style: solid; border-radius: 4px; }
+
+/* Theme Settings */
+#extraRightBox { background-color: rgb(44, 49, 58); }
+#themeSettingsTopDetail { background-color: rgb(189, 147, 249); }
+
+/* Bottom Bar */
+#bottomBar { background-color: rgb(44, 49, 58); }
+#bottomBar QLabel { font-size: 11px; color: rgb(113, 126, 149); padding-left: 10px; padding-right: 10px; padding-bottom: 2px; }
+
+/* CONTENT SETTINGS */
+/* MENUS */
+#contentSettings .QPushButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 22px solid transparent;
+ background-color:transparent;
+ text-align: left;
+ padding-left: 44px;
+}
+#contentSettings .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#contentSettings .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+QTableWidget */
+QTableWidget {
+ background-color: transparent;
+ padding: 10px;
+ border-radius: 5px;
+ gridline-color: rgb(44, 49, 58);
+ border-bottom: 1px solid rgb(44, 49, 60);
+}
+QTableWidget::item{
+ border-color: rgb(44, 49, 60);
+ padding-left: 5px;
+ padding-right: 5px;
+ gridline-color: rgb(44, 49, 60);
+}
+QTableWidget::item:selected{
+ background-color: rgb(189, 147, 249);
+}
+QHeaderView::section{
+ background-color: rgb(33, 37, 43);
+ max-width: 30px;
+ border: 1px solid rgb(44, 49, 58);
+ border-style: none;
+ border-bottom: 1px solid rgb(44, 49, 60);
+ border-right: 1px solid rgb(44, 49, 60);
+}
+QTableWidget::horizontalHeader {
+ background-color: rgb(33, 37, 43);
+}
+QHeaderView::section:horizontal
+{
+ border: 1px solid rgb(33, 37, 43);
+ background-color: rgb(33, 37, 43);
+ padding: 3px;
+ border-top-left-radius: 7px;
+ border-top-right-radius: 7px;
+}
+QHeaderView::section:vertical
+{
+ border: 1px solid rgb(44, 49, 60);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+LineEdit */
+QLineEdit {
+ background-color: rgb(33, 37, 43);
+ border-radius: 5px;
+ border: 2px solid rgb(33, 37, 43);
+ padding-left: 10px;
+ selection-color: rgb(255, 255, 255);
+ selection-background-color: rgb(255, 121, 198);
+}
+QLineEdit:hover {
+ border: 2px solid rgb(64, 71, 88);
+}
+QLineEdit:focus {
+ border: 2px solid rgb(91, 101, 124);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+PlainTextEdit */
+QPlainTextEdit {
+ background-color: rgb(27, 29, 35);
+ border-radius: 5px;
+ padding: 10px;
+ selection-color: rgb(255, 255, 255);
+ selection-background-color: rgb(255, 121, 198);
+}
+QPlainTextEdit QScrollBar:vertical {
+ width: 8px;
+ }
+QPlainTextEdit QScrollBar:horizontal {
+ height: 8px;
+ }
+QPlainTextEdit:hover {
+ border: 2px solid rgb(64, 71, 88);
+}
+QPlainTextEdit:focus {
+ border: 2px solid rgb(91, 101, 124);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+ScrollBars */
+QScrollBar:horizontal {
+ border: none;
+ background: rgb(52, 59, 72);
+ height: 8px;
+ margin: 0px 21px 0 21px;
+ border-radius: 0px;
+}
+QScrollBar::handle:horizontal {
+ background: rgb(189, 147, 249);
+ min-width: 25px;
+ border-radius: 4px
+}
+QScrollBar::add-line:horizontal {
+ border: none;
+ background: rgb(55, 63, 77);
+ width: 20px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+QScrollBar::sub-line:horizontal {
+ border: none;
+ background: rgb(55, 63, 77);
+ width: 20px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal
+{
+ background: none;
+}
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+ background: none;
+}
+ QScrollBar:vertical {
+ border: none;
+ background: rgb(52, 59, 72);
+ width: 8px;
+ margin: 21px 0 21px 0;
+ border-radius: 0px;
+ }
+ QScrollBar::handle:vertical {
+ background: rgb(189, 147, 249);
+ min-height: 25px;
+ border-radius: 4px
+ }
+ QScrollBar::add-line:vertical {
+ border: none;
+ background: rgb(55, 63, 77);
+ height: 20px;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+ }
+ QScrollBar::sub-line:vertical {
+ border: none;
+ background: rgb(55, 63, 77);
+ height: 20px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+ }
+ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
+ background: none;
+ }
+
+ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
+ background: none;
+ }
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+CheckBox */
+QCheckBox::indicator {
+ border: 3px solid rgb(52, 59, 72);
+ width: 15px;
+ height: 15px;
+ border-radius: 10px;
+ background: rgb(44, 49, 60);
+}
+QCheckBox::indicator:hover {
+ border: 3px solid rgb(58, 66, 81);
+}
+QCheckBox::indicator:checked {
+ background: 3px solid rgb(52, 59, 72);
+ border: 3px solid rgb(52, 59, 72);
+ background-image: url(:/icons/images/icons/cil-check-alt.png);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+RadioButton */
+QRadioButton::indicator {
+ border: 3px solid rgb(52, 59, 72);
+ width: 15px;
+ height: 15px;
+ border-radius: 10px;
+ background: rgb(44, 49, 60);
+}
+QRadioButton::indicator:hover {
+ border: 3px solid rgb(58, 66, 81);
+}
+QRadioButton::indicator:checked {
+ background: 3px solid rgb(94, 106, 130);
+ border: 3px solid rgb(52, 59, 72);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+ComboBox */
+QComboBox{
+ background-color: rgb(27, 29, 35);
+ border-radius: 5px;
+ border: 2px solid rgb(33, 37, 43);
+ padding: 5px;
+ padding-left: 10px;
+}
+QComboBox:hover{
+ border: 2px solid rgb(64, 71, 88);
+}
+QComboBox::drop-down {
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 25px;
+ border-left-width: 3px;
+ border-left-color: rgba(39, 44, 54, 150);
+ border-left-style: solid;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ background-image: url(:/icons/images/icons/cil-arrow-bottom.png);
+ background-position: center;
+ background-repeat: no-reperat;
+ }
+QComboBox QAbstractItemView {
+ color: rgb(255, 121, 198);
+ background-color: rgb(33, 37, 43);
+ padding: 10px;
+ selection-background-color: rgb(39, 44, 54);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Sliders */
+QSlider::groove:horizontal {
+ border-radius: 5px;
+ height: 10px;
+ margin: 0px;
+ background-color: rgb(52, 59, 72);
+}
+QSlider::groove:horizontal:hover {
+ background-color: rgb(55, 62, 76);
+}
+QSlider::handle:horizontal {
+ background-color: rgb(189, 147, 249);
+ border: none;
+ height: 10px;
+ width: 10px;
+ margin: 0px;
+ border-radius: 5px;
+}
+QSlider::handle:horizontal:hover {
+ background-color: rgb(195, 155, 255);
+}
+QSlider::handle:horizontal:pressed {
+ background-color: rgb(255, 121, 198);
+}
+
+QSlider::groove:vertical {
+ border-radius: 5px;
+ width: 10px;
+ margin: 0px;
+ background-color: rgb(52, 59, 72);
+}
+QSlider::groove:vertical:hover {
+ background-color: rgb(55, 62, 76);
+}
+QSlider::handle:vertical {
+ background-color: rgb(189, 147, 249);
+ border: none;
+ height: 10px;
+ width: 10px;
+ margin: 0px;
+ border-radius: 5px;
+}
+QSlider::handle:vertical:hover {
+ background-color: rgb(195, 155, 255);
+}
+QSlider::handle:vertical:pressed {
+ background-color: rgb(255, 121, 198);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+CommandLinkButton */
+QCommandLinkButton {
+ color: rgb(255, 121, 198);
+ border-radius: 5px;
+ padding: 5px;
+ color: rgb(255, 170, 255);
+}
+QCommandLinkButton:hover {
+ color: rgb(255, 170, 255);
+ background-color: rgb(44, 49, 60);
+}
+QCommandLinkButton:pressed {
+ color: rgb(189, 147, 249);
+ background-color: rgb(52, 58, 71);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Button */
+#pagesContainer QPushButton {
+ border: 2px solid rgb(52, 59, 72);
+ border-radius: 5px;
+ background-color: rgb(52, 59, 72);
+}
+#pagesContainer QPushButton:hover {
+ background-color: rgb(57, 65, 80);
+ border: 2px solid rgb(61, 70, 86);
+}
+#pagesContainer QPushButton:pressed {
+ background-color: rgb(35, 40, 49);
+ border: 2px solid rgb(43, 50, 61);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+QToolButton {
+border-image: url(:/img/btn_mid_0.png);
+text-align: center;
+}
+QToolButton::menu-indicator { image: none; }
+
+
+#menuBar .QPushButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ /*border-left: 22px solid transparent;*/
+ /*text-align: center;*/
+ padding-right: 10px;
+}
+#menuBar .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#menuBar .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+#menuBar .QToolButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ /*border-left: 22px solid transparent;*/
+ /*text-align: center;*/
+ padding-right: 10px;
+}
+#menuBar .QToolButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#menuBar .QToolButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+
+#extraMenuBar .QToolButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ /*border-left: 22px solid transparent;*/
+ /*text-align: center;*/
+ padding-right: 10px;
+}
+#extraMenuBar .QToolButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#extraMenuBar .QToolButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+
+#extraMenuBar .QPushButton {
+ /*background-position: left center;*/
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 22px solid transparent;
+ text-align: center;
+ /*padding-left: 44px;*/
+}
+#extraMenuBar .QPushButton:hover {
+ background-color: rgb(40, 44, 52);
+}
+#extraMenuBar .QPushButton:pressed {
+ background-color: rgb(189, 147, 249);
+ color: rgb(255, 255, 255);
+}
+
+
+
+
+/* QMenu ------------------------------------------------------------------
+
+examples: https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu
+
+--------------------------------------------------------------------------- */
+QMenu {
+ background-color: rgb(40, 44, 52);
+ margin: 2px; /* some spacing around the menu */
+}
+
+QMenu::item {
+ padding: 2px 25px 2px 20px;
+ border: 1px solid transparent; /* reserve space for selection border */
+}
+
+QMenu::item:selected {
+ border-color: darkblue;
+ background: rgba(100, 100, 100, 150);
+}
+
+QMenu::icon:checked { /* appearance of a 'checked' icon */
+ background: gray;
+ border: 1px inset gray;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ bottom: 1px;
+ left: 1px;
+}
+
+QMenu::separator {
+ height: 2px;
+ background: lightblue;
+ margin-left: 10px;
+ margin-right: 5px;
+}
+
+QMenu::indicator {
+ width: 13px;
+ height: 13px;
+}
+
+/*
+
+QMenu::indicator:non-exclusive:unchecked {
+ image: url(:/images/checkbox_unchecked.png);
+}
+
+QMenu::indicator:non-exclusive:unchecked:selected {
+ image: url(:/images/checkbox_unchecked_hover.png);
+}
+
+QMenu::indicator:non-exclusive:checked {
+ image: url(:/images/checkbox_checked.png);
+}
+
+QMenu::indicator:non-exclusive:checked:selected {
+ image: url(:/images/checkbox_checked_hover.png);
+}
+
+
+QMenu::indicator:exclusive:unchecked {
+ image: url(:/images/radiobutton_unchecked.png);
+}
+
+QMenu::indicator:exclusive:unchecked:selected {
+ image: url(:/images/radiobutton_unchecked_hover.png);
+}
+
+QMenu::indicator:exclusive:checked {
+ image: url(:/images/radiobutton_checked.png);
+}
+
+QMenu::indicator:exclusive:checked:selected {
+ image: url(:/images/radiobutton_checked_hover.png);
+}*/
+
+QTabWidget::pane {
+ border: 1px solid lightgray;
+ top:-1px;
+ background: rgb(40, 44, 52);
+}
+
+QTabBar::tab {
+ background: rgb(40, 44, 52);;
+ border: 1px solid lightgray;
+ padding: 2px;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+QTabBar::tab:selected {
+ background: rgb(189, 147, 249);
+ margin-bottom: -1px;
+}</string>
+ </property>
+ <layout class="QVBoxLayout" name="appMargins">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="bgApp">
+ <property name="toolTipDuration">
+ <number>0</number>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <layout class="QHBoxLayout" name="appLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="leftMenuBg">
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>60</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="topLogoInfo">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <widget class="QLabel" name="titleLeftApp">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>3</y>
+ <width>160</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>PyDracula</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QFrame" name="topLogo">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>32</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" name="titleLeftDescription">
+ <property name="geometry">
+ <rect>
+ <x>60</x>
+ <y>22</y>
+ <width>160</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>8</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Modern GUI / Flat Style</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="leftMenuFrame">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTipDuration">
+ <number>0</number>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalMenuLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="toggleBox">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="toggleButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/icon_menu.png);</string>
+ </property>
+ <property name="text">
+ <string>Hide</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="topMenu">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>10</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btn_start_measuring_routine">
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>60</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16660</width>
+ <height>60</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QPushButton {
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-left: 22px solid transparent;
+ background-color: rgb(36, 209, 21);
+ text-align: left;
+ padding-left: 44px;
+ background-image: url(:/icons/images/icons/cil-media-play.png);
+}
+
+QPushButton:hover {
+ background-color: rgb(26, 153, 16);
+}
+
+QPushButton:pressed {
+ background-color: rgb(20, 120, 12);
+ color: rgb(255, 255, 255);
+}
+
+
+</string>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_home">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-home.png);</string>
+ </property>
+ <property name="text">
+ <string>Home</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_adc_control">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-signal-cellular-3.png);</string>
+ </property>
+ <property name="text">
+ <string>ADC Control</string>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_laser_control">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-lightbulb.png);</string>
+ </property>
+ <property name="text">
+ <string>Laser Control</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_probe_control">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-action-redo.png);</string>
+ </property>
+ <property name="text">
+ <string>Probe Control</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_measured_data">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-description.png);</string>
+ </property>
+ <property name="text">
+ <string>Measured Data</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_exit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-x.png);</string>
+ </property>
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="bottomMenu">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="toggleLeftBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/icon_settings.png);</string>
+ </property>
+ <property name="text">
+ <string>Left Box</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="extraLeftBox">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>0</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QVBoxLayout" name="extraColumLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="extraTopBg">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="extraTopLayout">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QFrame" name="extraIcon">
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="extraLabel">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Left Box</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="extraCloseColumnBtn">
+ <property name="minimumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Close left box</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources.qrc">
+ <normaloff>:/icons/images/icons/icon_close.png</normaloff>:/icons/images/icons/icon_close.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="extraContent">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item alignment="Qt::AlignTop">
+ <widget class="QFrame" name="extraTopMenu">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btn_share">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-share-boxed.png);</string>
+ </property>
+ <property name="text">
+ <string>Share</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_adjustments">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-equalizer.png);</string>
+ </property>
+ <property name="text">
+ <string>Adjustments</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btn_more">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-layers.png);</string>
+ </property>
+ <property name="text">
+ <string>More</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="extraCenter">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="minimumSize">
+ <size>
+ <width>222</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background: transparent;</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Segoe UI'; font-size:10pt; font-weight:400; font-style:normal;">
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; color:#ff79c6;">PyDracula</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ffffff;">An interface created using Python and PySide (support for PyQt), and with colors based on the Dracula theme created by Zeno Rocha.</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ffffff;">MIT License</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#bd93f9;">Created by: Wanderson M. Pimenta</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; color:#ff79c6;">Convert UI</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#ffffff;">pyside6-uic main.ui &gt; ui_main.py</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; color:#ff79c6;">Convert QRC</span></p>
+<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#ffffff;">pyside6-rcc resources.qrc -o resources_rc.py</span></p></body></html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="extraBottom">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="contentBox">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="contentTopBg">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="leftBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="verticalFrame">
+ <layout class="QFormLayout" name="formLayout">
+ <property name="horizontalSpacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QFrame" name="menuBar">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,0">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="menu_file">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ <kerning>true</kerning>
+ </font>
+ </property>
+ <property name="mouseTracking">
+ <bool>true</bool>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>File</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="menu_edit">
+ <property name="text">
+ <string>Edit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="menu_run">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Run</string>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="titleRight">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>FlexSensor 6</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item alignment="Qt::AlignRight">
+ <widget class="QFrame" name="rightButtons">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>5</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="settingsTopBtn">
+ <property name="minimumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Settings</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources.qrc">
+ <normaloff>:/icons/images/icons/icon_settings.png</normaloff>:/icons/images/icons/icon_settings.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="minimizeAppBtn">
+ <property name="minimumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Minimize</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources.qrc">
+ <normaloff>:/icons/images/icons/icon_minimize.png</normaloff>:/icons/images/icons/icon_minimize.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="maximizeRestoreAppBtn">
+ <property name="minimumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ <stylestrategy>PreferDefault</stylestrategy>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Maximize</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources.qrc">
+ <normaloff>:/icons/images/icons/icon_maximize.png</normaloff>:/icons/images/icons/icon_maximize.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeAppBtn">
+ <property name="minimumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Close</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../resources.qrc">
+ <normaloff>:/icons/images/icons/icon_close.png</normaloff>:/icons/images/icons/icon_close.png</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="contentBottom">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="content">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="pagesContainer">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="rightMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="styleSheet">
+ <string notr="true">background: transparent;</string>
+ </property>
+ <property name="currentIndex">
+ <number>4</number>
+ </property>
+ <widget class="QWidget" name="home">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_7">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="home_layout"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="prober_control">
+ <layout class="QVBoxLayout" name="verticalLayout_20">
+ <item>
+ <layout class="QGridLayout" name="prober_control_layout">
+ <property name="leftMargin">
+ <number>1</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="adc_control">
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="adc_control_layout"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="laser_control">
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="laser_control_layout"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="measured_data">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="measured_data_layout"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="extraRightBox">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>0</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="themeSettingsTopDetail">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>3</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="contentSettings">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_13">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="txt_logs"/>
+ </item>
+ <item alignment="Qt::AlignTop">
+ <widget class="QFrame" name="topMenus">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btn_print">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>45</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>PointingHandCursor</cursorShape>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-image: url(:/icons/images/icons/cil-print.png);</string>
+ </property>
+ <property name="text">
+ <string>Print</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="bottomBar">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="creditsLabel">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>-1</pointsize>
+ <italic>false</italic>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Flexsensor 6</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="version">
+ <property name="text">
+ <string>v1.0.3</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame_size_grip">
+ <property name="minimumSize">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../../resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/MainWindow/resources/convert.sh b/src/FlexSensor/MainWindow/resources/convert.sh
new file mode 100644
index 0000000000000000000000000000000000000000..eb75364500a9ddc5fb07ab9e2990bc1c2251cb18
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/convert.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Convert .ui files to .py files
+for ui in *.ui; do
+ pyside6-uic $ui > ../view/${ui%.*}.py
+done
+ pyside6-rcc ../../resources.qrc -o ../../resources_rc.py
diff --git a/src/FlexSensor/MainWindow/resources/ui_palette.xml b/src/FlexSensor/MainWindow/resources/ui_palette.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8fafb2b667af4fd7f647bd0e9d84a005270aab0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/ui_palette.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette>
+ <active/>
+ <inactive/>
+ <disabled/>
+</palette>
diff --git a/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml b/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8fafb2b667af4fd7f647bd0e9d84a005270aab0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette>
+ <active/>
+ <inactive/>
+ <disabled/>
+</palette>
diff --git a/src/FlexSensor/MainWindow/view/BaseWindow.py b/src/FlexSensor/MainWindow/view/BaseWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae6ca6e885ac46bf3737ce528c4428ce196ace1a
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/BaseWindow.py
@@ -0,0 +1,282 @@
+from PySide6.QtCore import QPropertyAnimation, QEasingCurve, QParallelAnimationGroup
+from PySide6.QtGui import QColor, Qt, QIcon
+from PySide6.QtWidgets import QMainWindow, QGraphicsDropShadowEffect, QSizeGrip, QPushButton
+
+import __version__
+from ConfigHandler.controller.AppSettings import Settings
+from MainWindow.view.MainView import Ui_MainWindow
+from MainWindow.view.widgets.custom_grips import CustomGrip
+
+
+class BaseWindow(QMainWindow):
+
+ def __init__(self, ui_main_window: Ui_MainWindow):
+ super().__init__()
+ self.GLOBAL_STATE = False
+ self.GLOBAL_TITLE_BAR = True
+
+ self._ui = ui_main_window
+ self._ui.setupUi(self)
+ Settings.ENABLE_CUSTOM_TITLE_BAR = True
+
+ # APP NAME
+ # ///////////////////////////////////////////////////////////////
+ title = "FlexSensor 6 - A SiPh automation tool"
+ description = f"Flexsensor {__version__.__version__}"
+ # APPLY TEXTS
+ self.setWindowTitle(title)
+ self._ui.titleRight.setText(description)
+
+ if not Settings.ENABLE_CUSTOM_TITLE_BAR:
+ self._ui.appMargins.setContentsMargins(0, 0, 0, 0)
+ self._ui.minimizeAppBtn.hide()
+ self._ui.maximizeRestoreAppBtn.hide()
+ self._ui.closeAppBtn.hide()
+ self._ui.frame_size_grip.hide()
+
+ # DROP SHADOW
+ self.shadow = QGraphicsDropShadowEffect(self)
+ self.shadow.setBlurRadius(17)
+ self.shadow.setXOffset(0)
+ self.shadow.setYOffset(0)
+ self.shadow.setColor(QColor(0, 0, 0, 150))
+ self._ui.bgApp.setGraphicsEffect(self.shadow)
+
+ # RESIZE WINDOW
+ self.sizegrip = QSizeGrip(self._ui.frame_size_grip)
+ self.sizegrip.setStyleSheet("width: 20px; height: 20px; margin 0px; padding: 0px;")
+ # self.setStyleSheet("background-color: rgb(0, 0, 0);")
+
+ # MINIMIZE
+ self._ui.minimizeAppBtn.clicked.connect(lambda: self.showMinimized())
+
+ # MAXIMIZE/RESTORE
+ self._ui.maximizeRestoreAppBtn.clicked.connect(lambda: self.maximize_restore())
+
+ # CLOSE APPLICATION
+ self._ui.closeAppBtn.clicked.connect(lambda: self.close())
+
+ self.setWindowFlags(Qt.FramelessWindowHint)
+ self.setAttribute(Qt.WA_TranslucentBackground)
+
+ self.left_grip = CustomGrip(self, Qt.LeftEdge, True)
+ self.right_grip = CustomGrip(self, Qt.RightEdge, True)
+ self.top_grip = CustomGrip(self, Qt.TopEdge, True)
+ self.bottom_grip = CustomGrip(self, Qt.BottomEdge, True)
+ self.maximize_restore()
+ # self._ui.titleRightInfo.mouseMoveEvent = self.moveWindow
+
+ # def moveWindow(self, event):
+
+ def openCloseRightBox(self):
+ self.toggleRightBox(True)
+
+ def openCloseLeftBox(self):
+ self.toggleLeftBox(True)
+
+ def toggleLeftBox(self, enable):
+ if enable:
+ # GET WIDTH
+ width = self._ui.extraLeftBox.width()
+ widthRightBox = self._ui.extraRightBox.width()
+ maxExtend = Settings.LEFT_BOX_WIDTH
+ color = Settings.BTN_LEFT_BOX_COLOR
+ standard = 0
+
+ # GET BTN STYLE
+ style = self._ui.toggleLeftBox.styleSheet()
+
+ # SET MAX WIDTH
+ if width == 0:
+ widthExtended = maxExtend
+ # SELECT BTN
+ self._ui.toggleLeftBox.setStyleSheet(style + color)
+ if widthRightBox != 0:
+ style = self._ui.settingsTopBtn.styleSheet()
+ self._ui.settingsTopBtn.setStyleSheet(style.replace(Settings.BTN_RIGHT_BOX_COLOR, ''))
+ else:
+ widthExtended = standard
+ # RESET BTN
+ self._ui.toggleLeftBox.setStyleSheet(style.replace(color, ''))
+
+ self.start_box_animation(width, widthRightBox, "left")
+
+ # UI initialization
+ # TOGGLE RIGHT BOX
+ # # ///////////////////////////////////////////////////////////////
+ def toggleRightBox(self, enable):
+ if enable:
+ # GET WIDTH
+ width = self._ui.extraRightBox.width()
+ widthLeftBox = self._ui.extraLeftBox.width()
+ maxExtend = Settings.RIGHT_BOX_WIDTH
+ color = Settings.BTN_RIGHT_BOX_COLOR
+ standard = 0
+
+ # GET BTN STYLE
+ style = self._ui.settingsTopBtn.styleSheet()
+
+ # SET MAX WIDTH
+ if width == 0:
+ widthExtended = maxExtend
+ # SELECT BTN
+ self._ui.settingsTopBtn.setStyleSheet(style + color)
+ if widthLeftBox != 0:
+ style = self._ui.toggleLeftBox.styleSheet()
+ self._ui.toggleLeftBox.setStyleSheet(style.replace(Settings.BTN_LEFT_BOX_COLOR, ''))
+ else:
+ widthExtended = standard
+ # RESET BTN
+ self._ui.settingsTopBtn.setStyleSheet(style.replace(color, ''))
+
+ self.start_box_animation(widthLeftBox, width, "right")
+
+ # TOGGLE MENU
+ # ///////////////////////////////////////////////////////////////
+ def toggleMenu(self, enable):
+ if enable:
+ # GET WIDTH
+ width = self._ui.leftMenuBg.width()
+ maxExtend = Settings.MENU_WIDTH
+ standard = 60
+
+ # SET MAX WIDTH
+ if width == 60:
+ widthExtended = maxExtend
+ else:
+ widthExtended = standard
+
+ # ANIMATION
+ self.animation = QPropertyAnimation(self._ui.leftMenuBg, b"minimumWidth")
+ self.animation.setDuration(Settings.TIME_ANIMATION)
+ self.animation.setStartValue(width)
+ self.animation.setEndValue(widthExtended)
+ self.animation.setEasingCurve(QEasingCurve.InOutQuart)
+ self.animation.start()
+
+ def start_box_animation(self, left_box_width, right_box_width, direction):
+ right_width = 0
+ left_width = 0
+
+ # Check values
+ if left_box_width == 0 and direction == "left":
+ left_width = 240
+ else:
+ left_width = 0
+ # Check values
+ if right_box_width == 0 and direction == "right":
+ right_width = 240
+ else:
+ right_width = 0
+
+ # ANIMATION LEFT BOX
+ self.left_box = QPropertyAnimation(self._ui.extraLeftBox, b"minimumWidth")
+ self.left_box.setDuration(Settings.TIME_ANIMATION)
+ self.left_box.setStartValue(left_box_width)
+ self.left_box.setEndValue(left_width)
+ self.left_box.setEasingCurve(QEasingCurve.InOutQuart)
+
+ # ANIMATION RIGHT BOX
+ self.right_box = QPropertyAnimation(self._ui.extraRightBox, b"minimumWidth")
+ self.right_box.setDuration(Settings.TIME_ANIMATION)
+ self.right_box.setStartValue(right_box_width)
+ self.right_box.setEndValue(right_width)
+ self.right_box.setEasingCurve(QEasingCurve.InOutQuart)
+
+ # GROUP ANIMATION
+ self.group = QParallelAnimationGroup()
+ self.group.addAnimation(self.left_box)
+ self.group.addAnimation(self.right_box)
+ self.group.start()
+
+ def selectMenu(self, getStyle):
+ select = getStyle + Settings.MENU_SELECTED_STYLESHEET
+ return select
+
+ def deselectMenu(self, getStyle):
+ deselect = getStyle.replace(Settings.MENU_SELECTED_STYLESHEET, "")
+ return deselect
+
+ # START SELECTION
+ def selectStandardMenu(self, widget):
+ for w in self._ui.topMenu.findChildren(QPushButton):
+ if w.objectName() == widget:
+ w.setStyleSheet(self.selectMenu(w.styleSheet()))
+
+ # RESET SELECTION
+ def resetStyle(self, widget):
+ for w in self._ui.topMenu.findChildren(QPushButton):
+ if w.objectName() != widget:
+ w.setStyleSheet(self.deselectMenu(w.styleSheet()))
+
+ def resize_grips(self):
+ if Settings.ENABLE_CUSTOM_TITLE_BAR:
+ self.left_grip.setGeometry(0, 10, 10, self.height())
+ self.right_grip.setGeometry(self.width() - 10, 10, 10, self.height())
+ self.top_grip.setGeometry(0, 0, self.width(), 10)
+ self.bottom_grip.setGeometry(0, self.height() - 10, self.width(), 10)
+
+ def resizeEvent(self, event):
+ # Update Size Grips
+ self.resize_grips()
+
+ # MOUSE CLICK EVENTS
+ # ///////////////////////////////////////////////////////////////
+ def mousePressEvent(self, event):
+ # SET DRAG POS WINDOW
+ self.dragPos = event.globalPos()
+
+ # PRINT MOUSE EVENTS
+ #if event.buttons() == Qt.LeftButton:
+ # print(f'Mouse click: LEFT CLICK {self.dragPos}')
+ #if event.buttons() == Qt.RightButton:
+ # print('Mouse click: RIGHT CLICK')
+
+ def mouseMoveEvent(self, event) -> None:
+ # IF MAXIMIZED CHANGE TO NORMAL
+
+ if self.returStatus():
+ self.maximize_restore()
+ # MOVE WINDOW
+ if event.buttons() == Qt.LeftButton:
+ self.move(self.pos() + event.globalPos() - self.dragPos)
+ print(f"Mouse move: {event.pos()} - {self.pos()}")
+ self.dragPos = event.globalPos()
+ # event.accept()
+ # self.update()
+
+ def maximize_restore(self):
+ status = self.GLOBAL_STATE
+ if status == False:
+ self.showMaximized()
+ GLOBAL_STATE = True
+ self._ui.appMargins.setContentsMargins(0, 0, 0, 0)
+ self._ui.maximizeRestoreAppBtn.setToolTip("Restore")
+ self._ui.maximizeRestoreAppBtn.setIcon(QIcon(u":/icons/images/icons/icon_restore.png"))
+ self._ui.frame_size_grip.hide()
+ self.left_grip.hide()
+ self.right_grip.hide()
+ self.top_grip.hide()
+ self.bottom_grip.hide()
+ else:
+ GLOBAL_STATE = False
+ self.showNormal()
+ self.resize(self.width() + 1, self.height() + 1)
+ self._ui.appMargins.setContentsMargins(10, 10, 10, 10)
+ self._ui.maximizeRestoreAppBtn.setToolTip("Maximize")
+ self._ui.maximizeRestoreAppBtn.setIcon(QIcon(u":/icons/images/icons/icon_maximize.png"))
+ self._ui.frame_size_grip.show()
+ self.left_grip.show()
+ self.right_grip.show()
+ self.top_grip.show()
+ self.bottom_grip.show()
+
+ # RETURN STATUS
+ # ///////////////////////////////////////////////////////////////
+ def returStatus(self):
+ return self.GLOBAL_STATE
+
+ # SET STATUS
+ # ///////////////////////////////////////////////////////////////
+ def setStatus(self, status):
+ self.GLOBAL_STATE = status
diff --git a/src/FlexSensor/MainWindow/view/MainThreadView.py b/src/FlexSensor/MainWindow/view/MainThreadView.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a852bd475396d4f41c11fdb31f0671aea227472
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/MainThreadView.py
@@ -0,0 +1,396 @@
+import logging
+import sys
+import traceback
+
+from PySide6.QtWidgets import (
+ QMessageBox, QGridLayout, QGroupBox, QStatusBar, QPushButton, QTabWidget, QToolButton, QDockWidget, )
+from PySide6.QtCore import QThread
+
+from PySide6.QtGui import QIcon, QAction
+
+import pyqtgraph as pg
+from pyqtgraph.dockarea import *
+
+import __version__
+from ConfigHandler.controller.VASInputFileParser import VASInputFileParser
+from MainWindow.view.BaseWindow import BaseWindow
+from MainWindow.view.widgets.HomeStatusWidget import HomeStatusWidget
+from MainWindow.view.widgets.ScopeWidget import ScopeWidget
+
+from MainWindow.view.MainView import Ui_MainWindow
+
+from MainWindow.controller.MainThreadController import MainThreadController
+from MainWindow.model.MainThreadModel import MainThreadModel
+from MainWindow.view.StepThroughView import StepThroughView
+from InitialSetupWizard.InitialSetupWizard import InitialSetupWizard
+from MainWindow.view.widgets.WidgetSettingsFilesFolders import (WidgetSettingsOutFilesFolders,
+ WidgetLaserSettings, WidgetSettingsInFilesFolders,
+ WidgetAD2Settings)
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluationTool.view.widgets.MenuBarDefinition import MenuBarDefinition
+from constants.qs_style_sheets import CSSPlayPushButton
+
+#
+from pathes import image_root
+import ConfigHandler as Config
+
+
+class MainWindow(BaseWindow):
+
+ def __init__(self, model: MainThreadModel, controller: MainThreadController):
+ super().__init__(Ui_MainWindow())
+ self.logger = logging.getLogger("MainThread (UI)")
+
+ self._model: MainThreadModel = model
+ self._controller: MainThreadController = controller
+
+ # Signals for finished acquisition
+ self.model.measurement_routine.signals.routine_iteration_finished.connect(
+ self.on_routine_iteration_finished)
+
+ self._ui.settingsTopBtn.clicked.connect(self.openCloseRightBox)
+ self._ui.toggleButton.clicked.connect(lambda: self.toggleMenu(True))
+ self._ui.btn_start_measuring_routine.clicked.connect(self._on_btn_run_clicked)
+
+ self.init_UI()
+
+ # SET HOME PAGE AND SELECT MENU
+ # ///////////////////////////////////////////////////////////////
+ self._ui.stackedWidget.setCurrentWidget(self._ui.home)
+ self._ui.btn_home.setStyleSheet(self.selectMenu(self._ui.btn_home.styleSheet()))
+
+ @property
+ def model(self) -> MainThreadModel:
+ return self._model
+
+ @property
+ def controller(self) -> MainThreadController:
+ return self._controller
+
+ # ==================================================================================================================
+ # UI initialization methods
+ # ==================================================================================================================
+ def init_UI(self):
+ self.logger.debug("Initializing UI of MainWindow.")
+ self.grid_layout_main = QGridLayout()
+ self.init_UI_status_bar()
+ self.menu_bar = MenuBarDefinition(self)
+
+ # Add the prober control
+ self._ui.prober_control_layout.addWidget(self.model.prober_window)
+ self._ui.btn_probe_control.clicked.connect(self._on_btn_prober_control_clicked)
+
+ # Add the ADC control
+ dock_ad2 = QDockWidget("AD2 Control", self)
+ dock_ad2.setWidget(self.model.ad2_window)
+ self._ui.adc_control_layout.addWidget(dock_ad2, 0,0)
+ self._ui.btn_adc_control.clicked.connect(self._on_btn_adc_control_clicked)
+
+ dock_laser = QDockWidget("Laser Control", self)
+ dock_laser.setWidget(self.model.laser_window)
+ self._ui.adc_control_layout.addWidget(dock_laser,0,1)
+ self._ui.btn_laser_control.clicked.connect(self._on_btn_laser_control_clicked)
+
+ # add the measurement evaluation tool
+ self._ui.measured_data_layout.addWidget(self.model.mea_eval_tool_window)
+ self._ui.btn_measured_data.clicked.connect(self._on_btn_measurement_evaluation_clicked)
+
+
+ self._ui.home_layout.addWidget(HomeStatusWidget(self), 0, 0, 1, 2)
+ self._ui.home_layout.addWidget(self.init_UI_measurement_settings(), 1, 0)
+ self._ui.home_layout.addWidget(ScopeWidget(self), 1, 1)
+ # self._ui.grid_layout_main.addWidget(self.init_UI_device_control(), 1, 1, 2, 1)
+
+ self._ui.home_layout.addWidget(self.init_UI_buttons(), 2, 0, 1, 2)
+ self._ui.btn_home.clicked.connect(self._on_btn_home_clicked)
+
+ # self.setGeometry(100, 100, 1250, 150)
+ self.setWindowTitle(f'FlexSensor Automator {__version__.__version__}')
+ self.setWindowIcon(QIcon('../images/FlexSensorIcon.png'))
+
+ # self.init_menu_run()
+
+ # widget = QWidget()
+ # widget.setLayout(layout)
+ # self.setCentralWidget(widget)
+ self._ui.closeAppBtn.clicked.connect(lambda: exit())
+
+
+ # def closeEvent(self, *args, **kwargs):
+ # # self.prober_worker.stop()
+ # # self.threadpool.waitForDone()
+ # self.thread.quit()
+ # self.logger.warning(f"Exiting {args}")
+ # sys.exit(1)
+
+ def init_UI_status_bar(self):
+ # global status_bar
+
+ self.status_bar = QStatusBar()
+ self.setStatusBar(self.status_bar)
+
+ def init_UI_measurement_settings(self):
+ tabwidget = QTabWidget()
+ self.configView = Config.View(self.model.vaut_config)
+ tab_input = tabwidget.addTab(WidgetSettingsInFilesFolders(self.model.vaut_config), "Input")
+ tab_folders = tabwidget.addTab(WidgetSettingsOutFilesFolders(self.model.vaut_config), "Folder Settings")
+ tab_ad2 = tabwidget.addTab(WidgetAD2Settings(self.model.vaut_config), "AD2 Settings")
+ tab_laser = tabwidget.addTab(WidgetLaserSettings(self.model.vaut_config), "Laser Settings")
+ tab_yaml = tabwidget.addTab(self.configView, "YAML Config")
+ tabwidget.currentChanged.connect(
+ lambda idx: self.configView.repopulate(self.model.vaut_config) if idx == tab_yaml else print("fg")
+ )
+ return tabwidget
+
+ # def init_UI_device_control(self):
+ # tabwidget = QTabWidget()
+ # # tab_scope = tabwidget.addTab(self.init_scope_meter(), "Scope")
+ # # tab_laser = tabwidget.addTab(self._controller.laser_window, "Laser Control")
+ # # tab_ad2dev = tabwidget.addTab(self._controller.ad2_window, "AD2 Control")
+ # # tab_prober = tabwidget.addTab(self._controller.prober_window, "Prober Control")
+ #
+ # return tabwidget
+
+ def init_scope_meter(self):
+ area = DockArea()
+
+ d1 = Dock("Analog Discovery 2")
+ d2 = Dock("Filtered")
+ area.addDock(d1, 'bottom')
+ area.addDock(d2, 'bottom', d1)
+
+ self.scope_original = pg.PlotWidget(title="AD2 Acquisition")
+ # self.scope_original.plot(np.random.normal(size=100)*1e12)
+ self.scope_original.plotItem.showGrid(x=True, y=True, alpha=1)
+ d1.addWidget(self.scope_original)
+
+ self.scope_filtered = pg.PlotWidget(title="Filtered Data")
+ # self.scope_filtered.plot(np.random.normal(size=100))
+ self.scope_filtered.plotItem.showGrid(x=True, y=True, alpha=1)
+ d2.addWidget(self.scope_filtered)
+
+ # self.scope = pg.PlotWidget()
+ # self.scope.plot([1, 2])
+
+ return area
+
+ def init_UI_buttons(self):
+ grid_group_box = QGroupBox()
+ layout = QGridLayout()
+
+ self.btn_run = QPushButton(parent=self, text="Run")
+ self.btn_run.clicked.connect(self._on_btn_run_clicked)
+ layout.addWidget(self.btn_run, 0, 0)
+
+ self.btn_stop = QPushButton(parent=self, text="Stop")
+ # self.btn_stop.clicked.connect(self.on_btn_stop_clicked)
+ layout.addWidget(self.btn_stop, 0, 1)
+
+ self.btn_exit = QPushButton(parent=self, text="Exit")
+ # self.btn_exit.clicked.connect(self.on_btn_exit_clicked)
+ layout.addWidget(self.btn_exit, 0, 2)
+
+ grid_group_box.setLayout(layout)
+
+ return grid_group_box
+
+ # def init_menu_file(self):
+ # exit_action = QAction(QIcon('exit.png'), '&Exit ', self)
+ # exit_action.setShortcut('Ctrl+Q')
+ # exit_action.setStatusTip('Exit application')
+ # exit_action.triggered.connect(self.close)
+ # self._ui.menu_file.addAction(exit_action)
+ #
+ # def init_menu_edit(self):
+ # pass
+ #
+ # def init_menu_run(self):
+ # # self.menu_run = self.menubar.addMenu("Run")
+ # self.open_step_trough = QAction('Open &Step Through Window', self)
+ # self.open_step_trough.setShortcut('Ctrl+W')
+ # self.open_step_trough.setStatusTip('Open Step Through Window')
+ # self.open_step_trough.triggered.connect(self.on_open_step_through)
+ # self._ui.menu_run.addAction(self.open_step_trough)
+ #
+ # self.open_train_home_wizard = QAction('&Initial Setup Wizard', self)
+ # self.open_train_home_wizard.setShortcut('Ctrl+I')
+ # self.open_train_home_wizard.setStatusTip('Open Initial Setup Wizard')
+ # self.open_train_home_wizard.setIcon(QIcon(f"{image_root}/icons/setup_wizard.png"))
+ # self.open_train_home_wizard.triggered.connect(self.on_open_initial_setup_wizard)
+ # self._ui.menu_run.addAction(self.open_train_home_wizard)
+ #
+ #
+ # def init_UI_menu_bar(self):
+ # # self.menubar = self.menuBar()
+ # self.init_menu_file()
+ # self.init_menu_edit()
+ # self.init_menu_run()
+ # # help_menu = menubar.addMenu("Help")
+ # # help_menu.addAction("About", self.on_about_clicked)
+
+ # ==================================================================================================================
+ # Signal handlers
+ # ==================================================================================================================
+ def _on_open_step_through(self):
+ file_parser = VASInputFileParser()
+ grouped_structures, _ = file_parser.read_file(
+ input_file=self.model.vaut_config.wafer_config.get_structure_file().absolute
+ )
+ self.step_through_view = StepThroughView(grouped_structures)
+ self.step_through_view.show()
+
+ def _on_open_initial_setup_wizard(self):
+ self.wizard = InitialSetupWizard(self.model.prober_controller)
+ self.wizard.show()
+
+ def _on_btn_laser_control_clicked(self):
+ self.resetStyle(self.sender().objectName())
+ self._ui.stackedWidget.setCurrentWidget(self._ui.laser_control)
+ self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+ def _on_btn_adc_control_clicked(self):
+ self.resetStyle(self.sender().objectName())
+ self._ui.stackedWidget.setCurrentWidget(self._ui.adc_control)
+ self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+ def _on_btn_prober_control_clicked(self):
+ self.resetStyle(self.sender().objectName())
+ self._ui.stackedWidget.setCurrentWidget(self._ui.prober_control)
+ self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+ def _on_btn_home_clicked(self):
+ self.resetStyle(self.sender().objectName())
+ self._ui.stackedWidget.setCurrentWidget(self._ui.home)
+ self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+ def _on_btn_measurement_evaluation_clicked(self):
+ self.resetStyle(self.sender().objectName())
+ self._ui.stackedWidget.setCurrentWidget(self._ui.measured_data)
+ self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+ def _on_btn_run_clicked(self):
+ self._ui.btn_start_measuring_routine.setStyleSheet(CSSPlayPushButton.style_pause())
+ self._controller.start_measurement_routine()
+
+ # ------------------------------------------------------------------------------------------------------------------
+ # not used (yet)
+ def on_wafer_version_changed(self, value):
+ pass
+ # # Set the object property
+ # self.vaut_config.set_wafer_version(value)
+ # # Update all textfields
+ # self.on_tb_log_file_text_changed(self.tb_log_file.text())
+ # self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+ # self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+ # self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+ # self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+ # self.tb_working_directory.setText(self.vaut_config.output_directory.rel)
+
+ def on_wafer_nr_changed(self, value):
+ pass
+ # # Set the object property
+ # self.vaut_config.set_wafer_nr(value)
+ # # Update all textfields
+ # self.on_tb_log_file_text_changed(self.tb_log_file.text())
+ # self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+ # self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+ # self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+ # self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+ # self.tb_working_directory.setText(self.vaut_config.output_directory.rel)
+
+ def on_routine_iteration_finished(self, cur_measured_signal: SingleMeasuredData = None):
+ pass
+ # if not isinstance(cur_measured_signal, SingleMeasuredData):
+ # self.logger.error(
+ # f"Prober did not return any valid measured signal: measured_signal was {type(cur_measured_signal)}")
+ # self.on_error_emitted((ValueError,
+ # f"Prober did not return any valid measured signal: measured_signal was {type(cur_measured_signal)}",
+ # traceback.format_exc()))
+ # # raise ValueError(f"Prober did not return any valid measured signal: measured_signal was {type(measured_signal)}")
+
+ # self.logger.info(
+ # f"Acquisition finished for structure {cur_measured_signal.wafer_properties.structure_name} (die: {cur_measured_signal.wafer_properties.die_number}).")
+ # try:
+ # if len(cur_measured_signal._filtered_amplitude['amplitude']) > 0:
+ # self.scope_original.clear()
+ # self.scope_original.plot(cur_measured_signal.measured_data['measurements'], pen=pg.mkPen(width=1))
+ # else:
+ # self.logger.warning("Nothing to plot!")
+ # except Exception as e:
+ # self.logger.error(f"Error plotting scope: {e}")
+ # self.on_error_emitted((type(e), f"Error plotting scope: {e}", traceback.format_exc()))
+
+ def on_error(self, error_message):
+ self.logger.error(error_message)
+ self.status_bar.showMessage(error_message)
+ self.status_bar.setStyleSheet("color: red")
+
+ def on_writeout_emitted(self, msg_type, message):
+
+ if msg_type == "debug":
+ self.status_bar.setStyleSheet('border: 0; color: blue;')
+ elif msg_type == "warning":
+ self.status_bar.setStyleSheet('border: 0; color: orange;')
+ elif msg_type == "error":
+ self.status_bar.setStyleSheet('border: 0; color: red;')
+ elif msg_type == "fatal":
+ self.status_bar.setStyleSheet('border: 0; color: red;')
+ else:
+ self.status_bar.setStyleSheet('border: 0; color: black;')
+ self.status_bar.showMessage(message)
+
+ def on_report_info_emitted(self, version_info):
+ self.lbl_die_no.setText("<b>" + str(version_info["die_no"]) + "</b>")
+ self.lbl_structure.setText("<b>" + str(version_info["structure"]) + "</b>")
+ self.lbl_die_col.setText("<b>" + str(version_info["chuck_col"]) + "</b>")
+ self.lbl_die_row.setText("<b>" + str(version_info["chuck_row"]) + "</b>")
+
+ def on_report_progress(self, progress):
+ self.progress.setValue(progress)
+
+ def on_structure_select(self):
+ pass
+ # self.test_win.show()
+
+ def on_error_emitted(self, value):
+ title, text, details = value
+ try:
+ self.error_dialog: QMessageBox
+ # self.error_dialog.close()
+ except Exception as e:
+ print(f"Can't close error_dialog: {e}")
+ # Show a error dialog
+ self.error_dialog = QMessageBox()
+ self.error_dialog.setText(str(text))
+ # set detailed text
+ self.error_dialog.setDetailedText(str(details))
+ self.error_dialog.setIcon(QMessageBox.Critical)
+ self.error_dialog.setWindowTitle(f"Measurmenent Routine Error: {title}")
+ self.error_dialog.exec_()
+
+ def on_warning_emitted(self, value):
+ try:
+ self.warning_dialog: QMessageBox
+ self.warning_dialog.close()
+ except Exception as e:
+ print(f"Can't close warning_dialog: {e}")
+
+ # Show a warning dialog
+ self.warning_dialog = QMessageBox()
+ self.warning_dialog.setText(str(value[1]))
+ # set detailed text
+ self.warning_dialog.setDetailedText(str(value[2]))
+ self.warning_dialog.setIcon(QMessageBox.Warning)
+ self.warning_dialog.setWindowTitle(f"Prober Task Warning: {value[0]}")
+ self.warning_dialog.exec_()
+
+ def closeEvent(self, event):
+ # do stuff
+ self.model.ad2_controller.stop_process()
+ self.model.laser_controller.stop_process()
+ event.accept() # let the window close
+
+
+ def __del__(self):
+ self.logger.info("Exiting")
+ quit()
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/view/MainView.py b/src/FlexSensor/MainWindow/view/MainView.py
new file mode 100644
index 0000000000000000000000000000000000000000..e875299a596dcae7c9d3d00b7770fc0234450d2d
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/MainView.py
@@ -0,0 +1,1587 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'MainViewWUffIj.ui'
+##
+## Created by: Qt User Interface Compiler version 6.2.3
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QFormLayout, QFrame, QGridLayout,
+ QHBoxLayout, QLabel, QLayout, QMainWindow,
+ QPushButton, QSizePolicy, QStackedWidget, QTextEdit,
+ QToolButton, QVBoxLayout, QWidget)
+import resources_rc
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(1085, 753)
+ MainWindow.setMinimumSize(QSize(940, 560))
+ MainWindow.setToolTipDuration(-9)
+ self.styleSheet = QWidget(MainWindow)
+ self.styleSheet.setObjectName(u"styleSheet")
+ self.styleSheet.setMaximumSize(QSize(16777214, 16777215))
+ self.styleSheet.setToolTipDuration(0)
+ self.styleSheet.setStyleSheet(u"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"\n"
+"SET APP STYLESHEET - FULL STYLES HERE\n"
+"DARK THEME - DRACULA COLOR BASED\n"
+"\n"
+"///////////////////////////////////////////////////////////////////////////////////////////////// */\n"
+"\n"
+"QWidget{\n"
+" color: rgb(221, 221, 221);\n"
+" font: 10pt \"Segoe UI\";\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Tooltip */\n"
+"QToolTip {\n"
+" color: #ffffff;\n"
+" background-color: rgba(33, 37, 43, 180);\n"
+" border: 1px solid rgb(44, 49, 58);\n"
+" background-image: none;\n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 2px solid rgb(255, 121, 198);\n"
+" text-align: left;\n"
+" padding-left: 8px;\n"
+" margin: 0px;\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Bg App */\n"
+"#bgApp { \n"
+" background"
+ "-color: rgb(40, 44, 52);\n"
+" border: 1px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Left Menu */\n"
+"#leftMenuBg { \n"
+" background-color: rgb(33, 37, 43);\n"
+"}\n"
+"#topLogo {\n"
+" background-color: rgb(33, 37, 43);\n"
+" border-image: url(:/images/images/images/FlexSensorIcon.png) 10 0 0 0 strech strech;\n"
+" background-position: centered;\n"
+" background-repeat: no-repeat;\n"
+"}\n"
+"#titleLeftApp { font: 63 12pt \"Segoe UI Semibold\"; }\n"
+"#titleLeftDescription { font: 8pt \"Segoe UI\"; color: rgb(189, 147, 249); }\n"
+"\n"
+"/* MENUS */\n"
+"\n"
+"\n"
+"\n"
+"#topMenu .QPushButton { \n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 22px solid transparent;\n"
+" background-color: transparent;\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+"}\n"
+"#topMenu .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#topMenu .QPushButton:p"
+ "ressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"#bottomMenu .QPushButton { \n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 20px solid transparent;\n"
+" background-color:transparent;\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+"}\n"
+"#bottomMenu .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#bottomMenu .QPushButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"#leftMenuFrame{\n"
+" border-top: 3px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* Toggle Button */\n"
+"#toggleButton {\n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 20px solid transparent;\n"
+" background-color: rgb(37, 41, 48);\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+" color: rgb(113, 126, 149);\n"
+"}\n"
+"#toggleButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#toggleButto"
+ "n:pressed {\n"
+" background-color: rgb(189, 147, 249);\n"
+"}\n"
+"\n"
+"/* Title Menu */\n"
+"/*#titleRightInfo { padding-left: 10px; }*/\n"
+"\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Extra Tab */\n"
+"#extraLeftBox { \n"
+" background-color: rgb(44, 49, 58);\n"
+"}\n"
+"#extraTopBg{ \n"
+" background-color: rgb(189, 147, 249)\n"
+"}\n"
+"\n"
+"/* Icon */\n"
+"#extraIcon {\n"
+" background-position: center;\n"
+" background-repeat: no-repeat;\n"
+" background-image: url(:/icons/images/icons/icon_settings.png);\n"
+"}\n"
+"\n"
+"/* Label */\n"
+"#extraLabel { color: rgb(255, 255, 255); }\n"
+"\n"
+"/* Btn Close */\n"
+"#extraCloseColumnBtn { background-color: rgba(255, 255, 255, 0); border: none; border-radius: 5px; }\n"
+"#extraCloseColumnBtn:hover { background-color: rgb(196, 161, 249); border-style: solid; border-radius: 4px; }\n"
+"#extraCloseColumnBtn:pressed { background-color: rgb(180, 141, 238); border-style: solid; border-radius: 4px; }\n"
+"\n"
+"/* Extr"
+ "a Content */\n"
+"#extraContent{\n"
+" border-top: 3px solid rgb(40, 44, 52);\n"
+"}\n"
+"\n"
+"/* Extra Top Menus */\n"
+"#extraTopMenu .QPushButton {\n"
+" /*background-position: left center;*/\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 22px solid transparent;\n"
+" background-color:transparent;\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+"}\n"
+"#extraTopMenu .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraTopMenu .QPushButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Content App */\n"
+"#contentTopBg{ \n"
+" background-color: rgb(33, 37, 43);\n"
+"}\n"
+"#contentBottom{\n"
+" border-top: 3px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* Top Buttons */\n"
+"#rightButtons .QPushButton { background-color: rgba(255, 255, 255, 0); border: none; border-radius: 5px; }\n"
+"#rightButtons .QPushBu"
+ "tton:hover { background-color: rgb(44, 49, 57); border-style: solid; border-radius: 4px; }\n"
+"#rightButtons .QPushButton:pressed { background-color: rgb(23, 26, 30); border-style: solid; border-radius: 4px; }\n"
+"\n"
+"/* Theme Settings */\n"
+"#extraRightBox { background-color: rgb(44, 49, 58); }\n"
+"#themeSettingsTopDetail { background-color: rgb(189, 147, 249); }\n"
+"\n"
+"/* Bottom Bar */\n"
+"#bottomBar { background-color: rgb(44, 49, 58); }\n"
+"#bottomBar QLabel { font-size: 11px; color: rgb(113, 126, 149); padding-left: 10px; padding-right: 10px; padding-bottom: 2px; }\n"
+"\n"
+"/* CONTENT SETTINGS */\n"
+"/* MENUS */\n"
+"#contentSettings .QPushButton { \n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 22px solid transparent;\n"
+" background-color:transparent;\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+"}\n"
+"#contentSettings .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#contentSettings .QPushButton:pressed { \n"
+""
+ " background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"QTableWidget */\n"
+"QTableWidget { \n"
+" background-color: transparent;\n"
+" padding: 10px;\n"
+" border-radius: 5px;\n"
+" gridline-color: rgb(44, 49, 58);\n"
+" border-bottom: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::item{\n"
+" border-color: rgb(44, 49, 60);\n"
+" padding-left: 5px;\n"
+" padding-right: 5px;\n"
+" gridline-color: rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::item:selected{\n"
+" background-color: rgb(189, 147, 249);\n"
+"}\n"
+"QHeaderView::section{\n"
+" background-color: rgb(33, 37, 43);\n"
+" max-width: 30px;\n"
+" border: 1px solid rgb(44, 49, 58);\n"
+" border-style: none;\n"
+" border-bottom: 1px solid rgb(44, 49, 60);\n"
+" border-right: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::horizontalHeader { \n"
+" background-color: rgb(33, 37, 43);\n"
+"}\n"
+"QHeaderView::section:horizontal\n"
+"{\n"
+" "
+ " border: 1px solid rgb(33, 37, 43);\n"
+" background-color: rgb(33, 37, 43);\n"
+" padding: 3px;\n"
+" border-top-left-radius: 7px;\n"
+" border-top-right-radius: 7px;\n"
+"}\n"
+"QHeaderView::section:vertical\n"
+"{\n"
+" border: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"LineEdit */\n"
+"QLineEdit {\n"
+" background-color: rgb(33, 37, 43);\n"
+" border-radius: 5px;\n"
+" border: 2px solid rgb(33, 37, 43);\n"
+" padding-left: 10px;\n"
+" selection-color: rgb(255, 255, 255);\n"
+" selection-background-color: rgb(255, 121, 198);\n"
+"}\n"
+"QLineEdit:hover {\n"
+" border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QLineEdit:focus {\n"
+" border: 2px solid rgb(91, 101, 124);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"PlainTextEdit */\n"
+"QPlainTextEdit {\n"
+" background-color: rgb(27, 29, 35);\n"
+" border-radius: 5px;\n"
+" padding: 10px;\n"
+" selection-"
+ "color: rgb(255, 255, 255);\n"
+" selection-background-color: rgb(255, 121, 198);\n"
+"}\n"
+"QPlainTextEdit QScrollBar:vertical {\n"
+" width: 8px;\n"
+" }\n"
+"QPlainTextEdit QScrollBar:horizontal {\n"
+" height: 8px;\n"
+" }\n"
+"QPlainTextEdit:hover {\n"
+" border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QPlainTextEdit:focus {\n"
+" border: 2px solid rgb(91, 101, 124);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"ScrollBars */\n"
+"QScrollBar:horizontal {\n"
+" border: none;\n"
+" background: rgb(52, 59, 72);\n"
+" height: 8px;\n"
+" margin: 0px 21px 0 21px;\n"
+" border-radius: 0px;\n"
+"}\n"
+"QScrollBar::handle:horizontal {\n"
+" background: rgb(189, 147, 249);\n"
+" min-width: 25px;\n"
+" border-radius: 4px\n"
+"}\n"
+"QScrollBar::add-line:horizontal {\n"
+" border: none;\n"
+" background: rgb(55, 63, 77);\n"
+" width: 20px;\n"
+" border-top-right-radius: 4px;\n"
+" border-bottom-right-radius: 4px;\n"
+" subcontrol-positi"
+ "on: right;\n"
+" subcontrol-origin: margin;\n"
+"}\n"
+"QScrollBar::sub-line:horizontal {\n"
+" border: none;\n"
+" background: rgb(55, 63, 77);\n"
+" width: 20px;\n"
+" border-top-left-radius: 4px;\n"
+" border-bottom-left-radius: 4px;\n"
+" subcontrol-position: left;\n"
+" subcontrol-origin: margin;\n"
+"}\n"
+"QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal\n"
+"{\n"
+" background: none;\n"
+"}\n"
+"QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal\n"
+"{\n"
+" background: none;\n"
+"}\n"
+" QScrollBar:vertical {\n"
+" border: none;\n"
+" background: rgb(52, 59, 72);\n"
+" width: 8px;\n"
+" margin: 21px 0 21px 0;\n"
+" border-radius: 0px;\n"
+" }\n"
+" QScrollBar::handle:vertical { \n"
+" background: rgb(189, 147, 249);\n"
+" min-height: 25px;\n"
+" border-radius: 4px\n"
+" }\n"
+" QScrollBar::add-line:vertical {\n"
+" border: none;\n"
+" background: rgb(55, 63, 77);\n"
+" height: 20px;\n"
+" border-bottom-left-radius: 4px;\n"
+" border-bottom-right-radius"
+ ": 4px;\n"
+" subcontrol-position: bottom;\n"
+" subcontrol-origin: margin;\n"
+" }\n"
+" QScrollBar::sub-line:vertical {\n"
+" border: none;\n"
+" background: rgb(55, 63, 77);\n"
+" height: 20px;\n"
+" border-top-left-radius: 4px;\n"
+" border-top-right-radius: 4px;\n"
+" subcontrol-position: top;\n"
+" subcontrol-origin: margin;\n"
+" }\n"
+" QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {\n"
+" background: none;\n"
+" }\n"
+"\n"
+" QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {\n"
+" background: none;\n"
+" }\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"CheckBox */\n"
+"QCheckBox::indicator {\n"
+" border: 3px solid rgb(52, 59, 72);\n"
+" width: 15px;\n"
+" height: 15px;\n"
+" border-radius: 10px;\n"
+" background: rgb(44, 49, 60);\n"
+"}\n"
+"QCheckBox::indicator:hover {\n"
+" border: 3px solid rgb(58, 66, 81);\n"
+"}\n"
+"QCheckBox::indicator:checked {\n"
+" background: 3px solid rgb(52, 59,"
+ " 72);\n"
+" border: 3px solid rgb(52, 59, 72); \n"
+" background-image: url(:/icons/images/icons/cil-check-alt.png);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"RadioButton */\n"
+"QRadioButton::indicator {\n"
+" border: 3px solid rgb(52, 59, 72);\n"
+" width: 15px;\n"
+" height: 15px;\n"
+" border-radius: 10px;\n"
+" background: rgb(44, 49, 60);\n"
+"}\n"
+"QRadioButton::indicator:hover {\n"
+" border: 3px solid rgb(58, 66, 81);\n"
+"}\n"
+"QRadioButton::indicator:checked {\n"
+" background: 3px solid rgb(94, 106, 130);\n"
+" border: 3px solid rgb(52, 59, 72); \n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"ComboBox */\n"
+"QComboBox{\n"
+" background-color: rgb(27, 29, 35);\n"
+" border-radius: 5px;\n"
+" border: 2px solid rgb(33, 37, 43);\n"
+" padding: 5px;\n"
+" padding-left: 10px;\n"
+"}\n"
+"QComboBox:hover{\n"
+" border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QComboBox:"
+ ":drop-down {\n"
+" subcontrol-origin: padding;\n"
+" subcontrol-position: top right;\n"
+" width: 25px; \n"
+" border-left-width: 3px;\n"
+" border-left-color: rgba(39, 44, 54, 150);\n"
+" border-left-style: solid;\n"
+" border-top-right-radius: 3px;\n"
+" border-bottom-right-radius: 3px; \n"
+" background-image: url(:/icons/images/icons/cil-arrow-bottom.png);\n"
+" background-position: center;\n"
+" background-repeat: no-reperat;\n"
+" }\n"
+"QComboBox QAbstractItemView {\n"
+" color: rgb(255, 121, 198); \n"
+" background-color: rgb(33, 37, 43);\n"
+" padding: 10px;\n"
+" selection-background-color: rgb(39, 44, 54);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Sliders */\n"
+"QSlider::groove:horizontal {\n"
+" border-radius: 5px;\n"
+" height: 10px;\n"
+" margin: 0px;\n"
+" background-color: rgb(52, 59, 72);\n"
+"}\n"
+"QSlider::groove:horizontal:hover {\n"
+" background-color: rgb(55, 62, 76);\n"
+"}\n"
+"QSlider::handle:horizontal {\n"
+" background-co"
+ "lor: rgb(189, 147, 249);\n"
+" border: none;\n"
+" height: 10px;\n"
+" width: 10px;\n"
+" margin: 0px;\n"
+" border-radius: 5px;\n"
+"}\n"
+"QSlider::handle:horizontal:hover {\n"
+" background-color: rgb(195, 155, 255);\n"
+"}\n"
+"QSlider::handle:horizontal:pressed {\n"
+" background-color: rgb(255, 121, 198);\n"
+"}\n"
+"\n"
+"QSlider::groove:vertical {\n"
+" border-radius: 5px;\n"
+" width: 10px;\n"
+" margin: 0px;\n"
+" background-color: rgb(52, 59, 72);\n"
+"}\n"
+"QSlider::groove:vertical:hover {\n"
+" background-color: rgb(55, 62, 76);\n"
+"}\n"
+"QSlider::handle:vertical {\n"
+" background-color: rgb(189, 147, 249);\n"
+" border: none;\n"
+" height: 10px;\n"
+" width: 10px;\n"
+" margin: 0px;\n"
+" border-radius: 5px;\n"
+"}\n"
+"QSlider::handle:vertical:hover {\n"
+" background-color: rgb(195, 155, 255);\n"
+"}\n"
+"QSlider::handle:vertical:pressed {\n"
+" background-color: rgb(255, 121, 198);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////"
+ "////////////////\n"
+"CommandLinkButton */\n"
+"QCommandLinkButton { \n"
+" color: rgb(255, 121, 198);\n"
+" border-radius: 5px;\n"
+" padding: 5px;\n"
+" color: rgb(255, 170, 255);\n"
+"}\n"
+"QCommandLinkButton:hover { \n"
+" color: rgb(255, 170, 255);\n"
+" background-color: rgb(44, 49, 60);\n"
+"}\n"
+"QCommandLinkButton:pressed { \n"
+" color: rgb(189, 147, 249);\n"
+" background-color: rgb(52, 58, 71);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Button */\n"
+"#pagesContainer QPushButton {\n"
+" border: 2px solid rgb(52, 59, 72);\n"
+" border-radius: 5px; \n"
+" background-color: rgb(52, 59, 72);\n"
+"}\n"
+"#pagesContainer QPushButton:hover {\n"
+" background-color: rgb(57, 65, 80);\n"
+" border: 2px solid rgb(61, 70, 86);\n"
+"}\n"
+"#pagesContainer QPushButton:pressed { \n"
+" background-color: rgb(35, 40, 49);\n"
+" border: 2px solid rgb(43, 50, 61);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"QToolButton { \n"
+"border-image:"
+ " url(:/img/btn_mid_0.png);\n"
+"text-align: center;\n"
+"}\n"
+"QToolButton::menu-indicator { image: none; }\n"
+"\n"
+"\n"
+"#menuBar .QPushButton { \n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" /*border-left: 22px solid transparent;*/\n"
+" /*text-align: center;*/\n"
+" padding-right: 10px;\n"
+"}\n"
+"#menuBar .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#menuBar .QPushButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"#menuBar .QToolButton {\n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" /*border-left: 22px solid transparent;*/\n"
+" /*text-align: center;*/\n"
+" padding-right: 10px;\n"
+"}\n"
+"#menuBar .QToolButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#menuBar .QToolButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"#extraMenuBar ."
+ "QToolButton {\n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" /*border-left: 22px solid transparent;*/\n"
+" /*text-align: center;*/\n"
+" padding-right: 10px;\n"
+"}\n"
+"#extraMenuBar .QToolButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraMenuBar .QToolButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"#extraMenuBar .QPushButton {\n"
+" /*background-position: left center;*/\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 22px solid transparent;\n"
+" text-align: center;\n"
+" /*padding-left: 44px;*/\n"
+"}\n"
+"#extraMenuBar .QPushButton:hover {\n"
+" background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraMenuBar .QPushButton:pressed { \n"
+" background-color: rgb(189, 147, 249);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"/* QMenu ------------------------------------------------------------------\n"
+"\n"
+"examples: https://doc.qt.io/"
+ "qt-5/stylesheet-examples.html#customizing-qmenu\n"
+"\n"
+"--------------------------------------------------------------------------- */\n"
+"QMenu {\n"
+" background-color: rgb(40, 44, 52);\n"
+" margin: 2px; /* some spacing around the menu */\n"
+"}\n"
+"\n"
+"QMenu::item {\n"
+" padding: 2px 25px 2px 20px;\n"
+" border: 1px solid transparent; /* reserve space for selection border */\n"
+"}\n"
+"\n"
+"QMenu::item:selected {\n"
+" border-color: darkblue;\n"
+" background: rgba(100, 100, 100, 150);\n"
+"}\n"
+"\n"
+"QMenu::icon:checked { /* appearance of a 'checked' icon */\n"
+" background: gray;\n"
+" border: 1px inset gray;\n"
+" position: absolute;\n"
+" top: 1px;\n"
+" right: 1px;\n"
+" bottom: 1px;\n"
+" left: 1px;\n"
+"}\n"
+"\n"
+"QMenu::separator {\n"
+" height: 2px;\n"
+" background: lightblue;\n"
+" margin-left: 10px;\n"
+" margin-right: 5px;\n"
+"}\n"
+"\n"
+"QMenu::indicator {\n"
+" width: 13px;\n"
+" height: 13px;\n"
+"}\n"
+"\n"
+"/*\n"
+"\n"
+"QMenu::indicator:non-exclusive:unch"
+ "ecked {\n"
+" image: url(:/images/checkbox_unchecked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:unchecked:selected {\n"
+" image: url(:/images/checkbox_unchecked_hover.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:checked {\n"
+" image: url(:/images/checkbox_checked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:checked:selected {\n"
+" image: url(:/images/checkbox_checked_hover.png);\n"
+"}\n"
+"\n"
+"\n"
+"QMenu::indicator:exclusive:unchecked {\n"
+" image: url(:/images/radiobutton_unchecked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:unchecked:selected {\n"
+" image: url(:/images/radiobutton_unchecked_hover.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:checked {\n"
+" image: url(:/images/radiobutton_checked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:checked:selected {\n"
+" image: url(:/images/radiobutton_checked_hover.png);\n"
+"}*/\n"
+"\n"
+"QTabWidget::pane {\n"
+" border: 1px solid lightgray;\n"
+" top:-1px; \n"
+" background: rgb(40, 44, 52); \n"
+"} \n"
+"\n"
+"Q"
+ "TabBar::tab {\n"
+" background: rgb(40, 44, 52);; \n"
+" border: 1px solid lightgray; \n"
+" padding: 2px;\n"
+" padding-left: 10px;\n"
+" padding-right: 10px;\n"
+"} \n"
+"\n"
+"QTabBar::tab:selected { \n"
+" background: rgb(189, 147, 249);\n"
+" margin-bottom: -1px; \n"
+"}")
+ self.appMargins = QVBoxLayout(self.styleSheet)
+ self.appMargins.setSpacing(0)
+ self.appMargins.setObjectName(u"appMargins")
+ self.appMargins.setContentsMargins(10, 10, 10, 10)
+ self.bgApp = QFrame(self.styleSheet)
+ self.bgApp.setObjectName(u"bgApp")
+ self.bgApp.setToolTipDuration(0)
+ self.bgApp.setStyleSheet(u"")
+ self.bgApp.setFrameShape(QFrame.NoFrame)
+ self.bgApp.setFrameShadow(QFrame.Plain)
+ self.appLayout = QHBoxLayout(self.bgApp)
+ self.appLayout.setSpacing(0)
+ self.appLayout.setObjectName(u"appLayout")
+ self.appLayout.setContentsMargins(0, 0, 0, 0)
+ self.leftMenuBg = QFrame(self.bgApp)
+ self.leftMenuBg.setObjectName(u"leftMenuBg")
+ self.leftMenuBg.setMinimumSize(QSize(60, 0))
+ self.leftMenuBg.setMaximumSize(QSize(60, 16777215))
+ self.leftMenuBg.setFrameShape(QFrame.NoFrame)
+ self.leftMenuBg.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_3 = QVBoxLayout(self.leftMenuBg)
+ self.verticalLayout_3.setSpacing(0)
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.topLogoInfo = QFrame(self.leftMenuBg)
+ self.topLogoInfo.setObjectName(u"topLogoInfo")
+ self.topLogoInfo.setMinimumSize(QSize(0, 50))
+ self.topLogoInfo.setMaximumSize(QSize(16777215, 50))
+ self.topLogoInfo.setFrameShape(QFrame.NoFrame)
+ self.topLogoInfo.setFrameShadow(QFrame.Raised)
+ self.titleLeftApp = QLabel(self.topLogoInfo)
+ self.titleLeftApp.setObjectName(u"titleLeftApp")
+ self.titleLeftApp.setGeometry(QRect(60, 3, 160, 20))
+ font = QFont()
+ font.setFamilies([u"Segoe UI Semibold"])
+ font.setPointSize(12)
+ font.setBold(False)
+ font.setItalic(False)
+ self.titleLeftApp.setFont(font)
+ self.titleLeftApp.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
+ self.topLogo = QFrame(self.topLogoInfo)
+ self.topLogo.setObjectName(u"topLogo")
+ self.topLogo.setGeometry(QRect(10, 4, 42, 42))
+ self.topLogo.setMinimumSize(QSize(42, 42))
+ self.topLogo.setMaximumSize(QSize(42, 42))
+ self.topLogo.setFrameShape(QFrame.NoFrame)
+ self.topLogo.setFrameShadow(QFrame.Raised)
+ self.titleLeftDescription = QLabel(self.topLogoInfo)
+ self.titleLeftDescription.setObjectName(u"titleLeftDescription")
+ self.titleLeftDescription.setGeometry(QRect(60, 22, 160, 16))
+ self.titleLeftDescription.setMaximumSize(QSize(16777215, 16))
+ font1 = QFont()
+ font1.setFamilies([u"Segoe UI"])
+ font1.setPointSize(8)
+ font1.setBold(False)
+ font1.setItalic(False)
+ self.titleLeftDescription.setFont(font1)
+ self.titleLeftDescription.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
+
+ self.verticalLayout_3.addWidget(self.topLogoInfo)
+
+ self.leftMenuFrame = QFrame(self.leftMenuBg)
+ self.leftMenuFrame.setObjectName(u"leftMenuFrame")
+ self.leftMenuFrame.setEnabled(True)
+ self.leftMenuFrame.setMinimumSize(QSize(0, 0))
+ self.leftMenuFrame.setMaximumSize(QSize(16777215, 16777215))
+ self.leftMenuFrame.setToolTipDuration(0)
+ self.leftMenuFrame.setLayoutDirection(Qt.LeftToRight)
+ self.leftMenuFrame.setFrameShape(QFrame.NoFrame)
+ self.leftMenuFrame.setFrameShadow(QFrame.Raised)
+ self.verticalMenuLayout = QVBoxLayout(self.leftMenuFrame)
+ self.verticalMenuLayout.setSpacing(0)
+ self.verticalMenuLayout.setObjectName(u"verticalMenuLayout")
+ self.verticalMenuLayout.setContentsMargins(0, 0, 0, 0)
+ self.toggleBox = QFrame(self.leftMenuFrame)
+ self.toggleBox.setObjectName(u"toggleBox")
+ self.toggleBox.setMaximumSize(QSize(16777215, 45))
+ self.toggleBox.setFrameShape(QFrame.NoFrame)
+ self.toggleBox.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_4 = QVBoxLayout(self.toggleBox)
+ self.verticalLayout_4.setSpacing(0)
+ self.verticalLayout_4.setObjectName(u"verticalLayout_4")
+ self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.toggleButton = QPushButton(self.toggleBox)
+ self.toggleButton.setObjectName(u"toggleButton")
+ sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.toggleButton.sizePolicy().hasHeightForWidth())
+ self.toggleButton.setSizePolicy(sizePolicy)
+ self.toggleButton.setMinimumSize(QSize(0, 45))
+ font2 = QFont()
+ font2.setFamilies([u"Segoe UI"])
+ font2.setPointSize(10)
+ font2.setBold(False)
+ font2.setItalic(False)
+ self.toggleButton.setFont(font2)
+ self.toggleButton.setCursor(QCursor(Qt.PointingHandCursor))
+ self.toggleButton.setLayoutDirection(Qt.LeftToRight)
+ self.toggleButton.setStyleSheet(u"background-image: url(:/icons/images/icons/icon_menu.png);")
+
+ self.verticalLayout_4.addWidget(self.toggleButton)
+
+
+ self.verticalMenuLayout.addWidget(self.toggleBox)
+
+ self.topMenu = QFrame(self.leftMenuFrame)
+ self.topMenu.setObjectName(u"topMenu")
+ self.topMenu.setMinimumSize(QSize(0, 10))
+ self.topMenu.setLayoutDirection(Qt.LeftToRight)
+ self.topMenu.setFrameShape(QFrame.NoFrame)
+ self.topMenu.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_8 = QVBoxLayout(self.topMenu)
+ self.verticalLayout_8.setSpacing(0)
+ self.verticalLayout_8.setObjectName(u"verticalLayout_8")
+ self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.btn_start_measuring_routine = QPushButton(self.topMenu)
+ self.btn_start_measuring_routine.setObjectName(u"btn_start_measuring_routine")
+ self.btn_start_measuring_routine.setMinimumSize(QSize(60, 60))
+ self.btn_start_measuring_routine.setMaximumSize(QSize(16660, 60))
+ self.btn_start_measuring_routine.setStyleSheet(u"QPushButton { \n"
+" background-position: left center;\n"
+" background-repeat: no-repeat;\n"
+" border: none;\n"
+" border-left: 22px solid transparent;\n"
+" background-color: rgb(36, 209, 21);\n"
+" text-align: left;\n"
+" padding-left: 44px;\n"
+" background-image: url(:/icons/images/icons/cil-media-play.png);\n"
+"}\n"
+"\n"
+"QPushButton:hover {\n"
+" background-color: rgb(26, 153, 16);\n"
+"}\n"
+"\n"
+"QPushButton:pressed { \n"
+" background-color: rgb(20, 120, 12);\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"")
+
+ self.verticalLayout_8.addWidget(self.btn_start_measuring_routine)
+
+ self.btn_home = QPushButton(self.topMenu)
+ self.btn_home.setObjectName(u"btn_home")
+ sizePolicy.setHeightForWidth(self.btn_home.sizePolicy().hasHeightForWidth())
+ self.btn_home.setSizePolicy(sizePolicy)
+ self.btn_home.setMinimumSize(QSize(0, 45))
+ self.btn_home.setMaximumSize(QSize(16777215, 16777215))
+ self.btn_home.setFont(font2)
+ self.btn_home.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_home.setLayoutDirection(Qt.LeftToRight)
+ self.btn_home.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-home.png);")
+
+ self.verticalLayout_8.addWidget(self.btn_home)
+
+ self.btn_adc_control = QPushButton(self.topMenu)
+ self.btn_adc_control.setObjectName(u"btn_adc_control")
+ sizePolicy.setHeightForWidth(self.btn_adc_control.sizePolicy().hasHeightForWidth())
+ self.btn_adc_control.setSizePolicy(sizePolicy)
+ self.btn_adc_control.setMinimumSize(QSize(0, 45))
+ self.btn_adc_control.setFont(font2)
+ self.btn_adc_control.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_adc_control.setLayoutDirection(Qt.LeftToRight)
+ self.btn_adc_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-signal-cellular-3.png);")
+ self.btn_adc_control.setIconSize(QSize(16, 16))
+
+ self.verticalLayout_8.addWidget(self.btn_adc_control)
+
+ self.btn_laser_control = QPushButton(self.topMenu)
+ self.btn_laser_control.setObjectName(u"btn_laser_control")
+ sizePolicy.setHeightForWidth(self.btn_laser_control.sizePolicy().hasHeightForWidth())
+ self.btn_laser_control.setSizePolicy(sizePolicy)
+ self.btn_laser_control.setMinimumSize(QSize(0, 45))
+ self.btn_laser_control.setFont(font2)
+ self.btn_laser_control.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_laser_control.setLayoutDirection(Qt.LeftToRight)
+ self.btn_laser_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-lightbulb.png);")
+
+ self.verticalLayout_8.addWidget(self.btn_laser_control)
+
+ self.btn_probe_control = QPushButton(self.topMenu)
+ self.btn_probe_control.setObjectName(u"btn_probe_control")
+ self.btn_probe_control.setEnabled(True)
+ sizePolicy.setHeightForWidth(self.btn_probe_control.sizePolicy().hasHeightForWidth())
+ self.btn_probe_control.setSizePolicy(sizePolicy)
+ self.btn_probe_control.setMinimumSize(QSize(0, 45))
+ self.btn_probe_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-action-redo.png);")
+
+ self.verticalLayout_8.addWidget(self.btn_probe_control)
+
+ self.btn_measured_data = QPushButton(self.topMenu)
+ self.btn_measured_data.setObjectName(u"btn_measured_data")
+ self.btn_measured_data.setMinimumSize(QSize(0, 45))
+ self.btn_measured_data.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-description.png);")
+
+ self.verticalLayout_8.addWidget(self.btn_measured_data)
+
+ self.btn_exit = QPushButton(self.topMenu)
+ self.btn_exit.setObjectName(u"btn_exit")
+ sizePolicy.setHeightForWidth(self.btn_exit.sizePolicy().hasHeightForWidth())
+ self.btn_exit.setSizePolicy(sizePolicy)
+ self.btn_exit.setMinimumSize(QSize(60, 45))
+ self.btn_exit.setFont(font2)
+ self.btn_exit.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_exit.setLayoutDirection(Qt.LeftToRight)
+ self.btn_exit.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-x.png);")
+
+ self.verticalLayout_8.addWidget(self.btn_exit)
+
+
+ self.verticalMenuLayout.addWidget(self.topMenu)
+
+ self.bottomMenu = QFrame(self.leftMenuFrame)
+ self.bottomMenu.setObjectName(u"bottomMenu")
+ self.bottomMenu.setFrameShape(QFrame.NoFrame)
+ self.bottomMenu.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_9 = QVBoxLayout(self.bottomMenu)
+ self.verticalLayout_9.setSpacing(0)
+ self.verticalLayout_9.setObjectName(u"verticalLayout_9")
+ self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
+ self.toggleLeftBox = QPushButton(self.bottomMenu)
+ self.toggleLeftBox.setObjectName(u"toggleLeftBox")
+ sizePolicy.setHeightForWidth(self.toggleLeftBox.sizePolicy().hasHeightForWidth())
+ self.toggleLeftBox.setSizePolicy(sizePolicy)
+ self.toggleLeftBox.setMinimumSize(QSize(0, 45))
+ self.toggleLeftBox.setFont(font2)
+ self.toggleLeftBox.setCursor(QCursor(Qt.PointingHandCursor))
+ self.toggleLeftBox.setLayoutDirection(Qt.LeftToRight)
+ self.toggleLeftBox.setStyleSheet(u"background-image: url(:/icons/images/icons/icon_settings.png);")
+
+ self.verticalLayout_9.addWidget(self.toggleLeftBox)
+
+
+ self.verticalMenuLayout.addWidget(self.bottomMenu)
+
+
+ self.verticalLayout_3.addWidget(self.leftMenuFrame)
+
+
+ self.appLayout.addWidget(self.leftMenuBg)
+
+ self.extraLeftBox = QFrame(self.bgApp)
+ self.extraLeftBox.setObjectName(u"extraLeftBox")
+ self.extraLeftBox.setMinimumSize(QSize(0, 0))
+ self.extraLeftBox.setMaximumSize(QSize(0, 16777215))
+ self.extraLeftBox.setFrameShape(QFrame.NoFrame)
+ self.extraLeftBox.setFrameShadow(QFrame.Raised)
+ self.extraLeftBox.setLineWidth(0)
+ self.extraColumLayout = QVBoxLayout(self.extraLeftBox)
+ self.extraColumLayout.setSpacing(0)
+ self.extraColumLayout.setObjectName(u"extraColumLayout")
+ self.extraColumLayout.setContentsMargins(0, 0, 0, 0)
+ self.extraTopBg = QFrame(self.extraLeftBox)
+ self.extraTopBg.setObjectName(u"extraTopBg")
+ self.extraTopBg.setMinimumSize(QSize(0, 50))
+ self.extraTopBg.setMaximumSize(QSize(16777215, 50))
+ self.extraTopBg.setFrameShape(QFrame.NoFrame)
+ self.extraTopBg.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_5 = QVBoxLayout(self.extraTopBg)
+ self.verticalLayout_5.setSpacing(0)
+ self.verticalLayout_5.setObjectName(u"verticalLayout_5")
+ self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.extraTopLayout = QGridLayout()
+ self.extraTopLayout.setObjectName(u"extraTopLayout")
+ self.extraTopLayout.setHorizontalSpacing(10)
+ self.extraTopLayout.setVerticalSpacing(0)
+ self.extraTopLayout.setContentsMargins(10, -1, 10, -1)
+ self.extraIcon = QFrame(self.extraTopBg)
+ self.extraIcon.setObjectName(u"extraIcon")
+ self.extraIcon.setMinimumSize(QSize(20, 0))
+ self.extraIcon.setMaximumSize(QSize(20, 20))
+ self.extraIcon.setFrameShape(QFrame.NoFrame)
+ self.extraIcon.setFrameShadow(QFrame.Raised)
+
+ self.extraTopLayout.addWidget(self.extraIcon, 0, 0, 1, 1)
+
+ self.extraLabel = QLabel(self.extraTopBg)
+ self.extraLabel.setObjectName(u"extraLabel")
+ self.extraLabel.setMinimumSize(QSize(150, 0))
+
+ self.extraTopLayout.addWidget(self.extraLabel, 0, 1, 1, 1)
+
+ self.extraCloseColumnBtn = QPushButton(self.extraTopBg)
+ self.extraCloseColumnBtn.setObjectName(u"extraCloseColumnBtn")
+ self.extraCloseColumnBtn.setMinimumSize(QSize(28, 28))
+ self.extraCloseColumnBtn.setMaximumSize(QSize(28, 28))
+ self.extraCloseColumnBtn.setCursor(QCursor(Qt.PointingHandCursor))
+ icon = QIcon()
+ icon.addFile(u":/icons/images/icons/icon_close.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.extraCloseColumnBtn.setIcon(icon)
+ self.extraCloseColumnBtn.setIconSize(QSize(20, 20))
+
+ self.extraTopLayout.addWidget(self.extraCloseColumnBtn, 0, 2, 1, 1)
+
+
+ self.verticalLayout_5.addLayout(self.extraTopLayout)
+
+
+ self.extraColumLayout.addWidget(self.extraTopBg)
+
+ self.extraContent = QFrame(self.extraLeftBox)
+ self.extraContent.setObjectName(u"extraContent")
+ self.extraContent.setFrameShape(QFrame.NoFrame)
+ self.extraContent.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_12 = QVBoxLayout(self.extraContent)
+ self.verticalLayout_12.setSpacing(0)
+ self.verticalLayout_12.setObjectName(u"verticalLayout_12")
+ self.verticalLayout_12.setContentsMargins(0, 0, 0, 0)
+ self.extraTopMenu = QFrame(self.extraContent)
+ self.extraTopMenu.setObjectName(u"extraTopMenu")
+ self.extraTopMenu.setFrameShape(QFrame.NoFrame)
+ self.extraTopMenu.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_11 = QVBoxLayout(self.extraTopMenu)
+ self.verticalLayout_11.setSpacing(0)
+ self.verticalLayout_11.setObjectName(u"verticalLayout_11")
+ self.verticalLayout_11.setContentsMargins(0, 0, 0, 0)
+ self.btn_share = QPushButton(self.extraTopMenu)
+ self.btn_share.setObjectName(u"btn_share")
+ sizePolicy.setHeightForWidth(self.btn_share.sizePolicy().hasHeightForWidth())
+ self.btn_share.setSizePolicy(sizePolicy)
+ self.btn_share.setMinimumSize(QSize(0, 45))
+ self.btn_share.setFont(font2)
+ self.btn_share.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_share.setLayoutDirection(Qt.LeftToRight)
+ self.btn_share.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-share-boxed.png);")
+
+ self.verticalLayout_11.addWidget(self.btn_share)
+
+ self.btn_adjustments = QPushButton(self.extraTopMenu)
+ self.btn_adjustments.setObjectName(u"btn_adjustments")
+ sizePolicy.setHeightForWidth(self.btn_adjustments.sizePolicy().hasHeightForWidth())
+ self.btn_adjustments.setSizePolicy(sizePolicy)
+ self.btn_adjustments.setMinimumSize(QSize(0, 45))
+ self.btn_adjustments.setFont(font2)
+ self.btn_adjustments.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_adjustments.setLayoutDirection(Qt.LeftToRight)
+ self.btn_adjustments.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-equalizer.png);")
+
+ self.verticalLayout_11.addWidget(self.btn_adjustments)
+
+ self.btn_more = QPushButton(self.extraTopMenu)
+ self.btn_more.setObjectName(u"btn_more")
+ sizePolicy.setHeightForWidth(self.btn_more.sizePolicy().hasHeightForWidth())
+ self.btn_more.setSizePolicy(sizePolicy)
+ self.btn_more.setMinimumSize(QSize(0, 45))
+ self.btn_more.setFont(font2)
+ self.btn_more.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_more.setLayoutDirection(Qt.LeftToRight)
+ self.btn_more.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-layers.png);")
+
+ self.verticalLayout_11.addWidget(self.btn_more)
+
+
+ self.verticalLayout_12.addWidget(self.extraTopMenu, 0, Qt.AlignTop)
+
+ self.extraCenter = QFrame(self.extraContent)
+ self.extraCenter.setObjectName(u"extraCenter")
+ self.extraCenter.setFrameShape(QFrame.NoFrame)
+ self.extraCenter.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_10 = QVBoxLayout(self.extraCenter)
+ self.verticalLayout_10.setObjectName(u"verticalLayout_10")
+ self.textEdit = QTextEdit(self.extraCenter)
+ self.textEdit.setObjectName(u"textEdit")
+ self.textEdit.setMinimumSize(QSize(222, 0))
+ self.textEdit.setStyleSheet(u"background: transparent;")
+ self.textEdit.setFrameShape(QFrame.NoFrame)
+ self.textEdit.setReadOnly(True)
+
+ self.verticalLayout_10.addWidget(self.textEdit)
+
+
+ self.verticalLayout_12.addWidget(self.extraCenter)
+
+ self.extraBottom = QFrame(self.extraContent)
+ self.extraBottom.setObjectName(u"extraBottom")
+ self.extraBottom.setFrameShape(QFrame.NoFrame)
+ self.extraBottom.setFrameShadow(QFrame.Raised)
+
+ self.verticalLayout_12.addWidget(self.extraBottom)
+
+
+ self.extraColumLayout.addWidget(self.extraContent)
+
+
+ self.appLayout.addWidget(self.extraLeftBox)
+
+ self.contentBox = QFrame(self.bgApp)
+ self.contentBox.setObjectName(u"contentBox")
+ self.contentBox.setFrameShape(QFrame.NoFrame)
+ self.contentBox.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_2 = QVBoxLayout(self.contentBox)
+ self.verticalLayout_2.setSpacing(0)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.contentTopBg = QFrame(self.contentBox)
+ self.contentTopBg.setObjectName(u"contentTopBg")
+ self.contentTopBg.setMinimumSize(QSize(0, 50))
+ self.contentTopBg.setMaximumSize(QSize(16777215, 50))
+ self.contentTopBg.setFrameShape(QFrame.NoFrame)
+ self.contentTopBg.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout = QHBoxLayout(self.contentTopBg)
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.horizontalLayout.setContentsMargins(0, 0, 10, 0)
+ self.leftBox = QFrame(self.contentTopBg)
+ self.leftBox.setObjectName(u"leftBox")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.leftBox.sizePolicy().hasHeightForWidth())
+ self.leftBox.setSizePolicy(sizePolicy1)
+ self.leftBox.setFocusPolicy(Qt.NoFocus)
+ self.leftBox.setFrameShape(QFrame.NoFrame)
+ self.leftBox.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout_3 = QHBoxLayout(self.leftBox)
+ self.horizontalLayout_3.setSpacing(0)
+ self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
+ self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalFrame = QFrame(self.leftBox)
+ self.verticalFrame.setObjectName(u"verticalFrame")
+ self.formLayout = QFormLayout(self.verticalFrame)
+ self.formLayout.setObjectName(u"formLayout")
+ self.formLayout.setHorizontalSpacing(0)
+ self.formLayout.setContentsMargins(0, 0, 0, 0)
+ self.menuBar = QFrame(self.verticalFrame)
+ self.menuBar.setObjectName(u"menuBar")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.menuBar.sizePolicy().hasHeightForWidth())
+ self.menuBar.setSizePolicy(sizePolicy2)
+ self.menuBar.setMinimumSize(QSize(0, 0))
+ self.menuBar.setFocusPolicy(Qt.NoFocus)
+ self.menuBar.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout_6 = QHBoxLayout(self.menuBar)
+ self.horizontalLayout_6.setSpacing(0)
+ self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
+ self.horizontalLayout_6.setSizeConstraint(QLayout.SetDefaultConstraint)
+ self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
+ self.menu_file = QToolButton(self.menuBar)
+ self.menu_file.setObjectName(u"menu_file")
+ self.menu_file.setEnabled(True)
+ sizePolicy3 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.menu_file.sizePolicy().hasHeightForWidth())
+ self.menu_file.setSizePolicy(sizePolicy3)
+ self.menu_file.setMinimumSize(QSize(0, 16))
+ self.menu_file.setMaximumSize(QSize(16777215, 16777215))
+ font3 = QFont()
+ font3.setFamilies([u"Segoe UI"])
+ font3.setPointSize(10)
+ font3.setBold(False)
+ font3.setItalic(False)
+ font3.setKerning(True)
+ self.menu_file.setFont(font3)
+ self.menu_file.setMouseTracking(True)
+ self.menu_file.setLayoutDirection(Qt.LeftToRight)
+ self.menu_file.setAutoFillBackground(False)
+ self.menu_file.setStyleSheet(u"")
+ self.menu_file.setCheckable(False)
+ self.menu_file.setPopupMode(QToolButton.InstantPopup)
+ self.menu_file.setToolButtonStyle(Qt.ToolButtonTextOnly)
+ self.menu_file.setAutoRaise(True)
+
+ self.horizontalLayout_6.addWidget(self.menu_file)
+
+ self.menu_edit = QToolButton(self.menuBar)
+ self.menu_edit.setObjectName(u"menu_edit")
+
+ self.horizontalLayout_6.addWidget(self.menu_edit)
+
+ self.menu_run = QToolButton(self.menuBar)
+ self.menu_run.setObjectName(u"menu_run")
+ self.menu_run.setMinimumSize(QSize(0, 0))
+ self.menu_run.setStyleSheet(u"")
+ self.menu_run.setPopupMode(QToolButton.InstantPopup)
+ self.menu_run.setToolButtonStyle(Qt.ToolButtonTextOnly)
+ self.menu_run.setAutoRaise(True)
+
+ self.horizontalLayout_6.addWidget(self.menu_run)
+
+
+ self.formLayout.setWidget(1, QFormLayout.LabelRole, self.menuBar)
+
+ self.titleRight = QLabel(self.verticalFrame)
+ self.titleRight.setObjectName(u"titleRight")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.titleRight.sizePolicy().hasHeightForWidth())
+ self.titleRight.setSizePolicy(sizePolicy4)
+ self.titleRight.setMaximumSize(QSize(16777215, 45))
+ self.titleRight.setFont(font2)
+ self.titleRight.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
+
+ self.formLayout.setWidget(0, QFormLayout.LabelRole, self.titleRight)
+
+
+ self.horizontalLayout_3.addWidget(self.verticalFrame)
+
+
+ self.horizontalLayout.addWidget(self.leftBox)
+
+ self.rightButtons = QFrame(self.contentTopBg)
+ self.rightButtons.setObjectName(u"rightButtons")
+ self.rightButtons.setMinimumSize(QSize(0, 28))
+ self.rightButtons.setFrameShape(QFrame.NoFrame)
+ self.rightButtons.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout_2 = QHBoxLayout(self.rightButtons)
+ self.horizontalLayout_2.setSpacing(5)
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.settingsTopBtn = QPushButton(self.rightButtons)
+ self.settingsTopBtn.setObjectName(u"settingsTopBtn")
+ self.settingsTopBtn.setMinimumSize(QSize(28, 28))
+ self.settingsTopBtn.setMaximumSize(QSize(28, 28))
+ self.settingsTopBtn.setCursor(QCursor(Qt.PointingHandCursor))
+ icon1 = QIcon()
+ icon1.addFile(u":/icons/images/icons/icon_settings.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.settingsTopBtn.setIcon(icon1)
+ self.settingsTopBtn.setIconSize(QSize(20, 20))
+
+ self.horizontalLayout_2.addWidget(self.settingsTopBtn)
+
+ self.minimizeAppBtn = QPushButton(self.rightButtons)
+ self.minimizeAppBtn.setObjectName(u"minimizeAppBtn")
+ self.minimizeAppBtn.setMinimumSize(QSize(28, 28))
+ self.minimizeAppBtn.setMaximumSize(QSize(28, 28))
+ self.minimizeAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+ icon2 = QIcon()
+ icon2.addFile(u":/icons/images/icons/icon_minimize.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.minimizeAppBtn.setIcon(icon2)
+ self.minimizeAppBtn.setIconSize(QSize(20, 20))
+
+ self.horizontalLayout_2.addWidget(self.minimizeAppBtn)
+
+ self.maximizeRestoreAppBtn = QPushButton(self.rightButtons)
+ self.maximizeRestoreAppBtn.setObjectName(u"maximizeRestoreAppBtn")
+ self.maximizeRestoreAppBtn.setMinimumSize(QSize(28, 28))
+ self.maximizeRestoreAppBtn.setMaximumSize(QSize(28, 28))
+ font4 = QFont()
+ font4.setFamilies([u"Segoe UI"])
+ font4.setPointSize(10)
+ font4.setBold(False)
+ font4.setItalic(False)
+ font4.setStyleStrategy(QFont.PreferDefault)
+ self.maximizeRestoreAppBtn.setFont(font4)
+ self.maximizeRestoreAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+ icon3 = QIcon()
+ icon3.addFile(u":/icons/images/icons/icon_maximize.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.maximizeRestoreAppBtn.setIcon(icon3)
+ self.maximizeRestoreAppBtn.setIconSize(QSize(20, 20))
+
+ self.horizontalLayout_2.addWidget(self.maximizeRestoreAppBtn)
+
+ self.closeAppBtn = QPushButton(self.rightButtons)
+ self.closeAppBtn.setObjectName(u"closeAppBtn")
+ self.closeAppBtn.setMinimumSize(QSize(28, 28))
+ self.closeAppBtn.setMaximumSize(QSize(28, 28))
+ self.closeAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+ self.closeAppBtn.setIcon(icon)
+ self.closeAppBtn.setIconSize(QSize(20, 20))
+
+ self.horizontalLayout_2.addWidget(self.closeAppBtn)
+
+
+ self.horizontalLayout.addWidget(self.rightButtons, 0, Qt.AlignRight)
+
+
+ self.verticalLayout_2.addWidget(self.contentTopBg)
+
+ self.contentBottom = QFrame(self.contentBox)
+ self.contentBottom.setObjectName(u"contentBottom")
+ self.contentBottom.setFrameShape(QFrame.NoFrame)
+ self.contentBottom.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_6 = QVBoxLayout(self.contentBottom)
+ self.verticalLayout_6.setSpacing(0)
+ self.verticalLayout_6.setObjectName(u"verticalLayout_6")
+ self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
+ self.content = QFrame(self.contentBottom)
+ self.content.setObjectName(u"content")
+ self.content.setFrameShape(QFrame.NoFrame)
+ self.content.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout_4 = QHBoxLayout(self.content)
+ self.horizontalLayout_4.setSpacing(0)
+ self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
+ self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.pagesContainer = QFrame(self.content)
+ self.pagesContainer.setObjectName(u"pagesContainer")
+ self.pagesContainer.setStyleSheet(u"")
+ self.pagesContainer.setFrameShape(QFrame.NoFrame)
+ self.pagesContainer.setFrameShadow(QFrame.Raised)
+ self.gridLayout_5 = QGridLayout(self.pagesContainer)
+ self.gridLayout_5.setObjectName(u"gridLayout_5")
+ self.gridLayout_5.setContentsMargins(10, 10, 10, 10)
+ self.stackedWidget = QStackedWidget(self.pagesContainer)
+ self.stackedWidget.setObjectName(u"stackedWidget")
+ self.stackedWidget.setStyleSheet(u"background: transparent;")
+ self.home = QWidget()
+ self.home.setObjectName(u"home")
+ self.home.setStyleSheet(u"")
+ self.gridLayout_7 = QGridLayout(self.home)
+ self.gridLayout_7.setObjectName(u"gridLayout_7")
+ self.home_layout = QGridLayout()
+ self.home_layout.setObjectName(u"home_layout")
+
+ self.gridLayout_7.addLayout(self.home_layout, 0, 0, 1, 1)
+
+ self.stackedWidget.addWidget(self.home)
+ self.prober_control = QWidget()
+ self.prober_control.setObjectName(u"prober_control")
+ self.verticalLayout_20 = QVBoxLayout(self.prober_control)
+ self.verticalLayout_20.setObjectName(u"verticalLayout_20")
+ self.prober_control_layout = QGridLayout()
+ self.prober_control_layout.setObjectName(u"prober_control_layout")
+ self.prober_control_layout.setContentsMargins(1, 2, 3, -1)
+
+ self.verticalLayout_20.addLayout(self.prober_control_layout)
+
+ self.stackedWidget.addWidget(self.prober_control)
+ self.adc_control = QWidget()
+ self.adc_control.setObjectName(u"adc_control")
+ self.gridLayout_6 = QGridLayout(self.adc_control)
+ self.gridLayout_6.setObjectName(u"gridLayout_6")
+ self.adc_control_layout = QGridLayout()
+ self.adc_control_layout.setObjectName(u"adc_control_layout")
+
+ self.gridLayout_6.addLayout(self.adc_control_layout, 0, 0, 1, 1)
+
+ self.stackedWidget.addWidget(self.adc_control)
+ self.laser_control = QWidget()
+ self.laser_control.setObjectName(u"laser_control")
+ self.gridLayout_4 = QGridLayout(self.laser_control)
+ self.gridLayout_4.setObjectName(u"gridLayout_4")
+ self.laser_control_layout = QGridLayout()
+ self.laser_control_layout.setObjectName(u"laser_control_layout")
+
+ self.gridLayout_4.addLayout(self.laser_control_layout, 0, 0, 1, 1)
+
+ self.stackedWidget.addWidget(self.laser_control)
+ self.measured_data = QWidget()
+ self.measured_data.setObjectName(u"measured_data")
+ self.gridLayout_2 = QGridLayout(self.measured_data)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.measured_data_layout = QGridLayout()
+ self.measured_data_layout.setObjectName(u"measured_data_layout")
+
+ self.gridLayout_2.addLayout(self.measured_data_layout, 0, 0, 1, 1)
+
+ self.stackedWidget.addWidget(self.measured_data)
+
+ self.gridLayout_5.addWidget(self.stackedWidget, 0, 0, 1, 1)
+
+
+ self.horizontalLayout_4.addWidget(self.pagesContainer)
+
+ self.extraRightBox = QFrame(self.content)
+ self.extraRightBox.setObjectName(u"extraRightBox")
+ self.extraRightBox.setMinimumSize(QSize(0, 0))
+ self.extraRightBox.setMaximumSize(QSize(0, 16777215))
+ self.extraRightBox.setFrameShape(QFrame.NoFrame)
+ self.extraRightBox.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_7 = QVBoxLayout(self.extraRightBox)
+ self.verticalLayout_7.setSpacing(0)
+ self.verticalLayout_7.setObjectName(u"verticalLayout_7")
+ self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.themeSettingsTopDetail = QFrame(self.extraRightBox)
+ self.themeSettingsTopDetail.setObjectName(u"themeSettingsTopDetail")
+ self.themeSettingsTopDetail.setMaximumSize(QSize(16777215, 3))
+ self.themeSettingsTopDetail.setFrameShape(QFrame.NoFrame)
+ self.themeSettingsTopDetail.setFrameShadow(QFrame.Raised)
+
+ self.verticalLayout_7.addWidget(self.themeSettingsTopDetail)
+
+ self.contentSettings = QFrame(self.extraRightBox)
+ self.contentSettings.setObjectName(u"contentSettings")
+ self.contentSettings.setFrameShape(QFrame.NoFrame)
+ self.contentSettings.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_13 = QVBoxLayout(self.contentSettings)
+ self.verticalLayout_13.setSpacing(0)
+ self.verticalLayout_13.setObjectName(u"verticalLayout_13")
+ self.verticalLayout_13.setContentsMargins(0, 0, 0, 0)
+ self.txt_logs = QTextEdit(self.contentSettings)
+ self.txt_logs.setObjectName(u"txt_logs")
+
+ self.verticalLayout_13.addWidget(self.txt_logs)
+
+ self.topMenus = QFrame(self.contentSettings)
+ self.topMenus.setObjectName(u"topMenus")
+ self.topMenus.setFrameShape(QFrame.NoFrame)
+ self.topMenus.setFrameShadow(QFrame.Raised)
+ self.verticalLayout_14 = QVBoxLayout(self.topMenus)
+ self.verticalLayout_14.setSpacing(0)
+ self.verticalLayout_14.setObjectName(u"verticalLayout_14")
+ self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
+ self.btn_print = QPushButton(self.topMenus)
+ self.btn_print.setObjectName(u"btn_print")
+ sizePolicy.setHeightForWidth(self.btn_print.sizePolicy().hasHeightForWidth())
+ self.btn_print.setSizePolicy(sizePolicy)
+ self.btn_print.setMinimumSize(QSize(0, 45))
+ self.btn_print.setFont(font2)
+ self.btn_print.setCursor(QCursor(Qt.PointingHandCursor))
+ self.btn_print.setLayoutDirection(Qt.LeftToRight)
+ self.btn_print.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-print.png);")
+
+ self.verticalLayout_14.addWidget(self.btn_print)
+
+
+ self.verticalLayout_13.addWidget(self.topMenus, 0, Qt.AlignTop)
+
+
+ self.verticalLayout_7.addWidget(self.contentSettings)
+
+
+ self.horizontalLayout_4.addWidget(self.extraRightBox)
+
+
+ self.verticalLayout_6.addWidget(self.content)
+
+ self.bottomBar = QFrame(self.contentBottom)
+ self.bottomBar.setObjectName(u"bottomBar")
+ self.bottomBar.setMinimumSize(QSize(0, 22))
+ self.bottomBar.setMaximumSize(QSize(16777215, 22))
+ self.bottomBar.setFrameShape(QFrame.NoFrame)
+ self.bottomBar.setFrameShadow(QFrame.Raised)
+ self.horizontalLayout_5 = QHBoxLayout(self.bottomBar)
+ self.horizontalLayout_5.setSpacing(0)
+ self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
+ self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.creditsLabel = QLabel(self.bottomBar)
+ self.creditsLabel.setObjectName(u"creditsLabel")
+ self.creditsLabel.setMaximumSize(QSize(16777215, 16))
+ font5 = QFont()
+ font5.setFamilies([u"Segoe UI"])
+ font5.setBold(False)
+ font5.setItalic(False)
+ self.creditsLabel.setFont(font5)
+ self.creditsLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
+
+ self.horizontalLayout_5.addWidget(self.creditsLabel)
+
+ self.version = QLabel(self.bottomBar)
+ self.version.setObjectName(u"version")
+ self.version.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
+
+ self.horizontalLayout_5.addWidget(self.version)
+
+ self.frame_size_grip = QFrame(self.bottomBar)
+ self.frame_size_grip.setObjectName(u"frame_size_grip")
+ self.frame_size_grip.setMinimumSize(QSize(20, 0))
+ self.frame_size_grip.setMaximumSize(QSize(20, 16777215))
+ self.frame_size_grip.setFrameShape(QFrame.NoFrame)
+ self.frame_size_grip.setFrameShadow(QFrame.Raised)
+
+ self.horizontalLayout_5.addWidget(self.frame_size_grip)
+
+
+ self.verticalLayout_6.addWidget(self.bottomBar)
+
+
+ self.verticalLayout_2.addWidget(self.contentBottom)
+
+
+ self.appLayout.addWidget(self.contentBox)
+
+
+ self.appMargins.addWidget(self.bgApp)
+
+ MainWindow.setCentralWidget(self.styleSheet)
+
+ self.retranslateUi(MainWindow)
+
+ self.stackedWidget.setCurrentIndex(4)
+
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ self.titleLeftApp.setText(QCoreApplication.translate("MainWindow", u"PyDracula", None))
+ self.titleLeftDescription.setText(QCoreApplication.translate("MainWindow", u"Modern GUI / Flat Style", None))
+ self.toggleButton.setText(QCoreApplication.translate("MainWindow", u"Hide", None))
+ self.btn_start_measuring_routine.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
+ self.btn_home.setText(QCoreApplication.translate("MainWindow", u"Home", None))
+ self.btn_adc_control.setText(QCoreApplication.translate("MainWindow", u"ADC Control", None))
+ self.btn_laser_control.setText(QCoreApplication.translate("MainWindow", u"Laser Control", None))
+ self.btn_probe_control.setText(QCoreApplication.translate("MainWindow", u"Probe Control", None))
+ self.btn_measured_data.setText(QCoreApplication.translate("MainWindow", u"Measured Data", None))
+ self.btn_exit.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
+ self.toggleLeftBox.setText(QCoreApplication.translate("MainWindow", u"Left Box", None))
+ self.extraLabel.setText(QCoreApplication.translate("MainWindow", u"Left Box", None))
+#if QT_CONFIG(tooltip)
+ self.extraCloseColumnBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Close left box", None))
+#endif // QT_CONFIG(tooltip)
+ self.extraCloseColumnBtn.setText("")
+ self.btn_share.setText(QCoreApplication.translate("MainWindow", u"Share", None))
+ self.btn_adjustments.setText(QCoreApplication.translate("MainWindow", u"Adjustments", None))
+ self.btn_more.setText(QCoreApplication.translate("MainWindow", u"More", None))
+ self.textEdit.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
+"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
+"p, li { white-space: pre-wrap; }\n"
+"</style></head><body style=\" font-family:'Segoe UI'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">PyDracula</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" color:#ffffff;\">An interface created using Python and PySide (support for PyQt), and with colors based on the Dracula theme created by Zeno Rocha.</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-inde"
+ "nt:0; text-indent:0px;\"><span style=\" color:#ffffff;\">MIT License</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" color:#bd93f9;\">Created by: Wanderson M. Pimenta</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">Convert UI</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:9pt; color:#ffffff;\">pyside6-uic main.ui > ui_main.py</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">Convert QRC</span></p>\n"
+"<p align=\"center\" "
+ "style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:9pt; color:#ffffff;\">pyside6-rcc resources.qrc -o resources_rc.py</span></p></body></html>", None))
+ self.menu_file.setText(QCoreApplication.translate("MainWindow", u"File", None))
+ self.menu_edit.setText(QCoreApplication.translate("MainWindow", u"Edit", None))
+ self.menu_run.setText(QCoreApplication.translate("MainWindow", u"Run", None))
+ self.titleRight.setText(QCoreApplication.translate("MainWindow", u"FlexSensor 6", None))
+#if QT_CONFIG(tooltip)
+ self.settingsTopBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Settings", None))
+#endif // QT_CONFIG(tooltip)
+ self.settingsTopBtn.setText("")
+#if QT_CONFIG(tooltip)
+ self.minimizeAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Minimize", None))
+#endif // QT_CONFIG(tooltip)
+ self.minimizeAppBtn.setText("")
+#if QT_CONFIG(tooltip)
+ self.maximizeRestoreAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Maximize", None))
+#endif // QT_CONFIG(tooltip)
+ self.maximizeRestoreAppBtn.setText("")
+#if QT_CONFIG(tooltip)
+ self.closeAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Close", None))
+#endif // QT_CONFIG(tooltip)
+ self.closeAppBtn.setText("")
+ self.btn_print.setText(QCoreApplication.translate("MainWindow", u"Print", None))
+ self.creditsLabel.setText(QCoreApplication.translate("MainWindow", u"Flexsensor 6", None))
+ self.version.setText(QCoreApplication.translate("MainWindow", u"v1.0.3", None))
+ # retranslateUi
+
diff --git a/src/FlexSensor/MainWindow/view/StepThroughView.py b/src/FlexSensor/MainWindow/view/StepThroughView.py
new file mode 100644
index 0000000000000000000000000000000000000000..37e506f32435d5834af85a0cd03abbbdfa61b4c4
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/StepThroughView.py
@@ -0,0 +1,126 @@
+import traceback
+from PySide6.QtWidgets import (
+ QMainWindow, QWidget, QGridLayout, QPushButton, QLineEdit,
+)
+from PySide6.QtGui import QIcon
+
+import Prober as Prober
+
+import ConfigHandler.controller.VASInputFileParser as input_file_parser
+from Prober.controller.ProberController import ProberController
+from constants.FlexsensorConstants import Probe
+
+
+class StepThroughView(QMainWindow):
+ def __init__(self, grouped_structures, prober: ProberController):
+ super(StepThroughView, self).__init__()
+ self.prober = prober
+ self.grouped_structures = grouped_structures
+ self.idx_struct = 0
+ self.idx_group = 0
+ self.init_UI()
+ self.move_to_structure()
+ self.msg_server = None
+
+
+ def init_UI(self):
+ # create a layout
+ layout = QGridLayout()
+ widget = QWidget()
+ # add a label
+ self.group_name = QLineEdit("This is a label")
+ self.structure_name = QLineEdit("This is a label")
+ # add a button
+ self.btn_prev = QPushButton("Previous")
+ self.btn_prev.clicked.connect(self.on_click_prev)
+
+ # add a button
+ self.btn_next = QPushButton("Next")
+ self.btn_next.clicked.connect(self.on_click_next)
+
+ self.btn_search_for_light = QPushButton("Search for light")
+ self.btn_search_for_light.clicked.connect(self.on_search_for_light)
+
+ # Add the widgets to the layout
+ layout.addWidget(self.group_name, 0, 0, 1, 2)
+ layout.addWidget(self.structure_name, 1, 0, 1, 2)
+ layout.addWidget(self.btn_prev, 2, 0)
+ layout.addWidget(self.btn_next, 2, 1)
+
+
+ widget.setLayout(layout)
+ self.setCentralWidget(widget)
+ #self.layout.setLayout(tree)
+
+ self.setWindowTitle(f'Step Structure')
+ self.setWindowIcon(QIcon('icon.ico'))
+
+ def move_to_structure(self):
+
+ self.group: str = list(self.grouped_structures)[self.idx_group]
+ self.structures: dict = self.grouped_structures[self.group]
+ self.structure: input_file_parser.Structure = list(self.structures.values())[self.idx_struct]
+ try:
+ #with Prober.velox_api.MessageServerInterface() as self.msg_server:
+ #velox_api.MoveChuck(0, 0)
+ #print(f"New structure group ({self.idx_groups}): {self.groups}. {len(structures)} structures in group.")
+
+
+ # Move to die
+ #print(f"Move chuck (first probe) to X({self.structure.x_in}), Y({self.structure.y_in}).")
+ self.prober.move_chuck(self.structure.x_in, self.structure.y_in)
+
+ try:
+ if self.structure.in_out_diff_x > 50:
+ #print(
+ # f"Move second probe to X({self.structure.x_out}), Y({self.structure.y_out}) "
+ # f"- Difference x({self.structure.in_out_diff_x}) y({self.structure.in_out_diff_y})"
+ #)
+ self.prober.opt_if.move_optical_probe(Probe.OUTPUT, self.structure.in_out_diff_x, self.structure.in_out_diff_y, pos_ref="H")
+ #self.msg_server.sendSciCommand("MoveOpticalProbe",rparams='1 %s %s H' %
+ # (self.structure.in_out_diff_x, self.structure.in_out_diff_y)
+ #)
+ else:
+ raise Exception("Optical Probe Home not safe! x difference < 50 um: {self.structure.in_out_diff_x}")
+ except Exception as e:
+ print("error", f"Can't move optical probe safely. {e}")
+ print((
+ type(e), f"Can't move optical probe safely. {e}. Omitting Structure!", traceback.format_exc()
+ ))
+ print("warning", f"[!] Omitting structure {self.structure.name}")
+ except Exception as e:
+ print("error", f"Can't move optical probe safely. {e}")
+ print((
+ type(e), f"Can't move optical probe safely. {e}. Omitting Structure!", traceback.format_exc()
+ ))
+
+ self.group_name.setText(f"Group: {self.group}")
+ self.structure_name.setText(f"Structure: {self.structure.name}")
+
+ def on_search_for_light(self):
+ self.prober.opt_if.store_optical_probe_pos()
+ #self.prober.opt_if.restore_optical_probe_motor_pos(probe=Probe.INPUT)
+ #self.prober.opt_if.restore_optical_probe_motor_pos(probe=Probe.OUTPUT)
+
+
+ def on_click_prev(self):
+ self.idx_struct = self.idx_struct - 1
+ if self.idx_struct < 0:
+ self.idx_group = self.idx_group - 1
+ if self.idx_group < 0:
+ self.idx_group = len(self.grouped_structures) - 1
+
+ group: str = list(self.grouped_structures)[self.idx_group]
+ self.idx_struct = len(self.grouped_structures[group]) - 1
+ self.move_to_structure()
+
+ def on_click_next(self):
+ self.idx_struct = self.idx_struct + 1
+ if self.idx_struct >= len(self.structures):
+ self.idx_group = self.idx_group + 1
+ if self.idx_group >= len(self.grouped_structures):
+ self.idx_group = 0
+ self.idx_struct = 0
+ self.move_to_structure()
+
+
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/view/__init__.py b/src/FlexSensor/MainWindow/view/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py b/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..cf4b98992cb76d348fc55ba5e0805b32ec10628d
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py
@@ -0,0 +1,93 @@
+import sys
+
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QGroupBox, QGridLayout, QLineEdit, QLabel, QProgressBar
+
+import __version__
+from MainWindow.view import MainView
+from Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
+
+
+class HomeStatusWidget(QWidget):
+
+ def __init__(self, view: MainView):
+ super().__init__()
+
+ self.velox_kernel_version = None
+ self.python_version = None
+ self.script_version = None
+
+ self.view: MainView = view
+ layout = QGridLayout()
+ layout.addWidget(self.init_UI_wafer_info(), 0, 0, 1, 1)
+ layout.addWidget(self.init_UI_status_wdg(), 0, 1, 1, 1)
+ layout.addWidget(self.init_UI_version_info(), 1, 0, 1, 2)
+
+ self.setLayout(layout)
+
+ def init_UI_wafer_info(self):
+
+ grid_group_box = QGroupBox()
+ layout = QGridLayout()
+
+ self.tb_wafer_version = QLineEdit(parent=self, text=str(self.view.model.vaut_config.wafer_version))
+ #self.tb_wafer_version.textChanged.connect(self.on_wafer_version_changed)
+ layout.addWidget(QLabel("Wafer Version"), 0, 0, 1, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_wafer_version, 1, 0, 1, 2) # row, column, rowspan, colspan
+
+ self.tb_wafer_nr = QLineEdit(parent=self, text=str(self.view.model.vaut_config.wafer_nr))
+ #self.tb_wafer_nr.textChanged.connect(self.on_wafer_nr_changed)
+ layout.addWidget(QLabel("Wafer number"), 0, 2, 1, 1)
+ layout.addWidget(self.tb_wafer_nr, 1, 2, 1, 2)
+
+ grid_group_box.setLayout(layout)
+
+ return grid_group_box
+
+ def init_UI_status_wdg(self):
+ grid_group_box = QGroupBox()
+ layout = QVBoxLayout()
+ layout.addWidget(ProberPositionWidget(self.view.model.prober_model, "Horizontal"))
+
+ self.progress = QProgressBar(self)
+ self.progress.setStyleSheet(
+ "#GreenProgressBar { min-height: 12px; max-height: 12px; border-radius: 6px;}")
+ layout.addWidget(self.progress)
+ self.progress.setFixedHeight(self.progress.sizeHint().height() / 2)
+
+ grid_group_box.setLayout(layout)
+
+ return grid_group_box
+
+ def init_UI_version_info(self):
+
+ grid_group_box = QGroupBox()
+ layout = QGridLayout()
+ try:
+ self.velox_kernel_version = QLineEdit(parent=self,
+ text=self.view.model.prober_model.report_velox_kernel_version())
+
+ except Exception as e:
+ print(e)
+ self.velox_kernel_version = QLineEdit(
+ parent=self, text="Velox kernel version not available")
+
+ self.velox_kernel_version.setReadOnly(True)
+ # self.velox_kernel_version.setEnabled(False)
+ layout.addWidget(QLabel("Velox Kernel Version"), 2, 0)
+ layout.addWidget(self.velox_kernel_version, 3, 0)
+
+ self.python_version = QLineEdit(parent=self, text=str(sys.version))
+ self.python_version.setReadOnly(True)
+ # self.python_version.setEnabled(False)
+ layout.addWidget(QLabel("Python Version"), 2, 1)
+ layout.addWidget(self.python_version, 3, 1)
+
+ self.script_version = QLineEdit(parent=self, text=__version__.__version__)
+ self.script_version.setReadOnly(True)
+ self.script_version.setEnabled(False)
+ layout.addWidget(QLabel("Script Version"), 2, 2)
+ layout.addWidget(self.script_version, 3, 2)
+
+ grid_group_box.setLayout(layout)
+
+ return grid_group_box
diff --git a/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py b/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..8301a8aa6287a6a254a7a525a3e76c1887130059
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py
@@ -0,0 +1,32 @@
+import pyqtgraph as pg
+from PySide6.QtWidgets import QVBoxLayout, QWidget
+from pyqtgraph.dockarea import DockArea, Dock
+
+from MainWindow.view import MainView
+
+
+class ScopeWidget(QWidget):
+
+ def __init__(self, parent_view: MainView):
+ super().__init__()
+ self.parent_view = parent_view
+ layout = QVBoxLayout()
+ area = DockArea()
+
+ d1 = Dock("Analog Discovery 2")
+ d2 = Dock("Filtered")
+ area.addDock(d1, 'bottom')
+ area.addDock(d2, 'bottom', d1)
+
+ self.scope_original = pg.PlotWidget(title="AD2 Acquisition")
+ # self.scope_original.plot(np.random.normal(size=100)*1e12)
+ self.scope_original.plotItem.showGrid(x=True, y=True, alpha=1)
+ d1.addWidget(self.scope_original)
+
+ self.scope_filtered = pg.PlotWidget(title="Filtered Data")
+ # self.scope_filtered.plot(np.random.normal(size=100))
+ self.scope_filtered.plotItem.showGrid(x=True, y=True, alpha=1)
+ d2.addWidget(self.scope_filtered)
+ layout.addWidget(area)
+ self.setMinimumWidth(800)
+ self.setLayout(layout)
diff --git a/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py b/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py
new file mode 100644
index 0000000000000000000000000000000000000000..240ac93a1dc076903db0255eb560d5d92d0445f9
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py
@@ -0,0 +1,323 @@
+from PySide6.QtWidgets import QWidget, QGridLayout, QGroupBox, QLineEdit, QPushButton, QLabel, QDoubleSpinBox
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.view.ConfigView import ConfigView
+
+
+class WidgetSettingsInFilesFolders(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+
+ self.btn_select_list_of_structures = QPushButton(parent=self, text="...")
+ self.btn_select_working_directory = QPushButton(parent=self, text="...")
+
+ self.layout = QGridLayout()
+ self.init_UI()
+
+ def init_UI(self):
+ grid_group_box = QGroupBox("Input Files")
+ layout = QGridLayout()
+ # Working directory
+ self.tb_working_directory = QLineEdit(parent=self, text=str(self.vaut_config.get_output_directory().relative))
+ self.btn_select_working_directory.setMaximumWidth(self.btn_select_working_directory.sizeHint().height())
+ layout.addWidget(QLabel("Working directory"), 0, 0)
+ layout.addWidget(self.tb_working_directory, 0, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.btn_select_working_directory, 0, 3) # row, column, rowspan, colspan
+
+ # List of structures
+ self.tb_list_of_structures = QLineEdit(parent=self, text=str(self.vaut_config.wafer_config.get_structure_file().relative))
+ self.btn_select_list_of_structures.setMaximumWidth(self.btn_select_list_of_structures.sizeHint().height())
+ layout.addWidget(QLabel("Input Structure File"), 1, 0)
+ layout.addWidget(self.tb_list_of_structures, 1, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.btn_select_list_of_structures, 1, 3) # row, column, rowspan, colspan
+
+ grid_group_box.setLayout(layout)
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+
+class WidgetSettingsOutFilesFolders(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+
+ self.tb_log_file = QLineEdit(
+ text="self.vaut_config.wafer_config.get_log_file().filename")
+ self.tb_measurement_output = QLineEdit(
+ text="self.vaut_config.wafer_config.get_measurement_output().filename")
+ self.tb_mat_files_output = QLineEdit(
+ text="self.vaut_config.wafer_config.get_measurement_mat_file().filename")
+ self.tb_bookmark_file = QLineEdit(
+ text="self.vaut_config.wafer_config.get_bookmark_file()._mat_filename")
+ self.tb_scope_image_file = QLineEdit(
+ text="self.vaut_config.wafer_config.get_scope_image_file()._mat_filename")
+
+
+
+ self.layout = QGridLayout()
+ self.init_UI()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Output Files")
+ grid_group_box.setLayout(layout)
+
+
+
+
+
+
+ self.lbl_log_file = QLabel(parent=self)
+ self.tb_log_file.textChanged.connect(self.on_tb_log_file_text_changed)
+ self.on_tb_log_file_text_changed(self.tb_log_file.text())
+ layout.addWidget(QLabel("Log File"), 0, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_log_file, 0, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_log_file, 1, 0, 1, 2) # row, column, rowspan, colspan
+
+ # measurement output
+ self.lbl_measurement_output = QLabel(parent=self)
+ self.tb_measurement_output.textChanged.connect(self.on_tb_measurement_output_text_changed)
+ self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+ layout.addWidget(QLabel("Measurement output"), 2, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_measurement_output, 2, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_measurement_output, 3, 0, 1, 2) # row, column, rowspan, colspan
+
+ # Mat files output
+ self.lbl_mat_files_output = QLabel(parent=self)
+ self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+
+ self.tb_mat_files_output.textChanged.connect(self.on_tb_mat_files_output_text_changed)
+ layout.addWidget(QLabel("Matlab Files"), 4, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_mat_files_output, 4, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_mat_files_output, 5, 0, 1, 2) # row, column, rowspan, colspan
+
+ # bookmark files
+ self.lbl_bookmark_file = QLabel(parent=self)
+ self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+ self.tb_bookmark_file.textChanged.connect(self.on_tb_bookmark_file_text_changed)
+ self.tb_scope_image_file.textChanged.connect(self.on_tb_scope_image_file_text_changed)
+ layout.addWidget(QLabel("Bookmark files"), 6, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_bookmark_file, 6, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_bookmark_file, 7, 0, 1, 2) # row, column, rowspan, colspan
+
+ # scope shots
+ self.lbl_scope_image_file = QLabel(parent=self)
+ self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+ layout.addWidget(QLabel("Scope Shots"), 8, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_scope_image_file, 8, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_scope_image_file, 9, 0, 1, 2)
+
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+ def on_tb_scope_image_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_scope_image_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_scope_image_file().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_scope_image_file.setText(val)
+ # set label hover text
+ self.lbl_scope_image_file.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+ def on_tb_measurement_output_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_measurement_output().set_obj(value)
+ val = self.vaut_config.wafer_config.get_measurement_output().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_measurement_output.setText(val)
+ # set label hover text
+ self.lbl_measurement_output.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+ def on_tb_bookmark_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_bookmark_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_bookmark_file().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_bookmark_file.setText(val)
+ # set label hover text
+ self.lbl_bookmark_file.setToolTip(self.vaut_config.wafer_config.get_bookmark_file().absolute)
+
+ config = self.vaut_config
+
+ def on_tb_mat_files_output_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_measurement_mat_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_measurement_mat_file().relative.replace(
+ self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_mat_files_output.setText(val)
+ self.lbl_mat_files_output.setToolTip(self.vaut_config.wafer_config.get_measurement_mat_file().absolute)
+
+ def on_tb_log_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_log_file().set_obj(value)
+
+ val = self.vaut_config.wafer_config.get_log_file().relative.replace(self.vaut_config.get_output_directory().relative, "<b>wd</b>")
+ self.lbl_log_file.setText(val)
+ self.lbl_log_file.setToolTip(self.vaut_config.wafer_config.get_log_file().absolute)
+
+class WidgetAD2Settings(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+ self.c = ConfigView(vaut_config)
+
+
+ self.num_sample_rate = QDoubleSpinBox()
+ self.num_total_samples = QDoubleSpinBox()
+ self.num_sample_time = QDoubleSpinBox()
+
+ self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+ self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+ self.layout = QGridLayout()
+ self.init_UI()
+
+
+ def show_config(self):
+ self.c = ConfigView(self.vaut_config)
+ self.c.show()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Analog Discovery 2 Settings")
+ grid_group_box.setLayout(layout)
+
+ lbl_sample_rate = QLabel("Sample Rate")
+ layout.addWidget(lbl_sample_rate, 1, 0)
+ self.num_sample_rate.valueChanged.connect(lambda v: self.vaut_config.ad2_device_config.set_sample_rate(v))
+ self.num_sample_rate.setRange(0, 10**8)
+ self.num_sample_rate.setSingleStep(1)
+ self.num_sample_rate.setValue(self.vaut_config.ad2_device_config.get_sample_rate())
+ self.num_sample_rate.setSuffix(" Hz")
+ self.num_sample_rate.setDecimals(3)
+ self.num_sample_rate.setKeyboardTracking(False)
+ layout.addWidget(self.num_sample_rate, 1, 1, 1, 2)
+
+ lbl_total_samples = QLabel("Total Samples")
+ layout.addWidget(lbl_total_samples, 2, 0)
+ self.num_total_samples.setRange(0, 10**8)
+ self.num_total_samples.setSingleStep(1)
+ self.num_total_samples.setValue(self.vaut_config.ad2_device_config.get_total_samples())
+ self.num_total_samples.setDecimals(3)
+ self.num_total_samples.setKeyboardTracking(False)
+ layout.addWidget(self.num_total_samples, 2, 1, 1, 2)
+
+ lbl_sample_time = QLabel("Sample Time")
+ layout.addWidget(lbl_sample_time, 3, 0)
+ self.num_sample_time.setRange(0, 10**8)
+ self.num_sample_time.setSingleStep(1)
+ self.num_sample_time.setValue(self.vaut_config.ad2_device_config.get_sample_time())
+ self.num_sample_time.setSuffix(" s")
+ self.num_sample_time.setDecimals(3)
+ self.num_sample_time.setKeyboardTracking(False)
+ layout.addWidget(self.num_sample_time, 3, 1, 1, 2)
+
+ lbl_ad2_raw_out_file = QLabel("Raw Out File")
+ layout.addWidget(lbl_ad2_raw_out_file, 4, 0)
+ tb_ad2_raw_out_file = QLineEdit(text=self.vaut_config.ad2_device_config.get_ad2_raw_out_file().relative)
+ layout.addWidget(tb_ad2_raw_out_file, 4, 1)
+ layout.addWidget(self.btn_select_ad2_raw_out_file, 4, 2)
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+class WidgetLaserSettings(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+ self.c = None
+
+
+ self.num_wavelength_sweep_start = QDoubleSpinBox()
+ self.num_wavelength_range_stop = QDoubleSpinBox()
+ self.num_velocity = QDoubleSpinBox()
+ self.num_acceleration = QDoubleSpinBox()
+ self.num_deceleration = QDoubleSpinBox()
+
+
+ #self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+ #self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+ self.layout = QGridLayout()
+ self.init_UI()
+
+
+ def show_config(self):
+ self.c = ConfigView(self.vaut_config)
+ self.c.show()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Laser Settings")
+ grid_group_box.setLayout(layout)
+
+ lbl_wavelength_sweep_start = QLabel("Wavelength Sweep")
+ layout.addWidget(lbl_wavelength_sweep_start, 1, 0)
+
+
+
+ self.num_wavelength_sweep_start.setRange(0, 10 ** 8)
+ self.num_wavelength_sweep_start.setSingleStep(1)
+ self.num_wavelength_sweep_start.setValue(self.vaut_config.laser_config.get_wavelength_range()[0])
+ self.num_wavelength_sweep_start.setSuffix(" nm")
+ self.num_wavelength_sweep_start.setDecimals(3)
+ self.num_wavelength_sweep_start.setKeyboardTracking(False)
+ layout.addWidget(self.num_wavelength_sweep_start, 1, 1)
+ self.num_wavelength_sweep_start.valueChanged.connect(
+ lambda v: self.vaut_config.laser_config.set_wavelength_range(
+ [float(v), float(self.num_wavelength_range_stop.value())])
+ )
+
+ self.num_wavelength_range_stop.setRange(0, 10 ** 8)
+ self.num_wavelength_range_stop.setSingleStep(1)
+ self.num_wavelength_range_stop.setValue(self.vaut_config.laser_config.get_wavelength_range()[1])
+ self.num_wavelength_range_stop.setSuffix(" nm")
+ self.num_wavelength_range_stop.setDecimals(3)
+ self.num_wavelength_range_stop.setKeyboardTracking(False)
+ layout.addWidget(self.num_wavelength_range_stop, 1, 2)
+
+ self.num_wavelength_range_stop.valueChanged.connect(
+ lambda v: self.vaut_config.laser_config.set_wavelength_range(
+ [float(self.num_wavelength_sweep_start.value()), float(v)]
+ ))
+
+ lbl_velocity = QLabel("Velocity")
+ layout.addWidget(lbl_velocity, 2, 0)
+ self.num_velocity.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_velocity(v))
+ self.num_velocity.setRange(0, 10**8)
+ self.num_velocity.setSingleStep(1)
+ self.num_velocity.setValue(self.vaut_config.laser_config.get_velocity())
+ self.num_acceleration.setSuffix(" m/s")
+ self.num_velocity.setDecimals(3)
+ self.num_velocity.setKeyboardTracking(False)
+ layout.addWidget(self.num_velocity, 2, 1, 1, 2)
+
+ lbl_acceleration = QLabel("Acceleration")
+ layout.addWidget(lbl_acceleration, 3, 0)
+ self.num_acceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_acceleration(v))
+ self.num_acceleration.setRange(0, 10**8)
+ self.num_acceleration.setSingleStep(1)
+ self.num_acceleration.setValue(self.vaut_config.laser_config.get_acceleration())
+ self.num_acceleration.setSuffix(" m/s^2")
+ self.num_acceleration.setDecimals(3)
+ self.num_acceleration.setKeyboardTracking(False)
+ layout.addWidget(self.num_acceleration, 3, 1, 1, 2)
+
+ lbl_deceleration = QLabel("Deceleration")
+ layout.addWidget(lbl_deceleration, 4, 0)
+ self.num_deceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_deceleration(v))
+ self.num_deceleration.setRange(0, 10 ** 8)
+ self.num_deceleration.setSingleStep(1)
+ self.num_deceleration.setValue(self.vaut_config.laser_config.get_deceleration())
+ self.num_deceleration.setSuffix(" m/s^2")
+ self.num_deceleration.setDecimals(3)
+ self.num_deceleration.setKeyboardTracking(False)
+ layout.addWidget(self.num_deceleration, 4, 1, 1, 2)
+
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
diff --git a/src/FlexSensor/MainWindow/view/widgets/__init__.py b/src/FlexSensor/MainWindow/view/widgets/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py b/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..edc45ae18fc40102f8a27651f77dac72d5026488
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py
@@ -0,0 +1,17 @@
+# ///////////////////////////////////////////////////////////////
+#
+# BY: WANDERSON M.PIMENTA
+# PROJECT MADE WITH: Qt Designer and PySide6
+# V: 1.0.0
+#
+# This project can be used freely for all uses, as long as they maintain the
+# respective credits only in the Python scripts, any information in the visual
+# interface (GUI) can be modified without any implication.
+#
+# There are limitations on Qt licenses if you want to use your products
+# commercially, I recommend reading them on the official website:
+# https://doc.qt.io/qtforpython/licenses.html
+#
+# ///////////////////////////////////////////////////////////////
+
+from . custom_grips import CustomGrip
diff --git a/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py b/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py
new file mode 100644
index 0000000000000000000000000000000000000000..53a15a1d68cb56d2f1fe1821a1ce9dd261b6f340
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py
@@ -0,0 +1,238 @@
+# ///////////////////////////////////////////////////////////////
+#
+# BY: WANDERSON M.PIMENTA
+# PROJECT MADE WITH: Qt Designer and PySide6
+# V: 1.0.0
+#
+# This project can be used freely for all uses, as long as they maintain the
+# respective credits only in the Python scripts, any information in the visual
+# interface (GUI) can be modified without any implication.
+#
+# There are limitations on Qt licenses if you want to use your products
+# commercially, I recommend reading them on the official website:
+# https://doc.qt.io/qtforpython/licenses.html
+#
+# ///////////////////////////////////////////////////////////////
+
+from PySide6.QtCore import *
+from PySide6.QtGui import *
+from PySide6.QtWidgets import *
+
+class CustomGrip(QWidget):
+ def __init__(self, parent, position, disable_color = False):
+
+ # SETUP UI
+ QWidget.__init__(self)
+ self.parent = parent
+ self.setParent(parent)
+ self.wi = Widgets()
+
+ # SHOW TOP GRIP
+ if position == Qt.TopEdge:
+ self.wi.top(self)
+ self.setGeometry(0, 0, self.parent.width(), 10)
+ self.setMaximumHeight(10)
+
+ # GRIPS
+ top_left = QSizeGrip(self.wi.top_left)
+ top_right = QSizeGrip(self.wi.top_right)
+
+ # RESIZE TOP
+ def resize_top(event):
+ delta = event.pos()
+ height = max(self.parent.minimumHeight(), self.parent.height() - delta.y())
+ geo = self.parent.geometry()
+ geo.setTop(geo.bottom() - height)
+ self.parent.setGeometry(geo)
+ event.accept()
+ self.wi.top.mouseMoveEvent = resize_top
+
+ # ENABLE COLOR
+ if disable_color:
+ self.wi.top_left.setStyleSheet("background: transparent")
+ self.wi.top_right.setStyleSheet("background: transparent")
+ self.wi.top.setStyleSheet("background: transparent")
+
+ # SHOW BOTTOM GRIP
+ elif position == Qt.BottomEdge:
+ self.wi.bottom(self)
+ self.setGeometry(0, self.parent.height() - 10, self.parent.width(), 10)
+ self.setMaximumHeight(10)
+
+ # GRIPS
+ self.bottom_left = QSizeGrip(self.wi.bottom_left)
+ self.bottom_right = QSizeGrip(self.wi.bottom_right)
+
+ # RESIZE BOTTOM
+ def resize_bottom(event):
+ delta = event.pos()
+ height = max(self.parent.minimumHeight(), self.parent.height() + delta.y())
+ self.parent.resize(self.parent.width(), height)
+ event.accept()
+ self.wi.bottom.mouseMoveEvent = resize_bottom
+
+ # ENABLE COLOR
+ if disable_color:
+ self.wi.bottom_left.setStyleSheet("background: transparent")
+ self.wi.bottom_right.setStyleSheet("background: transparent")
+ self.wi.bottom.setStyleSheet("background: transparent")
+
+ # SHOW LEFT GRIP
+ elif position == Qt.LeftEdge:
+ self.wi.left(self)
+ self.setGeometry(0, 10, 10, self.parent.height())
+ self.setMaximumWidth(10)
+
+ # RESIZE LEFT
+ def resize_left(event):
+ delta = event.pos()
+ width = max(self.parent.minimumWidth(), self.parent.width() - delta.x())
+ geo = self.parent.geometry()
+ geo.setLeft(geo.right() - width)
+ self.parent.setGeometry(geo)
+ event.accept()
+ self.wi.leftgrip.mouseMoveEvent = resize_left
+
+ # ENABLE COLOR
+ if disable_color:
+ self.wi.leftgrip.setStyleSheet("background: transparent")
+
+ # RESIZE RIGHT
+ elif position == Qt.RightEdge:
+ self.wi.right(self)
+ self.setGeometry(self.parent.width() - 10, 10, 10, self.parent.height())
+ self.setMaximumWidth(10)
+
+ def resize_right(event):
+ delta = event.pos()
+ width = max(self.parent.minimumWidth(), self.parent.width() + delta.x())
+ self.parent.resize(width, self.parent.height())
+ event.accept()
+ self.wi.rightgrip.mouseMoveEvent = resize_right
+
+ # ENABLE COLOR
+ if disable_color:
+ self.wi.rightgrip.setStyleSheet("background: transparent")
+
+
+ def mouseReleaseEvent(self, event):
+ self.mousePos = None
+
+ def resizeEvent(self, event):
+ if hasattr(self.wi, 'container_top'):
+ self.wi.container_top.setGeometry(0, 0, self.width(), 10)
+
+ elif hasattr(self.wi, 'container_bottom'):
+ self.wi.container_bottom.setGeometry(0, 0, self.width(), 10)
+
+ elif hasattr(self.wi, 'leftgrip'):
+ self.wi.leftgrip.setGeometry(0, 0, 10, self.height() - 20)
+
+ elif hasattr(self.wi, 'rightgrip'):
+ self.wi.rightgrip.setGeometry(0, 0, 10, self.height() - 20)
+
+class Widgets(object):
+ def top(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ self.container_top = QFrame(Form)
+ self.container_top.setObjectName(u"container_top")
+ self.container_top.setGeometry(QRect(0, 0, 500, 10))
+ self.container_top.setMinimumSize(QSize(0, 10))
+ self.container_top.setMaximumSize(QSize(16777215, 10))
+ self.container_top.setFrameShape(QFrame.NoFrame)
+ self.container_top.setFrameShadow(QFrame.Raised)
+ self.top_layout = QHBoxLayout(self.container_top)
+ self.top_layout.setSpacing(0)
+ self.top_layout.setObjectName(u"top_layout")
+ self.top_layout.setContentsMargins(0, 0, 0, 0)
+ self.top_left = QFrame(self.container_top)
+ self.top_left.setObjectName(u"top_left")
+ self.top_left.setMinimumSize(QSize(10, 10))
+ self.top_left.setMaximumSize(QSize(10, 10))
+ self.top_left.setCursor(QCursor(Qt.SizeFDiagCursor))
+ self.top_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+ self.top_left.setFrameShape(QFrame.NoFrame)
+ self.top_left.setFrameShadow(QFrame.Raised)
+ self.top_layout.addWidget(self.top_left)
+ self.top = QFrame(self.container_top)
+ self.top.setObjectName(u"top")
+ self.top.setCursor(QCursor(Qt.SizeVerCursor))
+ self.top.setStyleSheet(u"background-color: rgb(85, 255, 255);")
+ self.top.setFrameShape(QFrame.NoFrame)
+ self.top.setFrameShadow(QFrame.Raised)
+ self.top_layout.addWidget(self.top)
+ self.top_right = QFrame(self.container_top)
+ self.top_right.setObjectName(u"top_right")
+ self.top_right.setMinimumSize(QSize(10, 10))
+ self.top_right.setMaximumSize(QSize(10, 10))
+ self.top_right.setCursor(QCursor(Qt.SizeBDiagCursor))
+ self.top_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+ self.top_right.setFrameShape(QFrame.NoFrame)
+ self.top_right.setFrameShadow(QFrame.Raised)
+ self.top_layout.addWidget(self.top_right)
+
+ def bottom(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ self.container_bottom = QFrame(Form)
+ self.container_bottom.setObjectName(u"container_bottom")
+ self.container_bottom.setGeometry(QRect(0, 0, 500, 10))
+ self.container_bottom.setMinimumSize(QSize(0, 10))
+ self.container_bottom.setMaximumSize(QSize(16777215, 10))
+ self.container_bottom.setFrameShape(QFrame.NoFrame)
+ self.container_bottom.setFrameShadow(QFrame.Raised)
+ self.bottom_layout = QHBoxLayout(self.container_bottom)
+ self.bottom_layout.setSpacing(0)
+ self.bottom_layout.setObjectName(u"bottom_layout")
+ self.bottom_layout.setContentsMargins(0, 0, 0, 0)
+ self.bottom_left = QFrame(self.container_bottom)
+ self.bottom_left.setObjectName(u"bottom_left")
+ self.bottom_left.setMinimumSize(QSize(10, 10))
+ self.bottom_left.setMaximumSize(QSize(10, 10))
+ self.bottom_left.setCursor(QCursor(Qt.SizeBDiagCursor))
+ self.bottom_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+ self.bottom_left.setFrameShape(QFrame.NoFrame)
+ self.bottom_left.setFrameShadow(QFrame.Raised)
+ self.bottom_layout.addWidget(self.bottom_left)
+ self.bottom = QFrame(self.container_bottom)
+ self.bottom.setObjectName(u"bottom")
+ self.bottom.setCursor(QCursor(Qt.SizeVerCursor))
+ self.bottom.setStyleSheet(u"background-color: rgb(85, 170, 0);")
+ self.bottom.setFrameShape(QFrame.NoFrame)
+ self.bottom.setFrameShadow(QFrame.Raised)
+ self.bottom_layout.addWidget(self.bottom)
+ self.bottom_right = QFrame(self.container_bottom)
+ self.bottom_right.setObjectName(u"bottom_right")
+ self.bottom_right.setMinimumSize(QSize(10, 10))
+ self.bottom_right.setMaximumSize(QSize(10, 10))
+ self.bottom_right.setCursor(QCursor(Qt.SizeFDiagCursor))
+ self.bottom_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+ self.bottom_right.setFrameShape(QFrame.NoFrame)
+ self.bottom_right.setFrameShadow(QFrame.Raised)
+ self.bottom_layout.addWidget(self.bottom_right)
+
+ def left(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ self.leftgrip = QFrame(Form)
+ self.leftgrip.setObjectName(u"left")
+ self.leftgrip.setGeometry(QRect(0, 10, 10, 480))
+ self.leftgrip.setMinimumSize(QSize(10, 0))
+ self.leftgrip.setCursor(QCursor(Qt.SizeHorCursor))
+ self.leftgrip.setStyleSheet(u"background-color: rgb(255, 121, 198);")
+ self.leftgrip.setFrameShape(QFrame.NoFrame)
+ self.leftgrip.setFrameShadow(QFrame.Raised)
+
+ def right(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(500, 500)
+ self.rightgrip = QFrame(Form)
+ self.rightgrip.setObjectName(u"right")
+ self.rightgrip.setGeometry(QRect(0, 0, 10, 500))
+ self.rightgrip.setMinimumSize(QSize(10, 0))
+ self.rightgrip.setCursor(QCursor(Qt.SizeHorCursor))
+ self.rightgrip.setStyleSheet(u"background-color: rgb(255, 0, 127);")
+ self.rightgrip.setFrameShape(QFrame.NoFrame)
+ self.rightgrip.setFrameShadow(QFrame.Raised)
diff --git a/src/FlexSensor/MainWindow/view/widgets/menu_bar_widget.py b/src/FlexSensor/MainWindow/view/widgets/menu_bar_widget.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py b/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcbe0d82efa3172ce5ecda09fa96125df16b4310
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py
@@ -0,0 +1,317 @@
+from PySide6.QtWidgets import QWidget, QGridLayout, QGroupBox, QLineEdit, QPushButton, QLabel, QDoubleSpinBox
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.view.ConfigView import ConfigView
+
+
+class WidgetSettingsInFilesFolders(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+
+ self.btn_select_list_of_structures = QPushButton(parent=self, text="...")
+ self.btn_select_working_directory = QPushButton(parent=self, text="...")
+
+ self.layout = QGridLayout()
+ self.init_UI()
+
+ def init_UI(self):
+ grid_group_box = QGroupBox("Input Files")
+ layout = QGridLayout()
+ # Working directory
+ self.tb_working_directory = QLineEdit(parent=self, text=str(self.vaut_config.get_output_directory().relative))
+ self.btn_select_working_directory.setMaximumWidth(self.btn_select_working_directory.sizeHint().height())
+ layout.addWidget(QLabel("Working directory"), 0, 0)
+ layout.addWidget(self.tb_working_directory, 0, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.btn_select_working_directory, 0, 3) # row, column, rowspan, colspan
+
+ # List of structures
+ self.tb_list_of_structures = QLineEdit(parent=self, text=str(self.vaut_config.wafer_config.get_structure_file().relative))
+ self.btn_select_list_of_structures.setMaximumWidth(self.btn_select_list_of_structures.sizeHint().height())
+ layout.addWidget(QLabel("Input Structure File"), 1, 0)
+ layout.addWidget(self.tb_list_of_structures, 1, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.btn_select_list_of_structures, 1, 3) # row, column, rowspan, colspan
+
+ grid_group_box.setLayout(layout)
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+
+class WidgetSettingsOutFilesFolders(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+
+ self.tb_log_file = QLineEdit(text=self.vaut_config.wafer_config.get_log_file().filename)
+ self.tb_measurement_output = QLineEdit(text=self.vaut_config.wafer_config.get_measurement_output().filename)
+ self.tb_mat_files_output = QLineEdit(text=self.vaut_config.wafer_config.get_measurement_mat_file().filename)
+ self.tb_bookmark_file = QLineEdit(text=self.vaut_config.wafer_config.get_bookmark_file().filename)
+ self.tb_scope_image_file = QLineEdit(text=self.vaut_config.wafer_config.get_scope_image_file().filename)
+
+
+ self.layout = QGridLayout()
+ self.init_UI()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Output Files")
+ grid_group_box.setLayout(layout)
+
+
+
+
+
+
+ self.lbl_log_file = QLabel(parent=self)
+ self.tb_log_file.textChanged.connect(self.on_tb_log_file_text_changed)
+ self.on_tb_log_file_text_changed(self.tb_log_file.text())
+ layout.addWidget(QLabel("Log File"), 0, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_log_file, 0, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_log_file, 1, 0, 1, 2) # row, column, rowspan, colspan
+
+ # measurement output
+ self.lbl_measurement_output = QLabel(parent=self)
+ self.tb_measurement_output.textChanged.connect(self.on_tb_measurement_output_text_changed)
+ self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+ layout.addWidget(QLabel("Measurement output"), 2, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_measurement_output, 2, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_measurement_output, 3, 0, 1, 2) # row, column, rowspan, colspan
+
+ # Mat files output
+ self.lbl_mat_files_output = QLabel(parent=self)
+ self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+
+ self.tb_mat_files_output.textChanged.connect(self.on_tb_mat_files_output_text_changed)
+ layout.addWidget(QLabel("Matlab Files"), 4, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_mat_files_output, 4, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_mat_files_output, 5, 0, 1, 2) # row, column, rowspan, colspan
+
+ # bookmark files
+ self.lbl_bookmark_file = QLabel(parent=self)
+ self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+ self.tb_bookmark_file.textChanged.connect(self.on_tb_bookmark_file_text_changed)
+ self.tb_scope_image_file.textChanged.connect(self.on_tb_scope_image_file_text_changed)
+ layout.addWidget(QLabel("Bookmark files"), 6, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_bookmark_file, 6, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_bookmark_file, 7, 0, 1, 2) # row, column, rowspan, colspan
+
+ # scope shots
+ self.lbl_scope_image_file = QLabel(parent=self)
+ self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+ layout.addWidget(QLabel("Scope Shots"), 8, 0) # row, column, rowspan, colspan
+ layout.addWidget(self.tb_scope_image_file, 8, 1) # row, column, rowspan, colspan
+ layout.addWidget(self.lbl_scope_image_file, 9, 0, 1, 2)
+
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+ def on_tb_scope_image_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_scope_image_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_scope_image_file().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_scope_image_file.setText(val)
+ # set label hover text
+ self.lbl_scope_image_file.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+ def on_tb_measurement_output_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_measurement_output().set_obj(value)
+ val = self.vaut_config.wafer_config.get_measurement_output().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_measurement_output.setText(val)
+ # set label hover text
+ self.lbl_measurement_output.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+ def on_tb_bookmark_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_bookmark_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_bookmark_file().relative.replace(self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_bookmark_file.setText(val)
+ # set label hover text
+ self.lbl_bookmark_file.setToolTip(self.vaut_config.wafer_config.get_bookmark_file().absolute)
+
+ config = self.vaut_config
+
+ def on_tb_mat_files_output_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_measurement_mat_file().set_obj(value)
+ val = self.vaut_config.wafer_config.get_measurement_mat_file().relative.replace(
+ self.vaut_config.get_output_directory().relative,
+ "<b>wd</b>")
+ self.lbl_mat_files_output.setText(val)
+ self.lbl_mat_files_output.setToolTip(self.vaut_config.wafer_config.get_measurement_mat_file().absolute)
+
+ def on_tb_log_file_text_changed(self, value):
+ if value is not None:
+ self.vaut_config.wafer_config.get_log_file().set_obj(value)
+
+ val = self.vaut_config.wafer_config.get_log_file().relative.replace(self.vaut_config.get_output_directory().relative, "<b>wd</b>")
+ self.lbl_log_file.setText(val)
+ self.lbl_log_file.setToolTip(self.vaut_config.wafer_config.get_log_file().absolute)
+
+class WidgetAD2Settings(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+ self.c = ConfigView(vaut_config)
+
+
+ self.num_sample_rate = QDoubleSpinBox()
+ self.num_total_samples = QDoubleSpinBox()
+ self.num_sample_time = QDoubleSpinBox()
+
+ self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+ self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+ self.layout = QGridLayout()
+ self.init_UI()
+
+
+ def show_config(self):
+ self.c = ConfigView(self.vaut_config)
+ self.c.show()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Analog Discovery 2 Settings")
+ grid_group_box.setLayout(layout)
+
+ lbl_sample_rate = QLabel("Sample Rate")
+ layout.addWidget(lbl_sample_rate, 1, 0)
+ self.num_sample_rate.valueChanged.connect(lambda v: self.vaut_config.ad2_device_config.set_sample_rate(v))
+ self.num_sample_rate.setRange(0, 10**8)
+ self.num_sample_rate.setSingleStep(1)
+ self.num_sample_rate.setValue(self.vaut_config.ad2_device_config.get_sample_rate())
+ self.num_sample_rate.setSuffix(" Hz")
+ self.num_sample_rate.setDecimals(3)
+ self.num_sample_rate.setKeyboardTracking(False)
+ layout.addWidget(self.num_sample_rate, 1, 1, 1, 2)
+
+ lbl_total_samples = QLabel("Total Samples")
+ layout.addWidget(lbl_total_samples, 2, 0)
+ self.num_total_samples.setRange(0, 10**8)
+ self.num_total_samples.setSingleStep(1)
+ self.num_total_samples.setValue(self.vaut_config.ad2_device_config.get_total_samples())
+ self.num_total_samples.setDecimals(3)
+ self.num_total_samples.setKeyboardTracking(False)
+ layout.addWidget(self.num_total_samples, 2, 1, 1, 2)
+
+ lbl_sample_time = QLabel("Sample Time")
+ layout.addWidget(lbl_sample_time, 3, 0)
+ self.num_sample_time.setRange(0, 10**8)
+ self.num_sample_time.setSingleStep(1)
+ self.num_sample_time.setValue(self.vaut_config.ad2_device_config.get_sample_time())
+ self.num_sample_time.setSuffix(" s")
+ self.num_sample_time.setDecimals(3)
+ self.num_sample_time.setKeyboardTracking(False)
+ layout.addWidget(self.num_sample_time, 3, 1, 1, 2)
+
+ lbl_ad2_raw_out_file = QLabel("Raw Out File")
+ layout.addWidget(lbl_ad2_raw_out_file, 4, 0)
+ tb_ad2_raw_out_file = QLineEdit(text=self.vaut_config.ad2_device_config.get_ad2_raw_out_file().relative)
+ layout.addWidget(tb_ad2_raw_out_file, 4, 1)
+ layout.addWidget(self.btn_select_ad2_raw_out_file, 4, 2)
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
+class WidgetLaserSettings(QWidget):
+ def __init__(self, vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.vaut_config = vaut_config
+ self.c = None
+
+
+ self.num_wavelength_sweep_start = QDoubleSpinBox()
+ self.num_wavelength_range_stop = QDoubleSpinBox()
+ self.num_velocity = QDoubleSpinBox()
+ self.num_acceleration = QDoubleSpinBox()
+ self.num_deceleration = QDoubleSpinBox()
+
+
+ #self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+ #self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+ self.layout = QGridLayout()
+ self.init_UI()
+
+
+ def show_config(self):
+ self.c = ConfigView(self.vaut_config)
+ self.c.show()
+
+ def init_UI(self):
+ layout = QGridLayout()
+ grid_group_box = QGroupBox("Laser Settings")
+ grid_group_box.setLayout(layout)
+
+ lbl_wavelength_sweep_start = QLabel("Wavelength Sweep")
+ layout.addWidget(lbl_wavelength_sweep_start, 1, 0)
+
+
+
+ self.num_wavelength_sweep_start.setRange(0, 10 ** 8)
+ self.num_wavelength_sweep_start.setSingleStep(1)
+ self.num_wavelength_sweep_start.setValue(self.vaut_config.laser_config.get_wavelength_range()[0])
+ self.num_wavelength_sweep_start.setSuffix(" nm")
+ self.num_wavelength_sweep_start.setDecimals(3)
+ self.num_wavelength_sweep_start.setKeyboardTracking(False)
+ layout.addWidget(self.num_wavelength_sweep_start, 1, 1)
+ self.num_wavelength_sweep_start.valueChanged.connect(
+ lambda v: self.vaut_config.laser_config.set_wavelength_range(
+ [float(v), float(self.num_wavelength_range_stop.value())])
+ )
+
+ self.num_wavelength_range_stop.setRange(0, 10 ** 8)
+ self.num_wavelength_range_stop.setSingleStep(1)
+ self.num_wavelength_range_stop.setValue(self.vaut_config.laser_config.get_wavelength_range()[1])
+ self.num_wavelength_range_stop.setSuffix(" nm")
+ self.num_wavelength_range_stop.setDecimals(3)
+ self.num_wavelength_range_stop.setKeyboardTracking(False)
+ layout.addWidget(self.num_wavelength_range_stop, 1, 2)
+
+ self.num_wavelength_range_stop.valueChanged.connect(
+ lambda v: self.vaut_config.laser_config.set_wavelength_range(
+ [float(self.num_wavelength_sweep_start.value()), float(v)]
+ ))
+
+ lbl_velocity = QLabel("Velocity")
+ layout.addWidget(lbl_velocity, 2, 0)
+ self.num_velocity.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_velocity(v))
+ self.num_velocity.setRange(0, 10**8)
+ self.num_velocity.setSingleStep(1)
+ self.num_velocity.setValue(self.vaut_config.laser_config.get_velocity())
+ self.num_acceleration.setSuffix(" m/s")
+ self.num_velocity.setDecimals(3)
+ self.num_velocity.setKeyboardTracking(False)
+ layout.addWidget(self.num_velocity, 2, 1, 1, 2)
+
+ lbl_acceleration = QLabel("Acceleration")
+ layout.addWidget(lbl_acceleration, 3, 0)
+ self.num_acceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_acceleration(v))
+ self.num_acceleration.setRange(0, 10**8)
+ self.num_acceleration.setSingleStep(1)
+ self.num_acceleration.setValue(self.vaut_config.laser_config.get_acceleration())
+ self.num_acceleration.setSuffix(" m/s^2")
+ self.num_acceleration.setDecimals(3)
+ self.num_acceleration.setKeyboardTracking(False)
+ layout.addWidget(self.num_acceleration, 3, 1, 1, 2)
+
+ lbl_deceleration = QLabel("Deceleration")
+ layout.addWidget(lbl_deceleration, 4, 0)
+ self.num_deceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_deceleration(v))
+ self.num_deceleration.setRange(0, 10 ** 8)
+ self.num_deceleration.setSingleStep(1)
+ self.num_deceleration.setValue(self.vaut_config.laser_config.get_deceleration())
+ self.num_deceleration.setSuffix(" m/s^2")
+ self.num_deceleration.setDecimals(3)
+ self.num_deceleration.setKeyboardTracking(False)
+ layout.addWidget(self.num_deceleration, 4, 1, 1, 2)
+
+
+ self.layout.addWidget(grid_group_box)
+ self.setLayout(self.layout)
+
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..217bfe27e638dd16e05d1575c480ff76f60c1331
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py
@@ -0,0 +1,184 @@
+import logging
+import os
+from pathlib import Path
+
+import numpy as np
+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
+
+
+class MeasuredData:
+
+
+ def __init__(self, laser_properties: LaserProperties, ad2_properties: AD2CaptDeviceProperties,
+ wafer_properties: WaferProperties, waveguide_properties: WaveguideProperties,
+ measurement_properties: MeasurementProperties):
+ #super().__init__()
+ self.logger = logging.getLogger("MeasuredSignal")
+ # ==============================================================================================================
+ # Tables
+ self._tables: MeasurementDataTables = MeasurementDataTables()
+
+ # ==============================================================================================================
+ # Properties for storing information
+ self._laser_properties: LaserProperties = laser_properties # Laser Properties
+ self._ad2_properties: AD2CaptDeviceProperties = ad2_properties # AD2CaptDev Properties
+ self._wafer_properties: WaferProperties = wafer_properties # Wafer Properties
+ self._waveguide_properties: WaveguideProperties = waveguide_properties # Waveguide Properties
+ # Measurement properties like findpeaks parameter
+ self._measurement_properties: MeasurementProperties = MeasurementProperties(
+ MPropertiesFindPeaks(0.1, 10000, None))
+
+ # ==============================================================================================================
+ # Dataframe with measured values
+ self._measured_data: pd.DataFrame = self._tables.append(pd.DataFrame(), '_measured_data', "Measured Data")
+ # Calculation Tables
+ # Stores the found peaks
+ self._peaks: pd.DataFrame = self._tables.append(pd.DataFrame(), '_peaks', 'Peaks')
+ # Store wg parameters like FSR, and ng
+ self._wg_param: pd.DataFrame = self._tables.append(pd.DataFrame(), '_wg_param', 'Waveguide Parameters')
+
+ # ==============================================================================================================
+ # COnnect the signals
+ self._measurement_properties.find_peaks.properties_changed.connect(self.find_peaks)
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ @property
+ def waveguide_properties(self):
+ return self._waveguide_properties
+
+ @waveguide_properties.setter
+ def waveguide_properties(self, value):
+ self._waveguide_properties = value
+
+ @property
+ def measurement_properties(self):
+ return self._measurement_properties
+
+ @measurement_properties.setter
+ def measurement_properties(self, value):
+ self._measurement_properties = value
+
+ @property
+ def ad2_properties(self):
+ return self._ad2_properties
+
+ @ad2_properties.setter
+ def ad2_properties(self, value):
+ self._ad2_properties = value
+
+ @property
+ def laser_properties(self):
+ return self._laser_properties
+
+ @laser_properties.setter
+ def laser_properties(self, value):
+ self._laser_properties = value
+
+ @property
+ def wafer_properties(self):
+ return self._wafer_properties
+
+ @wafer_properties.setter
+ def wafer_properties(self, value):
+ self._wafer_properties = value
+
+ # ==================================================================================================================
+ # Properties
+ # ==================================================================================================================
+ @property
+ def tables(self) -> MeasurementDataTables:
+ return self._tables
+
+ @property
+ def peaks(self) -> pd.DataFrame:
+ return self._peaks
+
+ # ==================================================================================================================
+ # Calculations and table creations
+ # ==================================================================================================================
+ def calculate_wg_params(self, table="_peaks"):
+ peaks_wl: ndarray = self.tables.get(table)['wavelength'].to_numpy()
+ try:
+ if len(peaks_wl) % 2 == 1:
+ self.logger.warning(f"[{self}] | Number of peaks not even ({len(peaks_wl)}), removing last peak.")
+ peaks_wl = peaks_wl[:-1]
+ self.logger.info(f"[{self}] | Reshaping {np.shape(peaks_wl)} to (-1, 2)")
+ self._wg_param = pd.DataFrame(peaks_wl.reshape(-1, 2), columns=['P1', 'P2'])
+ self._wg_param['FSR'] = self._wg_param.apply(lambda row: row['P2'] - row['P1'], axis=1)
+ self._wg_param['lambda'] = self._wg_param.apply(lambda row: np.mean((row['P2'], row['P1'])), axis=1)
+ self._wg_param['ng'] = self.waveguide_properties.group_index(self._wg_param)
+ # self._wg_param.apply(lambda row: (row['lambda'] ** 2) / (row['FSR'] * dl), axis=1)
+ # Filter outliers
+ self._wg_param = self._tables.update(self._wg_param[(np.abs(scipy.stats.zscore(self._wg_param['ng'])) < 2)],
+ '_wg_param')
+ except Exception as e:
+ print(f"Error {e}")
+
+ def __str__(self):
+ return f"{self.wafer_properties.wafer_number}/" \
+ f"{self.wafer_properties.die_number}/" \
+ f"{self.wafer_properties.structure_name} - {self.wafer_properties.repetition}"
+
+ # ==================================================================================================================
+ # I/O - Operations and Plotting
+ # ==================================================================================================================
+ def _save_mat_file(self, filename: str) -> object:
+
+ self._mat_filename = Path(filename)
+ dirname = self._mat_filename.parent.absolute()
+ self.logger.info(f"[{self}] | Generating mat file and saving to {self._mat_filename.name} (folder: {dirname})")
+ if self._mat_filename is None or self._mat_filename == "":
+ raise ValueError("No mat file generated. Filename is not defined")
+
+ if not str(self._mat_filename).endswith(".mat"):
+ raise ValueError("No mat file generated. Filename does not end with .mat")
+ if self._measured_data is None:
+ raise ValueError(
+ "No mat file generated. No measured amplitude data. No mat file produced fot this structure.")
+ # Get the file name from file
+
+ # Make a path
+ # Check if path exists
+ if not os.path.exists(dirname):
+ try:
+ os.makedirs(dirname)
+ except OSError as exc: # Guard against
+ raise ValueError("No mat file generated. Could not create directory")
+ mdic = self.to_dict()
+ #print(mdic)
+ scipy.io.savemat(self._mat_filename, mdict=mdic)
+ #self._measured_data.to_csv(self.datafile)
+ self.write_matlab_file(self._mat_filename, self.datafile, f"{self._mat_filename.parent}/load_all.m")
+
+ self.logger.info(f"[{self}] | Stored matlab file to {self._mat_filename}")
+
+ return self._mat_filename
+
+ def write_matlab_file(self, mat_file, csv_file, filename: str) -> object:
+ mfile = ""
+ mfile += "load('" + str(filename) + "');"
+ # load csv with matlab
+ mfile += "data = readcsv('" + str(self.datafile) + "');"
+ # save matlab file
+ with open(filename, 'w') as f:
+ f.write(mfile)
+
+ # ==================================================================================================================
+ # abstract methods
+ # ==================================================================================================================
+ def find_peaks(self):
+ raise NotImplementedError()
+
+ def to_dict(self) -> dict:
+ raise NotImplementedError()
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..77293227af0a117a1792590b8e355de068bf5d12
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py
@@ -0,0 +1,142 @@
+import time
+
+import numpy as np
+import pandas as pd
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QProgressDialog
+from numpy import ndarray
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+import mcpy
+from MeasurementData.MeasuredData.SupportClasses.MatplotlibPlottingHelpers import MPLPlottingHelper
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from generics.logger import setup_logging
+from wrappers.QProgressBarWindow import QProgressBarWindow
+
+
+class MultiMeasuredData(MeasuredData):
+
+ def __init__(self, single_measurements: list[SingleMeasuredData]):
+ self._single_measurements = single_measurements
+
+ super().__init__(laser_properties=self._single_measurements[0].laser_properties,
+ ad2_properties=self._single_measurements[0].ad2_properties,
+ wafer_properties=self._single_measurements[0].wafer_properties,
+ waveguide_properties=self._single_measurements[0].waveguide_properties,
+ measurement_properties=self._single_measurements[0].measurement_properties,
+ )
+ self.wafer_properties._structure_name += " - Mean"
+
+ self._recalculate_measured_data()
+ self.consolidate_measurement()
+ self.calculate_mean_and_std()
+ self.calculate_wg_params(table='_peaks')
+ self.calculate_all(table='_peaks')
+
+ def consolidate_measurement(self):
+ self.logger.info("Consolidating all measurements to one measurement")
+ progress = QProgressDialog(f"Reading files...", "Abort", 0, len(self._single_measurements))
+ progress.setWindowModality(Qt.WindowModal)
+ progress.show()
+
+ tmp_measured_data = []
+ for i, mea, it in QProgressBarWindow(self._single_measurements):
+ it.print(f"Consolidating measurement {str(mea)}")
+ tmp_measured_data.append(pd.DataFrame(
+ mea.tables.get('_peaks')['wavelength'].reset_index()[:].values,
+ columns=[f'index_{mea.wafer_properties.repetition}',
+ f'wavelength_{mea.wafer_properties.repetition}']
+ ))
+
+ self._measured_data = self._tables.update(pd.concat(tmp_measured_data, axis=1), '_measured_data')
+
+ def _recalculate_measured_data(self):
+ self.logger.info("Recalculating all measurements")
+
+ for i, mea, it in QProgressBarWindow(self._single_measurements):
+ mea.calulate_all()
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def calculate_mean_and_std(self):
+ self._peaks['wavelength'] = self._measured_data.filter(like='wavelength').apply(
+ lambda row: mcpy.DirectObservations(row), axis=1)
+ self._peaks['index'] = self._measured_data.filter(like='index').apply(
+ lambda row: mcpy.DirectObservations(row), axis=1)
+ self._tables.update(self._peaks, '_peaks')
+
+ def calculate_all(self, table='_peaks', N=100000):
+ peaks_wl: ndarray = self.tables.get(table)['wavelength'].to_numpy()
+ try:
+ if len(peaks_wl) % 2 == 1:
+ self.logger.warning(f"[{self}] | Number of peaks not even ({len(peaks_wl)}), removing last peak.")
+ peaks_wl = peaks_wl[:-1]
+ self.logger.info(f"[{self}] | Reshaping {np.shape(peaks_wl)} to (-1, 2)")
+ self._wg_param = pd.DataFrame(peaks_wl.reshape(-1, 2), columns=['P1', 'P2']) # .astype(Uncertainty)
+
+ self._wg_param['P1 (MC)'] = self._wg_param.apply(
+ lambda row: row['P1'].rand(N), axis=1)
+
+ self._wg_param['P2 (MC)'] = self._wg_param.apply(
+ lambda row: row['P2'].rand(N), axis=1)
+
+ self._wg_param['FSR (MC)'] = self._wg_param.apply(
+ lambda row: row['P2 (MC)'] - row['P1 (MC)'], axis=1)
+
+ self._wg_param['lambda (MC)'] = self._wg_param.apply(
+ lambda row: (row['P2 (MC)']+row['P1 (MC)'])/2, axis=1)
+
+ self._wg_param['ng (MC)'] = self._wg_param.apply(
+ lambda row: self.waveguide_properties.group_index(row['lambda (MC)'], row['FSR (MC)'] ), axis=1)
+ # Place here any other calculations
+
+ # Update the _tables
+ self._tables.update(self._wg_param, '_wg_param')
+ self._tables.add_plot('ng (FSR)',
+ plot_function=lambda plotwidget: MPLPlottingHelper.plt_errorbar_mcsamples(
+ plotwidget,
+ x_values=self._wg_param['lambda (MC)'],
+ y_values=self._wg_param['ng (MC)']))
+ self._tables.add_plot('FSR (FSR)',
+ plot_function=lambda plotwidget: MPLPlottingHelper.plt_errorbar_mcsamples(
+ plotwidget,
+ x_values=self._wg_param['lambda (MC)'],
+ y_values=self._wg_param['FSR (MC)']))
+ except Exception as e:
+ print(f"Error {e}")
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def to_dict(self) -> dict:
+ return {
+ "laser_properties": self._laser_properties.to_dict(),
+ "wafer_properties": self._wafer_properties.to_dict(),
+ "measurement_properties": self._measurement_properties.to_dict(),
+ "waveguide_properties": self._waveguide_properties.to_dict(),
+ "amplitudes": [i.to_dict() for i in self._single_measurements],
+
+ }
+
+ def __str__(self):
+ return f"{self.wafer_properties.wafer_number}/" \
+ f"{self.wafer_properties.die_number}/" \
+ f"{self.wafer_properties.structure_name}-Sum"
+
+
+if __name__ == "__main__":
+ setup_logging()
+
+ mypath = 'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+ mm_data = MeasurementDataLoader.from_folder(mypath)
+ print(mm_data.wafers)
+ print(mm_data.dies)
+ print(mm_data.structure_name)
+
+ filtered_files = mm_data.get_measurement_series(structure_name='mzi2-2')
+
+ data = MultiMeasuredData(filtered_files)
+ print(data._wg_param)
+ # ädata.generate_mat_file(r'E:\test.mat')
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..e21abc0db0a958240a6bf1e0fdb270909a2d12ff
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py
@@ -0,0 +1,667 @@
+import sys
+sys.path.append("../flexsensorpy")
+sys.path.append("../mcpy")
+import pathlib
+from datetime import datetime
+
+
+import scipy.io
+import numpy as np
+import pandas as pd
+
+import logging
+from pathlib import Path
+
+from PySide6.QtWidgets import QApplication
+from numpy import linspace
+from scipy import signal
+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)
+
+import mcpy
+
+from MeasurementData.Properties.WaferProperties import WaferProperties
+from generics.logger import setup_logging
+
+
+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
+
+ @staticmethod
+ def convert(mat_file):
+ """Reads the mat file and converts the new format to the old format"""
+ data = SingleMeasuredData.from_mat(mat_file)
+ filename = mat_file.name.replace('.mat', '_v2.mat')
+ path = str(mat_file.parent).replace('measurements', 'measurements_v2')
+ # create a folder converted and save the file there
+ file = Path(f"{path}/{filename}")
+ data.save(str(file))
+
+
+ def __init__(self,
+ laser_properties: LaserProperties,
+ ad2_properties: AD2CaptDeviceProperties,
+ wafer_properties: WaferProperties,
+ waveguide_properties: WaveguideProperties,
+ measurement_properties: MeasurementProperties,
+ timestamp: datetime,
+ measurement_file: Path | str = None,
+ measurement_data = None,
+ *args, **kwargs
+ ):
+ super().__init__(laser_properties, ad2_properties, wafer_properties, waveguide_properties, measurement_properties)
+
+ if isinstance(measurement_data, list) or isinstance(measurement_data, np.ndarray):
+ self.measurement_file = measurement_file
+ # Store ot
+ self._measured_data: pd.DataFrame = self._tables.update(
+ pd.DataFrame(measurement_data, columns=['amplitude']), '_measured_data')
+ self._measurement_length = len(self._measured_data)
+ self.logger.debug(f"Measurement signal length: {self._measurement_length}")
+ # Generate the wacelength vector
+ self._create_wavelength_vector()
+ # Detrend the signal
+ self._detrend_signal()
+ else:
+ #self._raw_measurement_data: dask.array = dd.read_parquet(self.measurement_file)
+ self._measured_data = self._tables.update(measurement_data, '_measured_data')
+
+
+ self.print_enabled = True
+ self._calculated = False
+ # ==============================================================================================================
+ self._timestamp = timestamp
+ self._measure_time = self._ad2_properties.measurement_time
+
+ self.datafile = None
+ # Measured Data (raw)
+
+ # self._measurement_data_smoothed = self._smooth_signal(self._measurement_data_detrend)
+
+ # ==============================================================================================================
+ # Dataframe with measured values
+
+ # self._create_wavelength_vector()
+ # self._detrend_signal()
+
+ @property
+ def measured_data(self):
+ return self._measured_data
+
+ @measured_data.setter
+ def measured_data(self, value):
+ self._measured_data = value
+
+ # ==================================================================================================================
+ # Generate a wavelength vector from the given settings
+ # ==================================================================================================================
+ def _create_wavelength_vector(self):
+ """
+ Creates the wavelength vector for the measured data.
+ The wavelength vector is created based on the given laser properties.
+ """
+
+ sample_rate = float(self._ad2_properties.sample_rate)
+ acc = float(self._laser_properties.acceleration)
+ dec = float(self._laser_properties.deceleration)
+ vel = float(self._laser_properties.velocity)
+ wl_range = self._laser_properties.wavelength_range
+
+ self.logger.debug(f"Creating wavelenght vector.")
+ self.logger.debug(f"Velocity: {vel}, Acc: {acc}, Dec: {dec}, Range: {wl_range}")
+
+ # the duration of a sample in s
+ duration_sample = 1 / sample_rate
+ t_acc = vel / acc # Acceleration time of the laser; s
+ t_dec = vel / dec # Deceleration time of the laser; s
+ self.logger.debug(f"duration_sample: {duration_sample}, t_acc: {t_acc}, Dec: {t_dec}")
+
+ self.p_acc_stop = int(t_acc * sample_rate)
+ self.logger.debug(f"Point acc_stop [{t_acc}*{sample_rate}]: {self.p_acc_stop}")
+
+ self.p_dec_start = int(self._measurement_length - t_acc * sample_rate)
+ self.logger.debug(f"Point dec_start [{self._measurement_length}-{t_acc}*{sample_rate}]: {self.p_dec_start}")
+
+ if self.p_acc_stop > self.p_dec_start:
+ raise ValueError("The Acceleration point cant be before the decceleration point: {self.p_acc_stop} > {self.p_dec_start}")
+
+ s_acc = []
+ for j in range(0, self.p_acc_stop):
+ s_acc.append(
+ ((1 / 2) * t_acc * (duration_sample * j) ** 2)
+ )
+ wl_acc = np.add(s_acc, float(wl_range[0]))
+ self.logger.debug(f"Length of acc vector: {len(wl_acc)}")
+ wl_dec = np.subtract(float(wl_range[len(wl_range) - 1]),
+ s_acc)[::-1]
+ self.logger.debug(f"Length of dec vector: {len(wl_dec)}")
+ # Acceleration Phase/Deceleration Phase - Start and stop point
+ self.wl_acc_stop = wl_acc[-1]
+ self.wl_dec_start = wl_dec[0]
+ #self.logger.debug(f"lenght: {self.p_dec_start} - {self.p_acc_stop}")
+ length = int((self.p_dec_start - self.p_acc_stop))
+ rounding_diff = self._measurement_length - (length + len(wl_acc) + len(wl_dec))
+ length += rounding_diff
+ self.logger.debug(f"0 {length}")
+ # self.logger.debug(f"+1 {length+2}")
+ #self.logger.debug(f"+3{length+3}")
+ #length = length + 1
+ # self.logger.debug(f"+1 {length}")
+ wl_move = linspace(self.wl_acc_stop, self.wl_dec_start, length)
+
+ wl = np.concatenate((wl_acc, wl_move, wl_dec))
+ self.logger.debug(f"[{self}] | Created wavelength vector: [0 - {self.p_acc_stop}] (Diff {len(wl_acc)}) -- "
+ f"<{len(wl_move)}> -- "
+ f"[{self.p_dec_start} - {len(wl)}] (Diff {len(wl_dec)})")
+
+ self._measured_data['wavelength'] = wl
+
+ def _smooth_signal(self, vec, window=150):
+
+ return np.convolve(vec, np.ones(window), 'valid') / window
+
+ def _detrend_signal(self):
+ self._measured_data['detrend'] = signal.detrend(self._measured_data['amplitude'])
+
+ # ==================================================================================================================
+ # Calculations and table creations
+ # ==================================================================================================================
+ def find_peaks(self):
+ self._detrend_signal()
+ vec = self._measured_data['detrend']
+ _peaks, _ = find_peaks(vec,
+ height=self.measurement_properties.find_peaks.height,
+ distance=self.measurement_properties.find_peaks.distance,
+ prominence=self.measurement_properties.find_peaks.prominence)
+ peaks = np.zeros(len(vec))
+ peaks[_peaks] = 1
+ self._measured_data['peaks'] = peaks.astype(bool)
+ self._peaks = self._tables.update(self._measured_data[self._measured_data['peaks'] == True], '_peaks')
+ self.logger.debug(f"[{self}] | Found {len(self._peaks)} peaks. "
+ f"Parameters {self.measurement_properties.find_peaks}")
+
+ def calulate_all(self, recalculate=False):
+ if not self._calculated or recalculate:
+ self.logger.info(f"[{self}] | Recalculating measurements {str(self)}")
+
+ self.find_peaks()
+ self.calculate_wg_params()
+ self._calculated = True
+
+ # ==================================================================================================================
+ # Filtering (old)
+ # ==================================================================================================================
+ def apply_filter(self):
+ if not self._ad2_properties_set:
+ raise Exception("AD2 properties not set. Please set them first.")
+
+ if not self._laser_properties_set:
+ raise Exception("Laser properties not set. Please set them first.")
+
+ (
+ self._filtered_amplitude,
+ first_start, self.start_idx,
+ first_end, self.end_idx,
+ self.signal_end_expected,
+ self.marker_start,
+ self.marker_stop
+ ) = self.filter_signal(self.measured_data, column='measurements')
+
+ self.time_start_point = self.start_idx / self.ad2_sample_rate
+ self.time_end_point = self.end_idx / self.ad2_sample_rate
+ self.time_end_point_expected = self.signal_end_expected / self.ad2_sample_rate
+
+ self._filtered_amplitude = self.assign_wavelength(self._filtered_amplitude, self.wavelength_range[0],
+ self.wavelength_range[1])
+ self.signal_length = len(self._filtered_amplitude)
+
+ # Sanity check if the found length is approximatly the same as the expected length
+ tolerance = 0.025 # 2,5 % tolerance = 0.25 sec
+ if 1 - abs(self.signal_end_expected / self.end_idx) > tolerance:
+ raise Exception(
+ f"The found signal length ({self.signal_end_expected})"
+ f"is not approximatly the same as the expected signal length ({self.end_idx})."
+ )
+
+ return (self._filtered_amplitude,
+ self.start_idx, self.time_start_point,
+ self.end_idx, self.time_end_point,
+ self.signal_end_expected, self.time_end_point_expected
+ )
+
+ def find_index(self, samples_sweep=None, keyword='filtered', threshold=0.0005, reverse_signal=False):
+ rolling_keyword = 'rolling'
+ marker = {
+ 'first_hit': 0,
+ 'steady_mean': 0,
+ 'steady_mean_pt': 0,
+ 'steady_mean_mt': 0,
+ 'steady_min': 0,
+ 'steady_max': 0,
+ 'window_for_mean': [0, 0],
+ 'window_for_search': [0, 0],
+ 'second_hit': 0,
+ }
+ if reverse_signal:
+ self.logger.debug("[FILTER:FIND INDEX] Reversing the signal")
+ samples = samples_sweep[::-1]
+ samples = samples.reset_index(drop=True)
+ else:
+ samples = samples_sweep
+
+ # create a new dataframe
+ # Drop values that have been already marked as invalid
+ samples = samples.dropna()
+
+ # *****************************************************************************************
+ # (1): Extract 200 ms and calculate a mean value. This will be used to find the
+ # approximative start point of the signal.
+ # (1.1) Cut a part that we are sure is steady (e.g. 100 ms after the start up to 300ms)
+ start_idx = int(self.ad2_sample_rate / 10)
+ stop_idx = int((self.ad2_sample_rate / 10) * 3)
+ sample_window_steady = samples[keyword][start_idx:stop_idx]
+ self.logger.debug(
+ "[FILTER:FIND INDEX:1.1] Extract 200 ms and find min and max values. start_idx %s, stop_idx %s" % (
+ start_idx, stop_idx))
+ # (1.2) We now want to approximatly find the part where the signal starts rising or fluctuatig.
+ # This is, where the Signal is greater than our min or max values
+ # Also, store these values as a marker
+ signal_min = float(sample_window_steady.min());
+ marker['steady_min'] = signal_min
+ signal_max = float(sample_window_steady.max());
+ marker['steady_max'] = signal_max
+ self.logger.debug(
+ "[FILTER:FIND INDEX:1.2] Signal processed. signal_min %s, signal_max %s" % (signal_min, signal_max))
+ # (1.3) Extract the first approximate starting position. This is, where the signal exceed
+ # our min or max values. We have found the first approximate starting point.
+ index_first_hit = samples[
+ (samples[rolling_keyword] >= signal_max) | (samples[rolling_keyword] <= signal_min)
+ ].first_valid_index()
+ index_first_hit_abs = samples.index1[index_first_hit]
+ self.logger.info(
+ f"[FILTER:FIND INDEX:1.3] First index found at {index_first_hit_abs / self.ad2_sample_rate} sec. index_first_hit {int(index_first_hit_abs)}/{len(samples)} (rel: {index_first_hit})")
+
+ # *****************************************************************************************
+ # (2) Now we want to calculate a mean that is near our starting point. For this, we go back
+ # 200 ms and calculate the mean of 200 ms. This should yield to a mean value that corresponds
+ # to our signal shortly bevor it starts.
+ value = int(self.ad2_sample_rate / 10)
+ if reverse_signal:
+ start_idx = int(index_first_hit - value * 4)
+ start_idx_abs = int(index_first_hit_abs + value * 2)
+ stop_idx = int(index_first_hit - value * 2)
+ stop_idx_abs = int(index_first_hit_abs + value * 4)
+ else:
+ start_idx = int(index_first_hit - value * 4)
+ start_idx_abs = int(index_first_hit_abs - value * 4)
+ stop_idx = int(index_first_hit - value * 2)
+ stop_idx_abs = int(index_first_hit_abs - value * 2)
+
+ window_for_mean = samples[keyword].loc[start_idx:stop_idx];
+ marker['window_for_mean'] = [start_idx_abs, stop_idx_abs]
+ self.logger.debug(
+ "[FILTER:FIND INDEX:2.1] Extract 200 ms and calculate a new mean value. start_idx %s (rel %s), stop_idx %s (rel: %s). len <%s>"
+ % (start_idx_abs, start_idx,
+ stop_idx_abs, stop_idx, len(window_for_mean)))
+ # (2.1) Calculate the mean value of the 200 ms window
+ signal_mean = float(window_for_mean.mean());
+ marker['steady_mean'] = signal_mean
+ self.logger.debug("[FILTER:FIND INDEX:2.2] Signal processed. signal_mean %s" % (signal_mean))
+
+ # *****************************************************************************************
+ # (3) Since we have found a mean value that hopefully cooresponds to our mean value of the steady
+ # part near our first starting point, we can try to find a more accurate starting point.
+ # Again, this si done by defining a threshold that, if exceeded, mark our new, more accurate starting point.
+ treshold_max = signal_mean * (1 + threshold);
+ marker['steady_mean_pt'] = treshold_max
+ treshold_min = signal_mean * (1 - threshold);
+ marker['steady_mean_mt'] = treshold_min
+ self.logger.debug(
+ "[FILTER:FIND INDEX:3.1] Defining new thresholds for mean: <%s>: treshold_max <%s>, treshold_min <%s>" % (
+ signal_mean, treshold_max, treshold_min))
+
+ # (3.1) New get a window of our expected signal start.
+ # self.print_m("[3]: dataframe 'samples_cut \n%s" % samples)
+ value = int(self.ad2_sample_rate / 10)
+ start_idx = int(index_first_hit - value)
+ start_idx_abs = int(index_first_hit_abs - value)
+ stop_idx = int(index_first_hit + value)
+ stop_idx_abs = int(index_first_hit_abs + value)
+ window_for_search = samples.loc[start_idx:stop_idx];
+ marker['window_for_search'] = [start_idx_abs, stop_idx_abs]
+ self.logger.debug(
+ "[FILTER:FIND INDEX:3.2] Extract 200 ms around the starting point. start_idx %s (rel %s), stop_idx %s (rel: %s). len <%s>"
+ % (start_idx_abs, start_idx, stop_idx_abs, stop_idx, len(window_for_search)))
+ # (3.2) Now we want to find the first point where the signal exceeds our threshold.
+ index_second_hit = window_for_search[
+ (window_for_search[rolling_keyword] > treshold_max) | (window_for_search[rolling_keyword] < treshold_min)
+ ].first_valid_index()
+ if index_second_hit is None:
+ raise Exception("End of Signal not found. index_second_hit %s" % index_second_hit)
+ # (3.3) This window may have not the corrct indices. We need to get the correct one
+ index_second_hit_abs = samples.index1[index_second_hit]
+ self.logger.info(
+ f"[FILTER:FIND INDEX:3.3] Second index found at {index_second_hit_abs / self.ad2_sample_rate} sec. index_second_hit {index_second_hit_abs}/{len(samples)} (rel: {index_second_hit})"
+ )
+
+ if index_second_hit == None:
+ index_second_hit = 0
+ else:
+ index_second_hit = samples.index1[index_second_hit]
+ marker['second_hit'] = index_second_hit
+ index_first_hit = samples.index1[index_first_hit]
+ marker['first_hit'] = index_first_hit
+
+ return index_first_hit_abs, index_second_hit_abs, marker
+
+ def filter_signal(self, measured_amplitude, column='measurements'):
+ self.logger.info("[FILTER] Applying filter to given signal.")
+ # Filter the first second of the measurement
+ measured_amplitude = measured_amplitude.reset_index().rename({'index': 'index1'}, axis='columns')
+ measured_amplitude['filtered'] = measured_amplitude[column]
+ measured_amplitude.loc[:self.ad2_sample_rate] = None
+ # Calculate the moving average
+ measured_amplitude["rolling"] = measured_amplitude['filtered'].rolling(window=1000).mean().shift(
+ -500) # [1000-1:] # 0,01nm
+ self.logger.debug(f"[FILTER] Total Length of given signal {len(measured_amplitude)}")
+
+ first_start, second_start, marker_start = self.find_index(measured_amplitude, column)
+ self.logger.info(f"[FILTER] Starting index found at {second_start} (first hit at {first_start}) ")
+ measured_amplitude['filtered'].loc[:second_start] = None
+
+ # Now we need to find the end of the signal. For this we assume, that the laser movement is "nearly" correct.
+ # The laser waits approximatly 500 ms to move the laser back to it's starting position.
+ index_signal_end_expected = int(second_start + (self.laser_movement_time * self.ad2_sample_rate))
+ self.logger.debug(f"[FILTER] Expected end: {index_signal_end_expected}")
+
+ # We found the expected length, the laser waits for 500 ms until moving back
+ # We want to use this, to get the mean value of the amplitude of this specific wave length
+ # For this we cut the signal 400 ms (= ad2_sample_rate * 0.4) after the expected end
+ measured_amplitude['filtered'].loc[int(index_signal_end_expected + (self.ad2_sample_rate * 0.4)):] = None
+ # Reverse the signal and do the same procedure again
+
+ first_end, second_end, marker_stop = self.find_index(measured_amplitude, column, reverse_signal=True)
+ self.logger.info(f"[FILTER] End index found at {second_end} (first hit at {first_end}).")
+ measured_amplitude['filtered'].loc[second_end:] = None
+
+ measured_amplitude.dropna(inplace=True)
+ # measured_amplitude = measured_amplitude.drop(['index1'], axis = 1)
+ filtered_aplitude = measured_amplitude.filter(['filtered'], axis=1).reset_index(drop=True)
+ self.logger.info(
+ f"[FILTER] AD2 sample rate: {self.ad2_sample_rate} samples/sec. "
+ f"AD2 samples: {self.ad2_total_samples} samples. "
+ f"AD2 measurement duration: {self.ad2_total_measurement_time} sec."
+ )
+ self.logger.info(
+ f"[FILTER] Laser movement ({self.wavelength_range[0]}-{self.wavelength_range[1]}): {self.laser_movement_time} sec. "
+ f"Laser velovity: {self.laser_velocity} m/s. "
+ f"Laser samples expected: {self.laser_samples_expected} samples ({self.laser_samples_expected / self.ad2_sample_rate}) sec."
+ )
+ self.logger.info(
+ f"[FILTER] Signal length {len(self._measured_data)} ({len(self._measured_data) / self.ad2_sample_rate} sec). "
+ f"Start {second_start} ({second_start / self.ad2_sample_rate} sec). "
+ f"End {second_end} ({second_end / self.ad2_sample_rate} sec). "
+ f"Expected: {index_signal_end_expected} ({index_signal_end_expected / self.ad2_sample_rate} sec). "
+ f"Diff {second_end - second_start} ({second_end / self.ad2_sample_rate - second_start / self.ad2_sample_rate} sec)."
+ )
+
+ # self.print_m(samples_sweep_down)
+ return (filtered_aplitude,
+ first_start, second_start,
+ first_end, second_end,
+ index_signal_end_expected,
+ marker_start,
+ marker_stop
+ )
+
+ def assign_wavelength(self, filtered_amplitude: list = None, wavelength_start: float = 850,
+ wavelength_stop: float = 855, start_point: int = None):
+ measurment_points = len(filtered_amplitude)
+ filtered_amplitude['wavelength'] = pd.Series(
+ np.linspace(wavelength_start, wavelength_stop, measurment_points)
+ )
+ # filtered_amplitude.set_index('wavelength',inplace=True)
+ # if start_point is None:
+ # # Get the number of measruement points (should be 50000):
+
+ # #self.print_m(measurment_points)
+
+ # #self.print_m(measured_amplitude)
+ # else:
+ # # We need to assign the first n (up to the start_point) points the l
+ # end_point = start_point + self.laser_samples_expected
+ # filtered_amplitude['wavelength'] = 0
+ # filtered_amplitude.loc[0:start_point-1, 'wavelength'] = wavelength_start
+ # filtered_amplitude.loc[start_point:end_point, 'wavelength'] = pd.Series(
+ # np.linspace(wavelength_start, wavelength_stop, measurment_points)
+ # )
+ # filtered_amplitude.loc[end_point+1:measurment_points-1, 'wavelength'] = wavelength_stop
+
+ return filtered_amplitude
+
+ # ==================================================================================================================
+ # To dicts
+ # ==================================================================================================================
+ def save(self, filename: str = None):
+ self.filename = filename
+ self._save_mat_file(self.filename)
+ #self._save_measurement_parquet(self.measurement_file)
+
+ def _save_measurement_parquet(self, filename: str = None):
+ # Save the measurement file
+
+ if filename is None:
+ filename = self.filename
+ filename = filename.replace('.mat', '.parquet')
+ self.measurement_file = filename
+ self._measured_data.to_parquet(self.measurement_file)
+ self.logger.info(f"Saved measurement file to {self.measurement_file}")
+
+ def to_dict(self) -> dict:
+ return {
+ "laser_properties": self._laser_properties.to_dict(),
+ "ad2_properties": self._ad2_properties.to_dict(),
+ "wafer_properties": self._wafer_properties.to_dict(),
+ "measurement_properties": self._measurement_properties.to_dict(),
+ #"waveguide_properties": self._waveguide_properties.to_dict(),
+ #"measurement_file": str(Path(self.measurement_file).absolute().relative_to(Path(self._mat_filename).parent)),
+ "amplitude": self._measured_data['amplitude'].to_list(),
+ "wavelength": self._measured_data['wavelength'].to_list(),
+ "amplitude_detrended": self._measured_data['detrend'].to_list(),
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "version": "2.0.0"
+ }
+
+ # def flatten(self, parent_key='', sep='.'):
+ # items = []
+ # for key, value in self.to_dict().items():
+ # new_key = f"{parent_key}{sep}{key}" if parent_key else key
+ # if isinstance(value, dict):
+ # items.extend(self.flatten(new_key, sep=sep).items())
+ # else:
+ # items.append((new_key, value))
+ # return dict(items)
+
+ def plot(self):
+
+ downsample = 100
+ filtered_amplitude_down = self._measured_data.copy()
+ filtered_amplitude_down = filtered_amplitude_down[filtered_amplitude_down.reset_index().index % downsample == 0]
+ # measured_amplitude = self.measured_amplitude.copy()
+ # measured_amplitude = measured_amplitude[
+ # measured_amplitude.reset_index().index % downsample == 0] # [240000:300000]
+ # app.run_server(debug=True, port=8050)
+ fig = make_subplots(
+ rows=2, cols=1,
+ subplot_titles=("filtered", "measurement")
+ )
+ fig.append_trace(
+ go.Scatter(
+ x=self._measured_data['wavelength'],
+ y=self._measured_data['amplitude']),
+ row=1, col=1
+ )
+
+ # fig.append_trace(
+ # go.Scatter(x=measured_amplitude.index, y=measured_amplitude['measurements']),
+ # row=2, col=1
+ # )
+
+ fig.add_vrect(x0=self.wl_acc_stop, x1=self.wl_dec_start, row=1, col=1,
+ annotation_text="valid: %s" % self._measurement_length, annotation_position="top left",
+ fillcolor="green", opacity=0.25, line_width=0)
+
+ # fig.update_layout(title_text=str(self._wafer_nr))
+
+ html = fig.to_html(full_html=False, include_plotlyjs='cdn')
+ # html += '</body></html>'
+
+ with open('p_graph.html', 'a') as f:
+ f.write(html)
+
+ return html
+ # fig.show()
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def enable_print(self, enable: bool = True):
+ self.print_enabled = enable
+
+ def print_m(self, *args, **kwargs):
+ if self.print_enabled:
+ self.logger.info(*args, **kwargs)
+
+
+if __name__ == "__main__":
+ app = QApplication()
+
+ # Load a mat file from E:\03_Simulations\03_Simulations\measurements\Ary1 using scipy
+ setup_logging()
+ # filename = r"E:\03_Simulations\03_Simulations\measurements\Ary1\Ary1_2021-03-10_15-00-00.mat"
+ data1 = SingleMeasuredData.from_mat(
+ r"support/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11.mat"
+ )
+ data1.calulate_all()
+ data1._save_mat_file(r'test.mat')
+
+ data2 = SingleMeasuredData.from_mat_v2(r'test.mat')
+ print("done")
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..0877d48ba056628516fba5707bba7668e2e7b358
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py
@@ -0,0 +1,26 @@
+import numpy as np
+import pandas as pd
+
+import mcpy
+
+
+class MPLPlottingHelper:
+
+ @staticmethod
+ def plt_errorbar_mcsamples(plot_widget, x_values: pd.Series, y_values: pd.Series,
+ xlable='Wavelength [nm]', ylable='(nm)'):
+ x = x_values
+ #y_values = y_values
+ y = y_values.apply(lambda row: row.mean)
+ err = y_values.apply(lambda row: row.uncertainty.ustd)
+ plot_widget.ax.clear()
+ # Plot the simple line
+ plot_widget.ax.errorbar(x, y, err)
+ #plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+ #plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+ # Scatter plot of the peaks
+ plot_widget.ax.set_xlabel(xlable)
+ plot_widget.ax.set_ylabel(ylable)
+ plot_widget.ax.grid(True)
+
+ plot_widget.canvas.draw()
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..91a7a2ad1881fec1c6ec3fe9f96447f08c7f4e29
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py
@@ -0,0 +1,70 @@
+from PySide6.QtCore import Qt, QAbstractItemModel, QModelIndex, Signal
+import collections
+
+from PySide6.QtGui import QStandardItem
+from PySide6.QtWidgets import QTreeWidgetItem, QTreeWidget
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataTree(QTreeWidget):
+
+ selected_data_changed = Signal(int)
+
+ def __init__(self, measured_data_list: list[SingleMeasuredData]):
+ super().__init__()
+ self.setHeaderLabels(['Name', 'Xin', 'Yin', 'Xout', 'Yout', 'number'])
+ self.grouped_data = {}
+ self.measured_data_list = measured_data_list
+ for it, data in enumerate(self.measured_data_list):
+ if data.wafer_properties.wafer_number not in self.grouped_data:
+ self.grouped_data[data.wafer_properties.wafer_number] = {}
+ if data.wafer_properties.die_number not in self.grouped_data[data.wafer_properties.wafer_number]:
+ self.grouped_data[data.wafer_properties.wafer_number][data.wafer_properties.die_number] = []
+ self.grouped_data[data.wafer_properties.wafer_number][data.wafer_properties.die_number].append((data, it))
+ self.populate_tree()
+
+
+
+
+ def populate_tree(self):
+
+ for wafer, die_dict in self.grouped_data.items():
+ wafer_item = QTreeWidgetItem([f'Wafer {wafer}'])
+ for die, data_list in die_dict.items():
+ die_item = QTreeWidgetItem([f'Die {die}'])
+ for data in data_list:
+ data, it = data
+ print(it)
+ data_item = QTreeWidgetItem([
+ data.wafer_properties.structure_name,
+ str(data.wafer_properties.structure_x_in),
+ str(data.wafer_properties.structure_y_in),
+ str(data.wafer_properties.structure_x_out),
+ str(data.wafer_properties.structure_y_out),
+ str(it)
+ ])
+ die_item.addChild(data_item)
+ wafer_item.addChild(die_item)
+ self.addTopLevelItem(wafer_item)
+
+ # def selected_data(self):
+ # item = self.currentItem()
+ # if item.parent():
+ # # Return MeasuredData instance for selected die
+ # wafer_item = item.parent()
+ # wafer_num = int(wafer_item.text(0).split()[-1])
+ # die_num = int(item.text(0).split()[-1])
+ # for data in self.measured_data_list:
+ # if data.wafer_number == wafer_num and data.die_number == die_num:
+ # return data
+ # else:
+ # # Return None for selected wafer
+ # return None
+
+ def mouseDoubleClickEvent(self, event):
+
+ item = self.currentItem()
+ print(item)
+ if item:
+ self.selected_data_changed.emit(int(item))
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a685ec39967f90049a0412301649b1e7482c589
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py
@@ -0,0 +1,132 @@
+import logging
+import time
+from dataclasses import dataclass
+from os import listdir
+from os.path import isfile, join
+from pathlib import Path
+from typing import Dict, Any
+
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QProgressDialog, QWidget
+
+import MeasurementEvaluationTool as met
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+from wrappers.QProgressBarWindow import QProgressBarWindow
+
+
+class MeasurementDataLoader(QWidget):
+
+ @staticmethod
+ def glob_files(path, glob):
+ """Recursively glob for files in a directory and subdirectories. Returns a list of paths"""
+ # use list comprehension and rglob
+ return [f for f in Path(path).rglob(glob)]
+
+ @classmethod
+ def from_folder(cls, path, to_database):
+ logging.info(f"Opening path {path}")
+ files = MeasurementDataLoader.glob_files(path, "*.mat") #[Path(f"{path}/{f}").absolute() for f in listdir(path) if isfile(join(path, f)) and ".mat" in f]
+ logging.info(f"Found {len(files)}.")
+
+ mea_list = []
+ for i, f, it in QProgressBarWindow(files):
+ it.print(f"Loading measurement {str(f.name)}")
+
+ #try:
+ #mea_list.append(SingleMeasuredData.from_mat_v2(f))
+ to_database.add_data(SingleMeasuredData.from_mat_v2(f))
+ #except Exception as e:
+ # logging.error(f"Could not load file {f.name}: {e}")
+
+ return cls(mea_list)
+
+ def __init__(self, data: list[SingleMeasuredData]):
+ super().__init__()
+ self._data = data
+ self.logger = logging
+ self._wafers = set()
+ self._dies = set()
+ self._structure_name = set()
+ self._sorted_files = self.classify(self._data)
+ # Now classify
+
+ @property
+ def structure_name(self) -> set[str]:
+ return self._structure_name
+
+ @property
+ def sorted_files(self) -> dict[str, dict[int, dict[Any, list[SingleMeasuredData]]]]:
+ return self._sorted_files
+
+ @property
+ def dies(self) -> set[int]:
+ return self._dies
+
+ @property
+ def wafers(self) -> set[str]:
+ return self._wafers
+
+ def classify(self, measurement_data: list[SingleMeasuredData]):
+ sorted_files = {}
+ for i, measurement, it in QProgressBarWindow(measurement_data):
+ it.print(f"Classifying {measurement}")
+ self.add_to_list(sorted_files, measurement)
+ return sorted_files
+
+ def get_measurement_series(self, wafer_number=None, die_number=None, structure_name=None) -> list[SingleMeasuredData]:
+ if wafer_number is None and len(self._sorted_files.keys()) > 1:
+ raise Exception(f"Wafer Number is ambiguous ({len(self._sorted_files)} possibilities). "
+ f"Please specify the wafer number!")
+ elif wafer_number is None:
+ wafer_number = list(self._sorted_files.keys())[0]
+ print(f"Wafer Number is not ambiguous. Selected wafer number {wafer_number}")
+
+ if die_number is None and len(self._sorted_files[wafer_number]) > 1:
+ raise Exception(f"Die Number is ambiguous ({len(self._sorted_files[wafer_number])} possibilities). "
+ f"Please specify the wafer number!")
+ elif die_number is None:
+ die_number = list(self._sorted_files[wafer_number].keys())[0]
+ print(f"Die Number is not ambiguous. Selected die number {die_number}")
+
+ if structure_name is None and len(self._sorted_files[wafer_number][die_number]) > 1:
+ raise Exception(f"Structure name is ambiguous ({len(self._sorted_files[wafer_number][die_number])} "
+ f"possibilities). Please specify the structure name!")
+ elif structure_name is None:
+ structure_name = list(self._sorted_files[wafer_number][die_number].keys())[0]
+ print(f"Structure name is not ambiguous. Selected structure name {structure_name}")
+
+ return self._sorted_files[wafer_number][die_number][structure_name]
+
+ def get_measurement(self, repetition, wafer_number=None, die_number=None, structure_name=None, ) -> SingleMeasuredData:
+ return self.get_measurement_series(wafer_number, die_number, structure_name)[repetition]
+
+ def add_to_list(self, sorted_files: dict, measurement: SingleMeasuredData):
+ """
+ Adds a measurement to the measurement list
+ """
+ wafer_number = measurement.wafer_properties.wafer_number
+ die_number = measurement.wafer_properties.die_number
+ structure_name = measurement.wafer_properties.structure_name
+
+
+ if (wafer_number in sorted_files and
+ die_number in sorted_files[wafer_number] and
+ structure_name in sorted_files[wafer_number][die_number]):
+ sorted_files[wafer_number][die_number][structure_name].append(measurement)
+ elif (wafer_number in sorted_files and
+ die_number not in sorted_files[wafer_number]):
+ sorted_files[wafer_number][die_number] = {structure_name: [measurement]}
+ elif (wafer_number in sorted_files and
+ die_number in sorted_files[wafer_number] and
+ structure_name not in sorted_files[wafer_number][die_number]):
+ sorted_files[wafer_number][die_number][structure_name] = [measurement]
+ else:
+ sorted_files[wafer_number] = {die_number: {structure_name: [measurement]}}
+ self._wafers.add(wafer_number)
+ self._dies.add(die_number)
+ self._structure_name.add(structure_name)
+
+if __name__ == "__main__":
+ mypath = r'E:\test_measurements'
+ mm_data = MeasurementDataLoader(mypath)
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py
new file mode 100644
index 0000000000000000000000000000000000000000..5810242617a638facf5de65af75929aa2d283235
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py
@@ -0,0 +1,45 @@
+import pandas as pd
+
+class MeasurementDataTables:
+
+ def __init__(self):
+ self._hidden_friendly_name: dict = {}
+ self._hidden_table_plt_functions: dict = {}
+
+ def append(self, new_table: pd.DataFrame, name, friendly_name=None):
+ if friendly_name is None:
+ friendly_name = name
+ self.__setattr__(name, new_table)
+ self._hidden_friendly_name[name] = friendly_name
+
+ return getattr(self, name)
+
+ def add_plot(self, name, plot_function = None):
+ if plot_function:
+ self._hidden_table_plt_functions[f"{name}"] = plot_function
+ return getattr(self, name)
+
+ def update(self, new_table: pd.DataFrame, name):
+ self.__setattr__(name, new_table)
+ return getattr(self, name)
+
+ def to_list(self) -> list[(pd.DataFrame, str, str)]:
+ # write a function that returns all attributes of this class
+ return [
+ (getattr(self, a), str(a), str(self._hidden_friendly_name[a])) for a in dir(self)
+ if not a.startswith('__')
+ and not callable(getattr(self, a))
+ and not '_hidden' in str(a)
+ ]
+
+ def get(self, table_name: str) -> pd.DataFrame:
+ return getattr(self, table_name)
+
+ def get_plot_function(self, name):
+ return self._hidden_table_plt_functions[name]
+
+ def get_plot_function_names(self):
+ return self._hidden_table_plt_functions.keys()
+
+ def plot(self):
+ pass
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac931f73649fc750400125673beb850275b87a58
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py
@@ -0,0 +1,203 @@
+import numpy as np
+from PySide6.QtCore import Signal
+
+import mcpy
+from mcpy import Uncertainty
+
+from generics.GenericProperties import GenericProperties
+
+
+class MPropertiesFindPeaks(GenericProperties):
+ properties_changed = Signal()
+
+ def __init__(self, prominence: float | None, distance: float | None, height: float | None):
+ super().__init__()
+ self.set_properties(prominence, distance, height)
+
+ def set_properties(self, prominence: float | None, distance: float | None, height: float | None):
+ self._prominence = prominence
+ self._distance = distance
+ self._height = height
+ self.properties_changed.emit()
+
+ @property
+ def height(self):
+ return self._height
+
+ @height.setter
+ def height(self, value):
+ self._height = value
+ self.properties_changed.emit()
+
+ @property
+ def prominence(self):
+ return self._prominence
+
+ @prominence.setter
+ def prominence(self, value):
+ self._prominence = value
+ self.properties_changed.emit()
+
+ @property
+ def distance(self):
+ return self._distance
+
+ @distance.setter
+ def distance(self, value):
+ self._distance = value
+ self.properties_changed.emit()
+
+ def fields(self) -> dict:
+ return {
+ 'prominence': self.prominence if self.prominence is not None else np.NaN,
+ 'distance': self.distance if self.prominence is not None else np.NaN,
+ 'height': self.height if self.height is not None else np.NaN,
+ }
+
+ def __str__(self):
+ return f"h: {self.height} - d: {self.distance} - p: {self.prominence}"
+
+
+class WaveguideProperties(GenericProperties):
+ def __init__(self, length: Uncertainty, width: Uncertainty, height: Uncertainty):
+ super().__init__()
+ self._length: Uncertainty = length
+ self._width: Uncertainty = width
+ self._height: Uncertainty = height
+
+ @property
+ def height(self):
+ return self._height
+
+ @height.setter
+ def height(self, value):
+ self._height = value
+
+ @property
+ def length(self):
+ return self._length
+
+ @length.setter
+ def length(self, value):
+ self._length = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+ def fields(self) -> dict:
+ return {
+ 'width': self.width.to_tuple(),
+ 'length': self.length.to_tuple(),
+ 'height': self.height.to_tuple(),
+ }
+
+class WaveguidePropertiesMZI(WaveguideProperties):
+ def __init__(self, length1: Uncertainty, length2: Uncertainty, width: Uncertainty, height: Uncertainty):
+
+ self._arm1 = WaveguideProperties(length1, width, height)
+ self._arm2 = WaveguideProperties(length2, width, height)
+ super().__init__(mcpy.Uncertainty(float(self._arm1.length) - float(self._arm2.length)), width, height)
+
+ @property
+ def length_diff(self):
+ return self._length_diff
+
+ @length_diff.setter
+ def length_diff(self, value):
+ self._length_diff = value
+
+ @property
+ def arm1(self):
+ return self._arm1
+
+ @arm1.setter
+ def arm1(self, value):
+ self._arm1 = value
+
+ @property
+ def arm2(self):
+ return self._arm2
+
+ @arm2.setter
+ def arm2(self, value):
+ self._arm2 = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+ def fields(self) -> dict:
+ return {
+ 'width': self.width,
+ 'length': self.length,
+ 'arm1': self.arm1,
+ 'arm2': self.arm2
+ }
+
+class WaveguidePropertiesMRR(WaveguideProperties):
+ def __init__(self, length, width: float, radius, gap: float):
+ super().__init__()
+ super().__init__(length, width)
+ self._radius = radius
+ self._gap = gap
+
+ @property
+ def length_diff(self):
+ return self._length_diff
+
+ @length_diff.setter
+ def length_diff(self, value):
+ self._length_diff = value
+
+ @property
+ def arm1(self):
+ return self._arm1
+
+ @arm1.setter
+ def arm1(self, value):
+ self._arm1 = value
+
+ @property
+ def arm2(self):
+ return self._arm2
+
+ @arm2.setter
+ def arm2(self, value):
+ self._arm2 = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+
+class MeasurementProperties(GenericProperties):
+ def __init__(self, find_peaks_properties: MPropertiesFindPeaks):
+ super().__init__()
+ self._find_peaks = find_peaks_properties
+
+ @property
+ def find_peaks(self):
+ return self._find_peaks
+
+ @find_peaks.setter
+ def find_peaks(self, value):
+ self._find_peaks = value
+
+ def fields(self) -> dict:
+ return {
+ 'find_peaks': self.find_peaks.fields(),
+ 'test': 1
+ }
diff --git a/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py b/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..231b75c81572eb64175920632ffaeb01129645e7
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py
@@ -0,0 +1,79 @@
+import pandas as pd
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class AD2CaptDeviceProperties(GenericProperties):
+
+ def __init__(self, samples_lost: float, samples_corrupted: float,
+ acquisition_rate: float, n_samples: int,
+ measurement_time: float):
+ super().__init__()
+ # Laser properties
+ self._samples_lost: float = self.to_float(samples_lost)
+ self._samples_currputed: float = self.to_float(samples_corrupted)
+ self._sample_rate: float = self.to_float(acquisition_rate)
+ self._n_samples: int = self.to_int(n_samples)
+ self._measurement_time: float = self.to_float(measurement_time)
+
+ @property
+ def samples_lost(self):
+ return self._samples_lost
+
+ @samples_lost.setter
+ def samples_lost(self, value):
+ self._samples_lost = value
+
+ @property
+ def samples_corrupted(self):
+ return self._samples_currputed
+
+ @samples_corrupted.setter
+ def samples_corrupted(self, value):
+ self._samples_currputed = value
+
+ @property
+ def n_samples(self):
+ return self._n_samples
+
+ @n_samples.setter
+ def n_samples(self, value):
+ self._n_samples = value
+
+ @property
+ def measurement_time(self):
+ return self._measurement_time
+
+ @measurement_time.setter
+ def measurement_time(self, value):
+ self._measurement_time = value
+
+ @property
+ def sample_rate(self):
+ return self._sample_rate
+
+ @sample_rate.setter
+ def sample_rate(self, value):
+ self._sample_rate = value
+
+
+ def to_dict(self) -> dict:
+ return {
+ 'samples_lost': self.samples_lost,
+ 'samples_corrupted': self.samples_corrupted,
+ 'n_samples': self.n_samples,
+ 'measurement_time': self.measurement_time,
+ 'acquisition_rate': self.sample_rate
+ }
+
+ @classmethod
+ def from_dict(cls, mat_struct):
+ return cls(
+ samples_lost=mat_struct['samples_lost'],
+ samples_corrupted=mat_struct['samples_corrupted'],
+ acquisition_rate=mat_struct['acquisition_rate'],
+ n_samples=mat_struct['n_samples'],
+ measurement_time=mat_struct['measurement_time']
+ )
+
+
diff --git a/src/FlexSensor/MeasurementData/Properties/GenericProperties.py b/src/FlexSensor/MeasurementData/Properties/GenericProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..a112641f7fc64c3c074917318df0c7cf0fb0e047
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/GenericProperties.py
@@ -0,0 +1,49 @@
+import pandas as pd
+from PySide6.QtCore import QObject
+from numpy import ndarray
+
+class GenericProperties(QObject,):
+
+ def __init__(self):
+
+ super().__init__()
+
+ def to_str(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return self.to_str(value[0])
+ else:
+ return str(value)
+
+ def to_int(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return self.to_int(value[0])
+ else:
+ return int(value)
+
+ def to_float(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return self.to_float(value[0])
+ else:
+ return float(value)
+
+ def to_tuple(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return tuple(value[0])
+ else:
+ return tuple(value)
+
+ def to_dict(self) -> dict:
+ raise NotImplementedError
+
+ @classmethod
+ def from_dict(self, data: dict):
+ raise NotImplementedError
+
+ def to_sql(self, engine):
+ self.metadata.create_all(engine)
+ "Create a relational table in the database with the given engine"
+ with Session(engine) as session:
+ session.add(self)
+ session.commit()
+ # df = pd.DataFrame(self.to_dict())
+ # df.to_sql(table_name, engine, if_exists='append', index=False)
diff --git a/src/FlexSensor/MeasurementData/Properties/LaserProperties.py b/src/FlexSensor/MeasurementData/Properties/LaserProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b2947cbe02dac59c28b14a3e363be2686c51ab8
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/LaserProperties.py
@@ -0,0 +1,68 @@
+import sys
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+import mcpy
+
+sys.path.append('../mcpy/mcpy')
+import mcpy
+
+
+class LaserProperties(GenericProperties):
+
+ def __init__(self, acceleration: mcpy.Uncertainty, deceleration: mcpy.Uncertainty, velocity: mcpy.Uncertainty,
+ wavelength_range: tuple):
+ super().__init__()
+ # Laser properties
+ self._acceleration: mcpy.Uncertainty = acceleration
+ self._deceleration: mcpy.Uncertainty = deceleration
+ self._velocity: mcpy.Uncertainty = velocity
+ self._wavelength_range: list | tuple = wavelength_range
+
+ @property
+ def deceleration(self) -> mcpy.Uncertainty:
+ return self._deceleration
+
+ @deceleration.setter
+ def deceleration(self, value):
+ self._deceleration = value
+
+ @property
+ def velocity(self) -> mcpy.Uncertainty:
+ return self._velocity
+
+ @velocity.setter
+ def velocity(self, value):
+ self._velocity = value
+
+ @property
+ def wavelength_range(self) -> mcpy.Uncertainty:
+ return self._wavelength_range
+
+ @wavelength_range.setter
+ def wavelength_range(self, value):
+ self._wavelength_range = value
+
+ @property
+ def acceleration(self) -> mcpy.Uncertainty:
+ return self._acceleration
+
+ @acceleration.setter
+ def acceleration(self, value):
+ self._acceleration = value
+
+ def to_dict(self) -> dict:
+ return {
+ 'deceleration': 1.997,#float(self.deceleration),
+ 'velocity': 1.002,#float(self.velocity),
+ 'wavelength_range': [840, 860], # .to_tuple(),
+ 'acceleration': 1.997 #float(self.acceleration)
+ }
+
+ @classmethod
+ def from_dict(cls, d):
+ return cls(
+ acceleration=mcpy.Uncertainty.from_dict(d['acceleration']),
+ deceleration=mcpy.Uncertainty.from_dict(d['deceleration']),
+ velocity=mcpy.Uncertainty.from_dict(d['deceleration']),
+ wavelength_range=()
+ )
diff --git a/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py b/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..12d544401fb913e439ae3a36cd30743c0472ca0c
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py
@@ -0,0 +1,247 @@
+import numpy as np
+from PySide6.QtCore import Signal
+
+import mcpy
+from mcpy import Uncertainty, MCSamples
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class MPropertiesFindPeaks(GenericProperties):
+
+
+ properties_changed = Signal()
+
+ def __init__(self, prominence: float | None, distance: float | None, height: float | None):
+ super().__init__()
+ self.set_properties(prominence, distance, height)
+
+ def set_properties(self, prominence: float | None, distance: float | None, height: float | None):
+ self._prominence = prominence
+ self._distance = distance
+ self._height = height
+ self.properties_changed.emit()
+
+ @property
+ def height(self):
+ return self._height
+
+ @height.setter
+ def height(self, value):
+ self._height = value
+ self.properties_changed.emit()
+
+ @property
+ def prominence(self):
+ return self._prominence
+
+ @prominence.setter
+ def prominence(self, value):
+ self._prominence = value
+ self.properties_changed.emit()
+
+ @property
+ def distance(self):
+ return self._distance
+
+ @distance.setter
+ def distance(self, value):
+ self._distance = value
+ self.properties_changed.emit()
+
+ def to_dict(self) -> dict:
+ return {
+ 'prominence': self.prominence if self.prominence is not None else np.NaN,
+ 'distance': self.distance if self.prominence is not None else np.NaN,
+ 'height': self.height if self.height is not None else np.NaN,
+ }
+
+ @classmethod
+ def from_dict(cls, data: dict):
+ return cls(
+ data['prominence'] if not np.isnan(data['prominence']) else None,
+ data['distance'] if not np.isnan(data['distance']) else None,
+ data['height'] if not np.isnan(data['height']) else None
+ )
+
+ def __str__(self):
+ return f"h: {self.height} - d: {self.distance} - p: {self.prominence}"
+
+
+class WaveguideProperties(GenericProperties):
+
+ def __init__(self, length: Uncertainty, width: Uncertainty, height: Uncertainty):
+ super().__init__()
+ self._length: Uncertainty = length
+ self._width: Uncertainty = width
+ self._height: Uncertainty = height
+
+ def group_index(self, lam0: MCSamples, FSR: MCSamples):
+ return (lam0 ** 2) / (FSR * self._length)
+
+ @property
+ def height(self):
+ return self._height
+
+ @height.setter
+ def height(self, value):
+ self._height = value
+
+ @property
+ def length(self):
+ return self._length
+
+ @length.setter
+ def length(self, value):
+ self._length = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+ def to_dict(self) -> dict:
+ return {
+ 'width': self.width.to_dict(),
+ 'length': self.length.to_dict(),
+ 'height': self.height.to_dict(),
+ }
+
+ @classmethod
+ def from_dict(cls, data: dict):
+ return cls(
+ Uncertainty.from_dict(data['length']),
+ Uncertainty.from_dict(data['width']),
+ Uncertainty.from_dict(data['height'])
+ )
+
+
+class WaveguidePropertiesMZI(WaveguideProperties):
+
+
+ def __init__(self, length1: Uncertainty, length2: Uncertainty, width: Uncertainty, height: Uncertainty):
+ self._arm1 = WaveguideProperties(length1, width, height)
+ self._arm2 = WaveguideProperties(length2, width, height)
+ super().__init__(mcpy.Uncertainty(float(self._arm1.length) - float(self._arm2.length)), width, height)
+
+ def group_index(self, lam0: MCSamples, FSR: MCSamples):
+ return (lam0 ** 2) / (FSR * (self.arm2.length.rand(lam0.N) -
+ self.arm1.length.rand(lam0.N)))
+
+ @property
+ def length_diff(self):
+ return self._length_diff
+
+ @length_diff.setter
+ def length_diff(self, value):
+ self._length_diff = value
+
+ @property
+ def arm1(self):
+ return self._arm1
+
+ @arm1.setter
+ def arm1(self, value):
+ self._arm1 = value
+
+ @property
+ def arm2(self):
+ return self._arm2
+
+ @arm2.setter
+ def arm2(self, value):
+ self._arm2 = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+ def to_dict(self) -> dict:
+ return {
+ 'width': self.width.to_dict(),
+ 'length': self.length.to_dict(),
+ 'arm1': self.arm1.to_dict(),
+ 'arm2': self.arm2.to_dict(),
+ 'height': self.height.to_dict(),
+ }
+
+ @classmethod
+ def from_dict(cls, data: dict):
+ return cls(
+ length1=mcpy.Uncertainty.from_dict(data['arm1']['length']),
+ length2=Uncertainty.from_dict(data['arm2']['length']),
+ width=Uncertainty.from_dict(data['width']),
+ height=Uncertainty.from_dict(data['height'])
+ )
+
+
+class WaveguidePropertiesMRR(WaveguideProperties):
+ def __init__(self, length, width: float, radius, gap: float):
+ super().__init__()
+ super().__init__(length, width)
+ self._radius = radius
+ self._gap = gap
+
+ @property
+ def length_diff(self):
+ return self._length_diff
+
+ @length_diff.setter
+ def length_diff(self, value):
+ self._length_diff = value
+
+ @property
+ def arm1(self):
+ return self._arm1
+
+ @arm1.setter
+ def arm1(self, value):
+ self._arm1 = value
+
+ @property
+ def arm2(self):
+ return self._arm2
+
+ @arm2.setter
+ def arm2(self, value):
+ self._arm2 = value
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, value):
+ self._width = value
+
+
+class MeasurementProperties(GenericProperties):
+ def __init__(self, find_peaks_properties: MPropertiesFindPeaks):
+ super().__init__()
+ self._find_peaks = find_peaks_properties
+
+ @property
+ def find_peaks(self):
+ return self._find_peaks
+
+ @find_peaks.setter
+ def find_peaks(self, value):
+ self._find_peaks = value
+
+ def to_dict(self) -> dict:
+ return {
+ 'find_peaks': self.find_peaks.to_dict(),
+ }
+
+ @classmethod
+ def from_dict(cls, d: dict):
+ return cls(
+ find_peaks_properties=MPropertiesFindPeaks.from_dict(d['find_peaks'])
+ )
diff --git a/src/FlexSensor/MeasurementData/Properties/WaferProperties.py b/src/FlexSensor/MeasurementData/Properties/WaferProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..546de51e3e227faafd3c2a2b8e9f750eb8a95135
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/WaferProperties.py
@@ -0,0 +1,108 @@
+
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class WaferProperties(GenericProperties):
+
+
+ def __init__(self,
+ wafer_number: str, structure_name: str,
+ die_nr: int, chuck_col: int, chuck_row: int,
+ structure_in: tuple, structure_out: tuple,
+ repetitions: int
+ ):
+ super().__init__()
+ self._structure_name = self.to_str(structure_name)
+ self._wafer_number = self.to_str(wafer_number)
+
+ self._die_number = self.to_int(die_nr)
+ self._chuck_col = self.to_int(chuck_col)
+ self._chuck_row = self.to_int(chuck_row)
+
+ self._structure_in = self.to_tuple(structure_in)
+ self._structure_out = self.to_tuple(structure_out)
+ self._structure_x_in = int(self._structure_in[0])
+ self._structure_y_in = int(self._structure_in[1])
+ self._structure_x_out = int(self._structure_out[0])
+ self._structure_y_out = int(self._structure_out[1])
+
+ self._repetitions: int = self.to_int(repetitions)
+
+ @property
+ def repetition(self):
+ return int(self._repetitions)
+
+ @property
+ def chuck_col(self):
+ return int(self._chuck_col)
+
+ @property
+ def chuck_row(self):
+ return int(self._chuck_row)
+
+ @property
+ def wafer_number(self) -> str:
+ return str(self._wafer_number)
+
+ @property
+ def structure_x_in(self):
+ return int(self._structure_x_in)
+
+ @property
+ def structure_y_in(self):
+ return int(self._structure_y_in)
+
+ @property
+ def structure_x_out(self):
+ return int(self._structure_x_out)
+
+ @property
+ def structure_name(self):
+ return str(self._structure_name)
+
+ @property
+ def die_number(self) -> int:
+ return int(self._die_number)
+
+ @property
+ def structure_y_out(self):
+ return int(self._structure_y_out)
+
+ @property
+ def structure_in(self):
+ return tuple(self._structure_in)
+
+ @property
+ def structure_out(self):
+ return tuple(self._structure_out)
+
+ @property
+ def chuck_row(self):
+ return int(self._chuck_row)
+
+ def to_dict(self) -> dict:
+ return {
+ 'wafer_number': self.wafer_number,
+ 'die_number': self.die_number,
+ 'structure_name': self.structure_name,
+ 'repetition': self.repetition,
+ 'structure_in': self.structure_in,
+ 'structure_out': self.structure_out,
+ 'chuck_col': self.chuck_col,
+ 'chuck_row': self.chuck_row
+
+ }
+
+ @classmethod
+ def from_dict(cls, d: dict):
+ return cls(
+ wafer_number=d['wafer_number'],
+ die_nr=d['die_number'],
+ structure_name=d['structure_name'],
+ repetitions=d['repetition'],
+ structure_in=d['structure_in'],
+ structure_out=d['structure_out'],
+ chuck_col=d['chuck_col'],
+ chuck_row=d['chuck_row']
+ )
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/__init__.py b/src/FlexSensor/MeasurementData/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m b/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m
new file mode 100644
index 0000000000000000000000000000000000000000..a9d12a2e008e05484775aafe784af9ec0083869d
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m
@@ -0,0 +1 @@
+load('testfiles/load_all.m');data = readcsv('None');
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/load_all.m b/src/FlexSensor/MeasurementData/tests/tmp/load_all.m
new file mode 100644
index 0000000000000000000000000000000000000000..284260549b90723aa2dbb4c94100899496cae33b
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/tests/tmp/load_all.m
@@ -0,0 +1 @@
+load('tmp/load_all.m');data = readcsv('None');
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat b/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat
new file mode 100644
index 0000000000000000000000000000000000000000..473d79a9bb81268364028c942632ce50b113c153
Binary files /dev/null and b/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat differ
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat b/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat
new file mode 100644
index 0000000000000000000000000000000000000000..8203321366c3ffb60ee771c18c3590fd34b3b80e
Binary files /dev/null and b/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat differ
diff --git a/src/FlexSensor/MeasurementEvaluation/__init__.py b/src/FlexSensor/MeasurementEvaluation/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py b/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py
new file mode 100644
index 0000000000000000000000000000000000000000..73305f7e40f55557c8e46576c25139ebb344bfe7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py
@@ -0,0 +1,60 @@
+import logging
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from MeasurementEvaluation.model.MeasurementDataModel import MeasurementDataModel
+
+
+class MeasurementDataController:
+
+ def __init__(self, model: MeasurementDataModel, path):
+ self.logger = logging.getLogger("MeasurementDataController")
+ self._model = model
+
+ self._model.path = path
+ self._md_loader = MeasurementDataLoader.from_folder(self._model.path)
+
+ self._model.selected_measurements = []
+ self._model.measurement_list = self._md_loader.sorted_files
+
+
+ @property
+ def consolidated_measurements(self):
+ return self._consolidated_measurements
+
+ @consolidated_measurements.setter
+ def consolidated_measurements(self, value):
+ self._consolidated_measurements = value
+
+ @property
+ def all_measurements(self):
+ return self._model.measurement_list
+
+ @property
+ def list_of_measurements(self) -> list[SingleMeasuredData]:
+ return self._model.selected_measurements
+
+ @property
+ def selected_measurement(self) -> SingleMeasuredData:
+ return self._model.display_measurement
+
+ def select_measurement(self, selected_measurement: MeasuredData):
+ self._model.display_measurement = selected_measurement
+
+ def consolidate_measurements(self, measurement_selection):
+ self._model.consolidated_measurement = MultiMeasuredData(measurement_selection)
+ self._model.selected_measurements = measurement_selection
+ self.select_measurement(self._model.consolidated_measurement)
+
+ def recalculate_measurements(self, measurement_selection):
+ self.logger.info("Recalculating all measurements")
+ for md in measurement_selection:
+ md.calulate_all()
+
+ def load_from_folder(self):
+ raise NotImplementedError
+
+ def add_measurement(self):
+ pass
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py b/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e55e292e0343f0eb2bda1a50bca42cff13b8950
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py
@@ -0,0 +1,85 @@
+from pathlib import Path
+
+from PySide6.QtCore import Signal, QObject
+
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataSignals(QObject):
+ path_changed = Signal(Path)
+
+ list_of_measurements_changed = Signal(list)
+ all_measurements_changed = Signal(dict)
+
+ num_of_measurements = Signal(int)
+ selected_measurement_changed = Signal(SingleMeasuredData)
+ consolidated_measurements_changed = Signal(MultiMeasuredData)
+
+
+class MeasurementDataModel:
+ def __init__(self):
+ self.signals = MeasuredDataSignals()
+
+ self._path: Path = None
+ self._measurement_list: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = None
+
+ self._consolidated_measurement: MultiMeasuredData = None
+ self._display_measurement: SingleMeasuredData = None
+ self._selected_measurements: list[SingleMeasuredData] = []
+
+ self._num_of_measurements: int = 0
+
+ @property
+ def consolidated_measurement(self):
+ return self._consolidated_measurement
+
+ @consolidated_measurement.setter
+ def consolidated_measurement(self, value):
+ self._consolidated_measurement = value
+
+ @property
+ def path(self):
+ return self._path
+
+ @path.setter
+ def path(self, value):
+ self._path = value
+ self.signals.path_changed.emit(self.path)
+
+ @property
+ def measurement_list(self) -> dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]:
+ return self._measurement_list
+
+ @measurement_list.setter
+ def measurement_list(self, value: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]) -> None:
+ self._measurement_list = value
+ self.signals.all_measurements_changed.emit(self.measurement_list)
+
+ @property
+ def selected_measurements(self) -> list[SingleMeasuredData]:
+ return self._selected_measurements
+
+ @selected_measurements.setter
+ def selected_measurements(self, value: list[SingleMeasuredData]) -> None:
+ self._selected_measurements = value
+ self.num_of_measurements = len(self.selected_measurements)
+ self.signals.list_of_measurements_changed.emit(self.selected_measurements)
+
+ @property
+ def num_of_measurements(self) -> int:
+ return self._num_of_measurements
+
+ @num_of_measurements.setter
+ def num_of_measurements(self, value: list[SingleMeasuredData]) -> None:
+ self._num_of_measurements = value
+ self.signals.num_of_measurements.emit(self.num_of_measurements)
+
+ @property
+ def display_measurement(self) -> SingleMeasuredData:
+ return self._display_measurement
+
+ @display_measurement.setter
+ def display_measurement(self, value: SingleMeasuredData) -> None:
+ self._display_measurement = value
+ self.signals.selected_measurement_changed.emit(self.display_measurement)
diff --git a/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py b/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c199832356abb7b39b9e08cf59a4ab742535720
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py
@@ -0,0 +1,30 @@
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QMenu
+
+
+class PandasTableModel(QAbstractTableModel):
+ def __init__(self, df):
+ super().__init__()
+ self.df = df
+
+ def rowCount(self, parent=None):
+ return self.df.shape[0]
+
+ def columnCount(self, parent=None):
+
+ return self.df.shape[1]
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row()
+ col = index.column()
+ return str(self.df.iloc[row, col])
+ return None
+
+ def headerData(self, section, orientation, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ if orientation == Qt.Horizontal:
+ return str(self.df.columns[section])
+ elif orientation == Qt.Vertical:
+ return str(self.df.index[section])
+ return None
diff --git a/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py b/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py
new file mode 100644
index 0000000000000000000000000000000000000000..940431b847253567a469bca7de5931bc8539e0d7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py
@@ -0,0 +1,159 @@
+import sys
+
+import numpy as np
+from PySide6.QtWidgets import QApplication, QWidget, QTableView, \
+ QComboBox, QPushButton, QGridLayout
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluation.controller.MeasurementDataController import MeasurementDataController
+from MeasurementEvaluation.model.MeasurementDataModel import MeasurementDataModel
+from MeasurementEvaluation.model.PandasTableModel import PandasTableModel
+from MeasurementData.MeasuredData.SupportClasses.MatplotlibPlottingHelpers import MPLPlottingHelper
+from MeasurementEvaluation.view.ParameterAdjustmentView import ParameterAdjustmentWindow
+from MeasurementEvaluation.view.widgets.MeasurementSelectionWidget import MeasurementSelectionWidget
+from MeasurementEvaluation.view.widgets.PlotViewWidget import PlotViewWidget
+from generics.logger import setup_logging
+
+
+class MeasurementDataView(QWidget):
+ def __init__(self, model: MeasurementDataModel, controller: MeasurementDataController):
+ super().__init__()
+ self._model = model
+ self._controller = controller
+ self.layout = QGridLayout()
+
+ self._model.signals.selected_measurement_changed.connect(self._on_selected_measurement_changed)
+
+ self._init_ui()
+
+ def _init_ui(self):
+ self.find_peaks_view = ParameterAdjustmentWindow()
+
+ # Add a view for selecting the measurement
+ self.measurement_selection = MeasurementSelectionWidget(self._controller.all_measurements)
+
+ self.measurement_selection.signals.open_find_peaks_window.connect(self._on_adapt_parameters_clicked)
+ self.measurement_selection.signals.on_consolidate_measurement_clicked.connect(self._on_consolidate_clicked)
+ self.measurement_selection.signals.on_recalculation_clicked.connect(self._on_recalculate_clicked)
+ self.measurement_selection.signals.on_show_item_click.connect(self._on_show_item_clicked)
+
+ # self.measurement_selection.selection.selected_data_changed.connect(self._on_selection_changed)
+ self.layout.addWidget(self.measurement_selection, 0, 0, 2, 1)
+
+ self.plot_widget = PlotViewWidget() # pg.PlotWidget()
+ self.layout.addWidget(self.plot_widget, 0, 1, 1, 1)
+
+ # Display the data in an QTableWidget
+ self.table_view = QTableView()
+ self.layout.addWidget(self.table_view, 1, 1, 1, 1)
+
+ # Add a dropdown
+ self.btn_consolidate = QPushButton('Consolidate all')
+ self.btn_consolidate.clicked.connect(self._on_consolidate_clicked)
+ self.layout.addWidget(self.btn_consolidate, 2, 0, 1, 1)
+
+ self.dd_select_measurement_table = QComboBox()
+ self.dd_select_measurement_table.currentIndexChanged.connect(self._on_data_table_changed)
+ self.layout.addWidget(self.dd_select_measurement_table, 2, 1, 1, 1)
+
+ self.setLayout(self.layout)
+ # self._controller.select_measurement(0)
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def _on_show_item_clicked(self, measurement_selection: SingleMeasuredData):
+ measurement_selection.calulate_all()
+ self._controller.select_measurement(measurement_selection)
+
+ def _on_consolidate_clicked(self, measurement_selection):
+ self._controller.recalculate_measurements(measurement_selection)
+ self._controller.consolidate_measurements(measurement_selection)
+ # self._current_measurement = self._controller.consolidated_measurements
+
+ def _on_recalculate_clicked(self, measurement_selection):
+ self._controller.recalculate_measurements(measurement_selection)
+
+ def _on_adapt_parameters_clicked(self, measurement_selection):
+ self.find_peaks_view.measured_data_list = measurement_selection
+ self.find_peaks_view.show()
+
+ def _on_selection_changed(self, it: int):
+ # self._controller.select_measurement(it)
+ self.measurement_selection.set_selected_data(self._controller.selected_measurement)
+
+ def _on_data_table_changed(self, idx):
+ table_name = self.dd_select_measurement_table.itemData(idx)
+ print(f"{table_name} - {type(table_name)}")
+ # print(self._current_measurement.tables.get(table_name))
+ table = self._controller.selected_measurement.tables.get(table_name)
+ # Define plt function here
+ self.table_view_model = PandasTableModel(table)
+ self.table_view.setModel(self.table_view_model)
+
+ # This will be removed later and is only for quick and dirty hardcoded plotting
+ if table_name == "_measured_data":
+ pass
+ # self._plot_measurement_table(table_name)
+ elif table_name == "_wg_param":
+ self._controller.selected_measurement.tables.get_plot_function('ng (FSR)')(self.plot_widget)
+
+ #self._plot_ng_table(table_name)
+
+ def _on_selected_measurement_changed(self, measurement: MeasurementData):
+ self._current_measurement = measurement
+ # Populate the measurement ment selection
+ self.dd_select_measurement_table.clear()
+ for table in measurement.tables.to_list():
+ # id in table -> table[2] = 'Friendly name', table[1] = 'table name'
+ self.dd_select_measurement_table.addItem(table[2], table[1])
+ #self.dd_select_measurement_table.addItem( measurement.tables.to_list()[2][2], table[2][1])
+
+ # ==================================================================================================================
+ #
+ # =============================================================================================================
+ def _plot_measurement_table(self, table_name, x_axis="wavelength", y_axis="detrend"):
+ self.plot_widget.ax.clear()
+ data = self._controller.selected_measurement.tables.get(table_name)
+ self.plot_widget.ax.plot(data[x_axis], data[y_axis], 'b-')[0]
+ self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+ self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+ # Scatter plot of the peaks
+ df_peaks = self._current_measurement.peaks
+ self.plot_widget.ax.scatter(df_peaks[x_axis], df_peaks[y_axis], marker='x', color='red')
+ self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+ self.plot_widget.ax.set_ylabel('Amplitude [1]')
+ self.plot_widget.ax.set_title('Measured data')
+ self.plot_widget.ax.grid(True)
+ self.plot_widget.ax.legend([y_axis, 'Peaks'])
+
+ self.plot_widget.canvas.draw()
+
+ def _plot_ng_table(self, table_name, x_axis="lambda", y_axis="FSR"):
+ self.plot_widget.ax.clear()
+ data = self._controller.selected_measurement.tables.get(table_name)
+ self.plot_widget.ax.plot(data[x_axis], data[y_axis])
+ self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+ self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+ # Scatter plot of the peaks
+ self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+ self.plot_widget.ax.set_ylabel(f'{y_axis} [1]')
+ self.plot_widget.ax.grid(True)
+
+ self.plot_widget.canvas.draw()
+
+
+if __name__ == "__main__":
+ app = QApplication()
+ setup_logging()
+
+ mypath = (
+ r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement')
+
+ model = MeasurementDataModel()
+ controller = MeasurementDataController(model, mypath)
+ window = MeasurementDataView(model, controller)
+ window.show()
+
+ sys.exit(app.exec())
diff --git a/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py b/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef897e8942be25b5fd3f0eabbf37ca931e3071b7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py
@@ -0,0 +1,167 @@
+from PySide6.QtWidgets import QLineEdit, QPushButton
+from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
+ QWidget, QLabel, QSlider, QComboBox)
+from PySide6.QtCore import Qt, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+import pyqtgraph as pg
+
+from MeasurementEvaluation.view.widgets.MeasuredDataInformationWidget import MeasuredDataInformationWidget
+
+
+class ParameterAdjustmentWindow(QMainWindow):
+
+ def __init__(self):
+ super().__init__()
+ self._current_measurement = None
+ self._measured_data_list = None
+
+ self.setWindowTitle("Find Peaks Demo")
+
+ layout = QVBoxLayout()
+ self.measurement_selection = QComboBox()
+ layout.addWidget(self.measurement_selection)
+
+ self._find_peaks_wdg = ParameterAdjustmentWidget()
+ self._find_peaks_wdg.apply_fp_param_to_all_clicked.connect(self._on_apply_to_all)
+
+ layout.addWidget(self._find_peaks_wdg)
+ widget = QWidget()
+ widget.setLayout(layout)
+
+ self.setCentralWidget(widget)
+
+ @property
+ def current_measurement(self):
+ return self._current_measurement
+
+ @current_measurement.setter
+ def current_measurement(self, value):
+ self._current_measurement = value
+ self._find_peaks_wdg.measured_data = self.current_measurement
+
+ @property
+ def measured_data_list(self):
+ return self._measured_data_list
+
+ @measured_data_list.setter
+ def measured_data_list(self, value):
+ self._measured_data_list = value
+ self.current_measurement = self._measured_data_list[0]
+ for i, md in enumerate(self._measured_data_list):
+ self.measurement_selection.addItem(str(md))
+ self.measurement_selection.currentIndexChanged.connect(self._on_measurement_changed)
+
+ def _on_apply_to_all(self, prominence, distance):
+ for md in self._measured_data_list:
+ md.measurement_properties.find_peaks.set_properties(prominence,distance,None)
+
+ def _on_measurement_changed(self, index):
+ self.current_measurement = self._measured_data_list[index]
+
+
+class ParameterAdjustmentWidget(QWidget):
+ apply_fp_param_to_all_clicked = Signal(float, float)
+
+ def __init__(self):
+ super().__init__()
+ self._measured_data: SingleMeasuredData = None
+ # Create the numpy array
+ self._init_ui()
+
+ @property
+ def measured_data(self):
+ return self._measured_data
+
+ @measured_data.setter
+ def measured_data(self, value):
+ self._measured_data = value
+ self.x = self._measured_data.tables.get('_measured_data')['wavelength']
+ self.y = self._measured_data.tables.get('_measured_data')['amplitude']
+ self.prom_slider.setValue(
+ self._measured_data.measurement_properties.find_peaks.prominence * 100)
+ self.dist_slider.setValue(
+ int(self._measured_data.measurement_properties.find_peaks.distance/10))
+
+ self.dist_slider.setRange(1, len(self.x))
+ self.update_plot()
+
+ def _init_ui(self):
+ # Create the plot widget
+ self.plot_widget = pg.PlotWidget()
+
+ # Create the sliders
+ self.prom_slider = QSlider(Qt.Horizontal)
+ self.prom_slider.setRange(0, 100)
+ #
+ self.prom_slider.setTickInterval(5)
+ self.prom_slider.setTickPosition(QSlider.TicksBelow)
+ self.prom_slider.sliderMoved.connect(self.update_plot)
+ self.edit_prom = QLineEdit(str(self.prom_slider.value()))
+
+ self.dist_slider = QSlider(Qt.Horizontal)
+
+ #
+ self.dist_slider.setTickInterval(100)
+ self.dist_slider.setTickPosition(QSlider.TicksBelow)
+ self.dist_slider.sliderMoved.connect(self.update_plot)
+ self.edit_dist = QLineEdit(str(self.dist_slider.value()))
+
+ self.btn_apply_to_all = QPushButton('Apply to all')
+ self.btn_apply_to_all.clicked.connect(
+ lambda: self.apply_fp_param_to_all_clicked.emit(
+ self.prom_slider.value() / 100,
+ self.dist_slider.value()
+ )
+ )
+ # Create the layout
+ prom_layout = QHBoxLayout()
+ prom_layout.addWidget(QLabel("Prominence:"))
+ prom_layout.addWidget(self.prom_slider)
+ prom_layout.addWidget(self.edit_prom)
+
+ dist_layout = QHBoxLayout()
+ dist_layout.addWidget(QLabel("Distance:"))
+ dist_layout.addWidget(self.dist_slider)
+ dist_layout.addWidget(self.edit_dist)
+
+ layout = QVBoxLayout()
+ layout.addWidget(self.plot_widget)
+ self.wdg_measured_information = MeasuredDataInformationWidget(self._measured_data)
+ layout.addWidget(self.wdg_measured_information)
+ layout.addLayout(prom_layout)
+ layout.addLayout(dist_layout)
+ layout.addWidget(self.btn_apply_to_all)
+ self.setLayout(layout)
+
+ def update_plot(self):
+ # Update the prominence and distance values
+ prom = self.prom_slider.value() / 100
+ dist = self.dist_slider.value()
+ self.wdg_measured_information.measurement_data = self.measured_data
+ # Update the peaks
+ self._measured_data.measurement_properties.find_peaks.prominence = prom
+ self._measured_data.measurement_properties.find_peaks.distance = dist
+
+ peaks_wl = self._measured_data.tables.get('_peaks')['wavelength']
+ peaks_amplitude = self._measured_data.tables.get('_peaks')['amplitude']
+ self.edit_dist.setText(str(dist))
+ self.edit_prom.setText(str(prom))
+
+ self.plot_widget.clear()
+ self.plot_widget.plot(self.x.to_list(), self.y.to_list())
+ self.plot_widget.plot(peaks_wl.to_list(), peaks_amplitude.to_list(), pen=None, symbol="o")
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ mypath = r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+ mm_data = MeasurementDataLoader.from_folder(mypath)
+ # matfile = mm_data.get_measurement(repetition=1, structure_name='mzi2-2')
+ matfiles = mm_data.get_measurement_series(structure_name='mzi2-2')
+ # matfile = SingleMeasuredData.from_mat(Path(f"{mypath}\measurement_die_22_struct_mzi2_2_20220306_1908_rep_2.mat"))
+ window = ParameterAdjustmentWindow(matfiles)
+ window.show()
+ app.exec_()
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e6ff908e2558e810e25810dc2b031a024c2bb1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py
@@ -0,0 +1,63 @@
+import numpy as np
+from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QGroupBox, QHBoxLayout, QGridLayout
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+
+
+class MeasuredDataInformationWidget(QGroupBox):
+ def __init__(self, measured_data: MeasuredData):
+ super().__init__()
+
+ self._wafer_number = "unknown"
+ self._die_number = "unknown"
+ self._structure_name = "unknown"
+ self._repetition = "unknown"
+ self._timestamp = "unknown"
+ self._measurement_time = 0
+ self._init_ui()
+ self.measurement_data = measured_data
+
+ def _init_ui(self):
+ # Create QLabel widgets to display the information
+ layout = QGridLayout()
+ self.wafer_label = QLabel()
+ self.die_label = QLabel()
+ self.structure_label = QLabel()
+ layout.addWidget(self.wafer_label, 0, 0)
+ layout.addWidget(self.die_label, 0, 1)
+ layout.addWidget(self.structure_label, 0, 2)
+
+ self.repetition_label = QLabel()
+ self.timestamp_label = QLabel()
+ self.measurement_time_label = QLabel()
+ layout.addWidget(self.repetition_label, 1, 0)
+ layout.addWidget(self.timestamp_label, 1, 1)
+ layout.addWidget(self.measurement_time_label, 1, 2)
+
+ # Create a vertical layout to arrange the QLabel widgets
+
+ # Set the layout for the group box
+ self.setLayout(layout)
+
+ @property
+ def measurement_data(self):
+ return self._measurement_data
+
+ @measurement_data.setter
+ def measurement_data(self, value):
+ if value is not None:
+ self._measurement_data = value
+ self._wafer_number = self._measurement_data.wafer_properties.wafer_number
+ self._die_number = self._measurement_data.wafer_properties.die_number
+ self._structure_name = self._measurement_data.wafer_properties.structure_name
+ self._repetition = self._measurement_data.wafer_properties.repetition
+ self._timestamp = "none"
+ self._measurement_time = self._measurement_data.ad2_properties.measurement_time
+
+ self.wafer_label.setText(f'Wafer Number: {self._wafer_number}')
+ self.die_label.setText(f'Die Number: {self._die_number}')
+ self.structure_label.setText(f'Structure Name: {self._structure_name}')
+ self.repetition_label.setText(f'Repetition: {self._repetition}')
+ self.timestamp_label.setText(f'Timestamp: {self._timestamp}')
+ self.measurement_time_label.setText(f'Measurement Time: {np.round(self._measurement_time, 3)}')
+
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab8b2fa889ed7bb1f34ae5a6048fdd5da72fafd1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py
@@ -0,0 +1,132 @@
+from PySide6.QtCore import Signal, Qt, QObject
+from PySide6.QtGui import QStandardItem, QStandardItemModel, QAction
+from PySide6.QtWidgets import (QTreeView, QVBoxLayout, QWidget, QTableView, QTableWidgetItem, QTableWidget, QMainWindow,
+ QAbstractItemView, QMenu)
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MultipleMeasurementItem(QStandardItem):
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ def type(self, *args, **kwargs):
+ return 'Multi'
+
+
+class SingleMeasurementItem(QStandardItem):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ def type(self):
+ return 'Single'
+
+
+class MeasurementSelectionWidgetSignals(QObject):
+ open_find_peaks_window = Signal(list)
+ on_consolidate_measurement_clicked = Signal(list)
+ on_recalculation_clicked = Signal(list)
+ on_show_item_click = Signal(SingleMeasuredData)
+
+
+class MeasurementSelectionWidget(QMainWindow):
+ consolidate_data = Signal(SingleMeasuredData)
+
+ def __init__(self, data):
+ super().__init__()
+ self.data: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = data
+
+ self.signals = MeasurementSelectionWidgetSignals()
+
+ self.tree_view = QTreeView(self)
+ self.model = QStandardItemModel()
+ self.tree_view.setModel(self.model)
+
+ self.setup_model()
+ self.tree_view.setSelectionMode(QAbstractItemView.SingleSelection)
+ self.tree_view.setSelectionBehavior(QAbstractItemView.SelectRows)
+ self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.tree_view.customContextMenuRequested.connect(self.show_context_menu)
+ self.setCentralWidget(self.tree_view)
+
+ def setup_model(self):
+ for k1, v1 in self.data.items():
+ parent_item = QStandardItem(k1)
+ self.model.appendRow(parent_item)
+ for k2, v2 in v1.items():
+ child_item = QStandardItem(str(k2))
+ parent_item.appendRow(child_item)
+ for k3, v3 in v2.items():
+ sub_child_item = MultipleMeasurementItem(k3)
+ child_item.appendRow(sub_child_item)
+ sub_child_item.setData(list(v2.values())[0])
+ for measured_data in v3:
+ data_item = SingleMeasurementItem(str(measured_data))
+ sub_child_item.appendRow(data_item)
+ data_item.setData(measured_data)
+
+ def multi_selection_menu(self, pos):
+ menu = QMenu(self)
+
+ action = QAction("Recalculate", self)
+ action.triggered.connect(self._on_recalculation_clicked)
+ menu.addAction(action)
+
+ action = QAction("Consolidate Data", self)
+ action.triggered.connect(self._on_consolidate_data_clicked)
+ menu.addAction(action)
+
+ action = QAction("Adapt 'FindPeaks' parameters", self)
+ action.triggered.connect(self._on_adapt_parameters_clicked)
+ menu.addAction(action)
+
+
+ menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+ def single_selection_menu(self, pos):
+ menu = QMenu(self)
+ action = QAction("Add to view", self)
+ action.triggered.connect(self._on_show_item_clicked)
+ menu.addAction(action)
+ menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+ def show_context_menu(self, pos):
+ selection = self.tree_view.selectionModel()
+ index = selection.currentIndex()
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ if item is not None:
+ if isinstance(item, SingleMeasurementItem):
+ self.single_selection_menu(pos)
+ elif isinstance(item, MultipleMeasurementItem):
+ self.multi_selection_menu(pos)
+
+ def _on_show_item_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_show_item_click.emit(data)
+
+ def _on_recalculation_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_recalculation_clicked.emit(data)
+
+ def _on_adapt_parameters_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.open_find_peaks_window.emit(data)
+
+ def _on_consolidate_data_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_consolidate_measurement_clicked.emit(data)
+
+ def on_clicked_acquire_item_data(self, selection):
+ index = selection.currentIndex()
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ if item.parent() is not None:
+ return item.data()
+ return None
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b40970ba56970d5f9a1d0f24346fcad1a400fb33
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py
@@ -0,0 +1,31 @@
+import numpy as np
+import pandas as pd
+
+import matplotlib
+import matplotlib.pyplot as plt
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QComboBox
+
+matplotlib.use('QT5Agg')
+
+class PlotViewWidget(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ # Create a Matplotlib figure and axes
+ self.figure = plt.figure()
+ self.canvas = FigureCanvas(self.figure)
+ self.ax = self.figure.add_subplot(111)
+
+ self.plot_selection = ""
+
+ # Add the canvas to this PySide6 widget
+ layout = QVBoxLayout(self)
+ layout.addWidget(self.canvas)
+
+ # Set up the initial graph with no data
+ self.ax.set_xlabel('Wavelength')
+ self.ax.set_ylabel('Amplitude')
+ self.ax.set_xlim(0, 1)
+ self.ax.set_ylim(0, 1)
+ self.ax.grid(True)
diff --git a/src/FlexSensor/MeasurementEvaluationTool/__init__.py b/src/FlexSensor/MeasurementEvaluationTool/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f81a7ff401d6760f956df11385f3c7032a57c2c
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/__init__.py
@@ -0,0 +1,6 @@
+from MeasurementEvaluationTool.view.MeasurementDataView import MeasurementDataView as View
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel as Model
+from MeasurementEvaluationTool.controller.MeasurementDataController import MeasurementDataController as Controller
+from MeasurementEvaluationTool.controller.MeasurementDatabase import MeasurementDatabase as Database
+
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader as Loader
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c0f2523e2240bfa97107c51bb57b68063f769e2
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py
@@ -0,0 +1,70 @@
+import logging
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from MeasurementEvaluationTool.controller.MeasurementDatabase import MeasurementDatabase
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel
+
+
+class MeasurementDataController:
+
+ def __init__(self, model: MeasurementDataModel, path=None):
+ self.logger = logging.getLogger("MeasurementDataController")
+ self._model = model
+
+ self._model.path = path
+
+
+ self._model.selected_measurements = []
+
+ if path is not None:
+ # Use the loader to load the data
+ self.db = MeasurementDatabase('data.db')
+ MeasurementDataLoader.from_folder(self._model.path, self.db)
+ #self._model.measurement_list = self._md_loader.sorted_files
+ else:
+
+ self._model.measurement_list = {}
+
+
+
+ @property
+ def consolidated_measurements(self):
+ return self._consolidated_measurements
+
+ @consolidated_measurements.setter
+ def consolidated_measurements(self, value):
+ self._consolidated_measurements = value
+
+ @property
+ def all_measurements(self):
+ return self._model.measurement_list
+
+ @property
+ def list_of_measurements(self) -> list[SingleMeasuredData]:
+ return self._model.selected_measurements
+
+ @property
+ def selected_measurement(self) -> SingleMeasuredData:
+ return self._model.display_measurement
+
+ def select_measurement(self, selected_measurement: MeasuredData):
+ self._model.display_measurement = selected_measurement
+
+ def consolidate_measurements(self, measurement_selection):
+ self._model.consolidated_measurement = MultiMeasuredData(measurement_selection)
+ self._model.selected_measurements = measurement_selection
+ self.select_measurement(self._model.consolidated_measurement)
+
+ def recalculate_measurements(self, measurement_selection):
+ self.logger.info("Recalculating all measurements")
+ for md in measurement_selection:
+ md.calulate_all()
+
+ def load_from_folder(self):
+ raise NotImplementedError
+
+ def add_measurement(self):
+ pass
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5c0d6e66f07c7f3d6726c96d8125b8f50e8aac3
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py
@@ -0,0 +1,95 @@
+import pickle
+import sqlite3
+
+from PySide6.QtWidgets import QApplication
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from generics.logger import setup_logging
+
+
+class MeasurementDatabase:
+ def __init__(self, db_name):
+ self.db_name = db_name
+ self.conn = sqlite3.connect(db_name)
+ self.cursor = self.conn.cursor()
+ self.create_table()
+
+ def create_table(self):
+ self.cursor.execute('''
+ CREATE TABLE IF NOT EXISTS single_measured_data (
+ wafer_number INTEGER,
+ die_number INTEGER,
+ structure_name TEXT,
+ rep INTEGER,
+ amplitude TEXT,
+ wavelength TEXT
+ )
+ ''')
+ self.conn.commit()
+
+ def add_data(self, data: SingleMeasuredData):
+ query = '''
+ INSERT INTO single_measured_data (
+ wafer_number,
+ die_number,
+ structure_name,
+ rep,
+ data_instance
+ ) VALUES (?, ?, ?, ?, ?)
+ '''
+ values = (
+ data.wafer_properties.wafer_number,
+ data.wafer_properties.die_number,
+ data.wafer_properties.structure_name,
+ data.wafer_properties.repetition,
+ pickle.dumps(data)
+ )
+ self.cursor.execute(query, values)
+ self.conn.commit()
+
+ def get_data(self, wafer_number, die_number):
+ query = '''
+ SELECT * FROM single_measured_data
+ WHERE wafer_number = ? AND die_number = ?
+ '''
+ values = (wafer_number, die_number)
+ self.cursor.execute(query, values)
+ rows = self.cursor.fetchall()
+ data_list = []
+ for row in rows:
+ amplitude = list(map(float, row[4].split()))
+ wavelength = list(map(float, row[5].split()))
+ data = SingleMeasuredData(row[0], row[1], row[2], row[3], amplitude, wavelength)
+ data_list.append(data)
+ return data_list
+
+ def delete_data(self, wafer_number, die_number):
+ query = '''
+ DELETE FROM single_measured_data
+ WHERE wafer_number = ? AND die_number = ?
+ '''
+ values = (wafer_number, die_number)
+ self.cursor.execute(query, values)
+ self.conn.commit()
+
+ def close_connection(self):
+ self.conn.close()
+
+
+if __name__ == "__main__":
+ app = QApplication()
+ setup_logging()
+
+ db = MeasurementDatabase("data.db")
+ # Load a measurement data
+ file = (r'F:\measurements_v2_06032022\measurements_v2_06032022\mea_mrr1_1_2022_03_04\T40741W177G0\MaskARY1_Jakob\measurement\measurement_die_22_struct_mrr1_1_20220304_2249_rep_2_v2.mat')
+
+
+ data = SingleMeasuredData.from_mat_v2(file)
+ db.add_data(data)
+ data_list = db.get_data(1, 2)
+ print(data_list)
+ db.delete_data(1, 2)
+ data_list = db.get_data(1, 2)
+ print(data_list)
+ db.close_connection()
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/data.db b/src/FlexSensor/MeasurementEvaluationTool/controller/data.db
new file mode 100644
index 0000000000000000000000000000000000000000..70224a870b586f87c9dde89cee46921be7177ea0
Binary files /dev/null and b/src/FlexSensor/MeasurementEvaluationTool/controller/data.db differ
diff --git a/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py b/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e55e292e0343f0eb2bda1a50bca42cff13b8950
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py
@@ -0,0 +1,85 @@
+from pathlib import Path
+
+from PySide6.QtCore import Signal, QObject
+
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataSignals(QObject):
+ path_changed = Signal(Path)
+
+ list_of_measurements_changed = Signal(list)
+ all_measurements_changed = Signal(dict)
+
+ num_of_measurements = Signal(int)
+ selected_measurement_changed = Signal(SingleMeasuredData)
+ consolidated_measurements_changed = Signal(MultiMeasuredData)
+
+
+class MeasurementDataModel:
+ def __init__(self):
+ self.signals = MeasuredDataSignals()
+
+ self._path: Path = None
+ self._measurement_list: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = None
+
+ self._consolidated_measurement: MultiMeasuredData = None
+ self._display_measurement: SingleMeasuredData = None
+ self._selected_measurements: list[SingleMeasuredData] = []
+
+ self._num_of_measurements: int = 0
+
+ @property
+ def consolidated_measurement(self):
+ return self._consolidated_measurement
+
+ @consolidated_measurement.setter
+ def consolidated_measurement(self, value):
+ self._consolidated_measurement = value
+
+ @property
+ def path(self):
+ return self._path
+
+ @path.setter
+ def path(self, value):
+ self._path = value
+ self.signals.path_changed.emit(self.path)
+
+ @property
+ def measurement_list(self) -> dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]:
+ return self._measurement_list
+
+ @measurement_list.setter
+ def measurement_list(self, value: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]) -> None:
+ self._measurement_list = value
+ self.signals.all_measurements_changed.emit(self.measurement_list)
+
+ @property
+ def selected_measurements(self) -> list[SingleMeasuredData]:
+ return self._selected_measurements
+
+ @selected_measurements.setter
+ def selected_measurements(self, value: list[SingleMeasuredData]) -> None:
+ self._selected_measurements = value
+ self.num_of_measurements = len(self.selected_measurements)
+ self.signals.list_of_measurements_changed.emit(self.selected_measurements)
+
+ @property
+ def num_of_measurements(self) -> int:
+ return self._num_of_measurements
+
+ @num_of_measurements.setter
+ def num_of_measurements(self, value: list[SingleMeasuredData]) -> None:
+ self._num_of_measurements = value
+ self.signals.num_of_measurements.emit(self.num_of_measurements)
+
+ @property
+ def display_measurement(self) -> SingleMeasuredData:
+ return self._display_measurement
+
+ @display_measurement.setter
+ def display_measurement(self, value: SingleMeasuredData) -> None:
+ self._display_measurement = value
+ self.signals.selected_measurement_changed.emit(self.display_measurement)
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py b/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py
new file mode 100644
index 0000000000000000000000000000000000000000..167996fda6b44efdc6e6879d1f0f82b028482aaa
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py
@@ -0,0 +1,171 @@
+import sys
+
+import numpy as np
+from PySide6.QtWidgets import QApplication, QWidget, QTableView, \
+ QComboBox, QPushButton, QGridLayout
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluationTool.controller.MeasurementDataController import MeasurementDataController
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel
+from generics.PandasTableModel import PandasTableModel
+from MeasurementEvaluationTool.view.ParameterAdjustmentView import ParameterAdjustmentWindow
+from MeasurementEvaluationTool.view.widgets.MeasurementSelectionWidget import MeasurementSelectionWidget
+from MeasurementEvaluationTool.view.widgets.PlotViewWidget import PlotViewWidget
+from generics.logger import setup_logging
+
+
+class MeasurementDataView(QWidget):
+ def __init__(self, model: MeasurementDataModel, controller: MeasurementDataController):
+ super().__init__()
+ self._model = model
+ self._controller = controller
+ self.layout = QGridLayout()
+
+ self._model.signals.selected_measurement_changed.connect(self._on_selected_measurement_changed)
+
+ self._init_ui()
+
+ def _init_ui(self):
+ self.find_peaks_view = ParameterAdjustmentWindow()
+
+ # Add a view for selecting the measurement
+ self.measurement_selection = MeasurementSelectionWidget(self._controller.all_measurements)
+
+ self.measurement_selection.signals.open_find_peaks_window.connect(self._on_adapt_parameters_clicked)
+ self.measurement_selection.signals.on_consolidate_measurement_clicked.connect(self._on_consolidate_clicked)
+ self.measurement_selection.signals.on_recalculation_clicked.connect(self._on_recalculate_clicked)
+ self.measurement_selection.signals.on_show_item_click.connect(self._on_show_item_clicked)
+
+ # self.measurement_selection.selection.selected_data_changed.connect(self._on_selection_changed)
+ self.layout.addWidget(self.measurement_selection, 0, 0, 2, 1)
+
+ self.plot_widget = PlotViewWidget() # pg.PlotWidget()
+ self.layout.addWidget(self.plot_widget, 0, 1, 1, 1)
+
+ # Display the data in an QTableWidget
+ self.table_view = QTableView()
+ self.layout.addWidget(self.table_view, 1, 1, 1, 1)
+
+ # Add a dropdown
+ self.btn_consolidate = QPushButton('Consolidate all')
+ self.btn_consolidate.clicked.connect(self._on_consolidate_clicked)
+ self.layout.addWidget(self.btn_consolidate, 2, 0, 1, 1)
+
+ self.dd_select_measurement_table = QComboBox()
+ self.dd_select_measurement_table.currentIndexChanged.connect(self._on_data_table_changed)
+ self.layout.addWidget(self.dd_select_measurement_table, 2, 1, 1, 1)
+
+ self.setLayout(self.layout)
+ # self._controller.select_measurement(0)
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def _on_show_item_clicked(self, measurement_selection: SingleMeasuredData):
+ measurement_selection.calulate_all()
+ self._controller.select_measurement(measurement_selection)
+
+ def _on_consolidate_clicked(self, measurement_selection):
+ self._controller.recalculate_measurements(measurement_selection)
+ self._controller.consolidate_measurements(measurement_selection)
+ # self._current_measurement = self._controller.consolidated_measurements
+
+ def _on_recalculate_clicked(self, measurement_selection):
+ self._controller.recalculate_measurements(measurement_selection)
+
+ def _on_adapt_parameters_clicked(self, measurement_selection):
+ self.find_peaks_view.measured_data_list = measurement_selection
+ self.find_peaks_view.show()
+
+ def _on_selection_changed(self, it: int):
+ # self._controller.select_measurement(it)
+ self.measurement_selection.set_selected_data(self._controller.selected_measurement)
+
+ def _on_data_table_changed(self, idx):
+ table_name = self.dd_select_measurement_table.itemData(idx)
+ print(f"{table_name} - {type(table_name)}")
+ # print(self._current_measurement.tables.get(table_name))
+ table = self._controller.selected_measurement.tables.get(table_name)
+ # Define plt function here
+ self.table_view_model = PandasTableModel(table)
+ self.table_view.setModel(self.table_view_model)
+
+ # This will be removed later and is only for quick and dirty hardcoded plotting
+ if table_name == "_measured_data":
+ pass
+ # self._plot_measurement_table(table_name)
+ elif table_name == "_wg_param":
+ self._controller.selected_measurement.tables.get_plot_function('ng (FSR)')(self.plot_widget)
+
+ #self._plot_ng_table(table_name)
+
+ def _on_selected_measurement_changed(self, measurement: MeasurementData):
+ self._current_measurement = measurement
+ # Populate the measurement ment selection
+ self.dd_select_measurement_table.clear()
+ for table in measurement.tables.to_list():
+ # id in table -> table[2] = 'Friendly name', table[1] = 'table name'
+ self.dd_select_measurement_table.addItem(table[2], table[1])
+ #self.dd_select_measurement_table.addItem( measurement.tables.to_list()[2][2], table[2][1])
+
+ # ==================================================================================================================
+ #
+ # =============================================================================================================
+ def _plot_measurement_table(self, table_name, x_axis="wavelength", y_axis="detrend"):
+ self.plot_widget.ax.clear()
+ data = self._controller.selected_measurement.tables.get(table_name)
+ self.plot_widget.ax.plot(data[x_axis], data[y_axis], 'b-')[0]
+ self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+ self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+ # Scatter plot of the peaks
+ df_peaks = self._current_measurement.peaks
+ self.plot_widget.ax.scatter(df_peaks[x_axis], df_peaks[y_axis], marker='x', color='red')
+ self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+ self.plot_widget.ax.set_ylabel('Amplitude [1]')
+ self.plot_widget.ax.set_title('Measured data')
+ self.plot_widget.ax.grid(True)
+ self.plot_widget.ax.legend([y_axis, 'Peaks'])
+
+ self.plot_widget.canvas.draw()
+
+ def _plot_ng_table(self, table_name, x_axis="lambda", y_axis="FSR"):
+ self.plot_widget.ax.clear()
+ data = self._controller.selected_measurement.tables.get(table_name)
+ self.plot_widget.ax.plot(data[x_axis], data[y_axis])
+ self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+ self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+ # Scatter plot of the peaks
+ self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+ self.plot_widget.ax.set_ylabel(f'{y_axis} [1]')
+ self.plot_widget.ax.grid(True)
+
+ self.plot_widget.canvas.draw()
+
+def convert_mat(mypath):
+ #mypath = (r'F:\measurements_06032022')
+ md_loader = MeasurementDataLoader.glob_files(mypath, '*.mat')
+ #measurement_list = md_loader.sorted_files
+
+ for measurement in md_loader:
+ SingleMeasuredData.convert(measurement)
+ print('done')
+
+
+if __name__ == "__main__":
+ app = QApplication()
+ setup_logging()
+
+ #mypath = (r'F:\measurements_06032022\measurements_06032022\mea_mzi1_2022_03_06\T40741W177G0')
+ #mypath = (r'F:\measurements_06032022')
+ #convert_mat(mypath)
+ #exit()
+
+ mypath = (r'F:\measurements_v2_06032022')
+
+ model = MeasurementDataModel()
+ controller = MeasurementDataController(model, mypath)
+ window = MeasurementDataView(model, controller)
+ window.show()
+
+ sys.exit(app.exec())
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py b/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py
new file mode 100644
index 0000000000000000000000000000000000000000..3848db134407336f072d3b9999cc194dbe8599bc
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py
@@ -0,0 +1,169 @@
+from PySide6.QtWidgets import QLineEdit, QPushButton
+from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
+ QWidget, QLabel, QSlider, QComboBox)
+from PySide6.QtCore import Qt, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+import pyqtgraph as pg
+
+from MeasurementEvaluationTool.view.widgets.MeasuredDataInformationWidget import MeasuredDataInformationWidget
+
+
+class ParameterAdjustmentWindow(QMainWindow):
+
+ def __init__(self):
+ super().__init__()
+ self._current_measurement = None
+ self._measured_data_list = None
+
+ self.setWindowTitle("Find Peaks Demo")
+
+ layout = QVBoxLayout()
+ self.measurement_selection = QComboBox()
+ layout.addWidget(self.measurement_selection)
+
+ self._find_peaks_wdg = ParameterAdjustmentWidget()
+ self._find_peaks_wdg.apply_fp_param_to_all_clicked.connect(self._on_apply_to_all)
+
+ layout.addWidget(self._find_peaks_wdg)
+ widget = QWidget()
+ widget.setLayout(layout)
+
+ self.setCentralWidget(widget)
+
+ @property
+ def current_measurement(self):
+ return self._current_measurement
+
+ @current_measurement.setter
+ def current_measurement(self, value):
+ self._current_measurement = value
+ self._find_peaks_wdg.measured_data = self.current_measurement
+
+ @property
+ def measured_data_list(self):
+ return self._measured_data_list
+
+ @measured_data_list.setter
+ def measured_data_list(self, value):
+ self._measured_data_list = value
+ self.current_measurement = self._measured_data_list[0]
+ for i, md in enumerate(self._measured_data_list):
+ self.measurement_selection.addItem(str(md))
+ self.measurement_selection.currentIndexChanged.connect(self._on_measurement_changed)
+
+ def _on_apply_to_all(self, prominence, distance):
+ for md in self._measured_data_list:
+ md.measurement_properties.find_peaks.set_properties(prominence,distance,None)
+
+ def _on_measurement_changed(self, index):
+ self.current_measurement = self._measured_data_list[index]
+
+
+class ParameterAdjustmentWidget(QWidget):
+ apply_fp_param_to_all_clicked = Signal(float, float)
+
+ def __init__(self):
+ super().__init__()
+ self._measured_data: SingleMeasuredData = None
+ # Create the numpy array
+ self._init_ui()
+
+ @property
+ def measured_data(self):
+ return self._measured_data
+
+ @measured_data.setter
+ def measured_data(self, value):
+ self._measured_data = value
+ self.x = self._measured_data.tables.get('_measured_data')['wavelength']
+ self.y = self._measured_data.tables.get('_measured_data')['amplitude']
+ self.prom_slider.setValue(
+ self._measured_data.measurement_properties.find_peaks.prominence * 100)
+ self.dist_slider.setValue(
+ int(self._measured_data.measurement_properties.find_peaks.distance/10))
+
+ self.dist_slider.setRange(1, len(self.x))
+ self.update_plot()
+
+ def _init_ui(self):
+ # Create the plot widget
+ self.plot_widget = pg.PlotWidget()
+
+ # Create the sliders
+ self.prom_slider = QSlider(Qt.Horizontal)
+ self.prom_slider.setRange(0, 100)
+ #
+ self.prom_slider.setTickInterval(5)
+ self.prom_slider.setTickPosition(QSlider.TicksBelow)
+ self.prom_slider.sliderMoved.connect(self.update_plot)
+ self.edit_prom = QLineEdit(str(self.prom_slider.value()))
+
+ self.dist_slider = QSlider(Qt.Horizontal)
+
+ #
+ self.dist_slider.setTickInterval(100)
+ self.dist_slider.setTickPosition(QSlider.TicksBelow)
+ self.dist_slider.sliderMoved.connect(self.update_plot)
+ self.edit_dist = QLineEdit(str(self.dist_slider.value()))
+
+ self.btn_apply_to_all = QPushButton('Apply to all')
+ self.btn_apply_to_all.clicked.connect(
+ lambda: self.apply_fp_param_to_all_clicked.emit(
+ self.prom_slider.value() / 100,
+ self.dist_slider.value()
+ )
+ )
+ # Create the layout
+ prom_layout = QHBoxLayout()
+ prom_layout.addWidget(QLabel("Prominence:"))
+ prom_layout.addWidget(self.prom_slider)
+ prom_layout.addWidget(self.edit_prom)
+
+ dist_layout = QHBoxLayout()
+ dist_layout.addWidget(QLabel("Distance:"))
+ dist_layout.addWidget(self.dist_slider)
+ dist_layout.addWidget(self.edit_dist)
+
+ layout = QVBoxLayout()
+ layout.addWidget(self.plot_widget)
+ self.wdg_measured_information = MeasuredDataInformationWidget(self._measured_data)
+ layout.addWidget(self.wdg_measured_information)
+ layout.addLayout(prom_layout)
+ layout.addLayout(dist_layout)
+ layout.addWidget(self.btn_apply_to_all)
+ self.setLayout(layout)
+
+ def update_plot(self):
+ # Update the prominence and distance values
+ prom = self.prom_slider.value() / 100
+ dist = self.dist_slider.value()
+ self.wdg_measured_information.measurement_data = self.measured_data
+ # Update the peaks
+ self._measured_data.measurement_properties.find_peaks.prominence = prom
+ self._measured_data.measurement_properties.find_peaks.distance = dist
+
+ peaks_wl = self._measured_data.tables.get('_peaks')['wavelength'].compute()
+ peaks_amplitude = self._measured_data.tables.get('_peaks')['amplitude'].compute()
+ self.edit_dist.setText(str(dist))
+ self.edit_prom.setText(str(prom))
+
+ self.plot_widget.clear()
+ x = self.x.compute()
+ y = self.y.compute()
+ self.plot_widget.plot(x.to_list(), y.to_list())
+ self.plot_widget.plot(peaks_wl.to_list(), peaks_amplitude.to_list(), pen=None, symbol="o")
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ mypath = r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+ mm_data = MeasurementDataLoader.from_folder(mypath)
+ # matfile = mm_data.get_measurement(repetition=1, structure_name='mzi2-2')
+ matfiles = mm_data.get_measurement_series(structure_name='mzi2-2')
+ # matfile = SingleMeasuredData.from_mat(Path(f"{mypath}\measurement_die_22_struct_mzi2_2_20220306_1908_rep_2.mat"))
+ window = ParameterAdjustmentWindow(matfiles)
+ window.show()
+ app.exec_()
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e6ff908e2558e810e25810dc2b031a024c2bb1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py
@@ -0,0 +1,63 @@
+import numpy as np
+from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QGroupBox, QHBoxLayout, QGridLayout
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+
+
+class MeasuredDataInformationWidget(QGroupBox):
+ def __init__(self, measured_data: MeasuredData):
+ super().__init__()
+
+ self._wafer_number = "unknown"
+ self._die_number = "unknown"
+ self._structure_name = "unknown"
+ self._repetition = "unknown"
+ self._timestamp = "unknown"
+ self._measurement_time = 0
+ self._init_ui()
+ self.measurement_data = measured_data
+
+ def _init_ui(self):
+ # Create QLabel widgets to display the information
+ layout = QGridLayout()
+ self.wafer_label = QLabel()
+ self.die_label = QLabel()
+ self.structure_label = QLabel()
+ layout.addWidget(self.wafer_label, 0, 0)
+ layout.addWidget(self.die_label, 0, 1)
+ layout.addWidget(self.structure_label, 0, 2)
+
+ self.repetition_label = QLabel()
+ self.timestamp_label = QLabel()
+ self.measurement_time_label = QLabel()
+ layout.addWidget(self.repetition_label, 1, 0)
+ layout.addWidget(self.timestamp_label, 1, 1)
+ layout.addWidget(self.measurement_time_label, 1, 2)
+
+ # Create a vertical layout to arrange the QLabel widgets
+
+ # Set the layout for the group box
+ self.setLayout(layout)
+
+ @property
+ def measurement_data(self):
+ return self._measurement_data
+
+ @measurement_data.setter
+ def measurement_data(self, value):
+ if value is not None:
+ self._measurement_data = value
+ self._wafer_number = self._measurement_data.wafer_properties.wafer_number
+ self._die_number = self._measurement_data.wafer_properties.die_number
+ self._structure_name = self._measurement_data.wafer_properties.structure_name
+ self._repetition = self._measurement_data.wafer_properties.repetition
+ self._timestamp = "none"
+ self._measurement_time = self._measurement_data.ad2_properties.measurement_time
+
+ self.wafer_label.setText(f'Wafer Number: {self._wafer_number}')
+ self.die_label.setText(f'Die Number: {self._die_number}')
+ self.structure_label.setText(f'Structure Name: {self._structure_name}')
+ self.repetition_label.setText(f'Repetition: {self._repetition}')
+ self.timestamp_label.setText(f'Timestamp: {self._timestamp}')
+ self.measurement_time_label.setText(f'Measurement Time: {np.round(self._measurement_time, 3)}')
+
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab8b2fa889ed7bb1f34ae5a6048fdd5da72fafd1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py
@@ -0,0 +1,132 @@
+from PySide6.QtCore import Signal, Qt, QObject
+from PySide6.QtGui import QStandardItem, QStandardItemModel, QAction
+from PySide6.QtWidgets import (QTreeView, QVBoxLayout, QWidget, QTableView, QTableWidgetItem, QTableWidget, QMainWindow,
+ QAbstractItemView, QMenu)
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MultipleMeasurementItem(QStandardItem):
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ def type(self, *args, **kwargs):
+ return 'Multi'
+
+
+class SingleMeasurementItem(QStandardItem):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ def type(self):
+ return 'Single'
+
+
+class MeasurementSelectionWidgetSignals(QObject):
+ open_find_peaks_window = Signal(list)
+ on_consolidate_measurement_clicked = Signal(list)
+ on_recalculation_clicked = Signal(list)
+ on_show_item_click = Signal(SingleMeasuredData)
+
+
+class MeasurementSelectionWidget(QMainWindow):
+ consolidate_data = Signal(SingleMeasuredData)
+
+ def __init__(self, data):
+ super().__init__()
+ self.data: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = data
+
+ self.signals = MeasurementSelectionWidgetSignals()
+
+ self.tree_view = QTreeView(self)
+ self.model = QStandardItemModel()
+ self.tree_view.setModel(self.model)
+
+ self.setup_model()
+ self.tree_view.setSelectionMode(QAbstractItemView.SingleSelection)
+ self.tree_view.setSelectionBehavior(QAbstractItemView.SelectRows)
+ self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.tree_view.customContextMenuRequested.connect(self.show_context_menu)
+ self.setCentralWidget(self.tree_view)
+
+ def setup_model(self):
+ for k1, v1 in self.data.items():
+ parent_item = QStandardItem(k1)
+ self.model.appendRow(parent_item)
+ for k2, v2 in v1.items():
+ child_item = QStandardItem(str(k2))
+ parent_item.appendRow(child_item)
+ for k3, v3 in v2.items():
+ sub_child_item = MultipleMeasurementItem(k3)
+ child_item.appendRow(sub_child_item)
+ sub_child_item.setData(list(v2.values())[0])
+ for measured_data in v3:
+ data_item = SingleMeasurementItem(str(measured_data))
+ sub_child_item.appendRow(data_item)
+ data_item.setData(measured_data)
+
+ def multi_selection_menu(self, pos):
+ menu = QMenu(self)
+
+ action = QAction("Recalculate", self)
+ action.triggered.connect(self._on_recalculation_clicked)
+ menu.addAction(action)
+
+ action = QAction("Consolidate Data", self)
+ action.triggered.connect(self._on_consolidate_data_clicked)
+ menu.addAction(action)
+
+ action = QAction("Adapt 'FindPeaks' parameters", self)
+ action.triggered.connect(self._on_adapt_parameters_clicked)
+ menu.addAction(action)
+
+
+ menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+ def single_selection_menu(self, pos):
+ menu = QMenu(self)
+ action = QAction("Add to view", self)
+ action.triggered.connect(self._on_show_item_clicked)
+ menu.addAction(action)
+ menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+ def show_context_menu(self, pos):
+ selection = self.tree_view.selectionModel()
+ index = selection.currentIndex()
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ if item is not None:
+ if isinstance(item, SingleMeasurementItem):
+ self.single_selection_menu(pos)
+ elif isinstance(item, MultipleMeasurementItem):
+ self.multi_selection_menu(pos)
+
+ def _on_show_item_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_show_item_click.emit(data)
+
+ def _on_recalculation_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_recalculation_clicked.emit(data)
+
+ def _on_adapt_parameters_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.open_find_peaks_window.emit(data)
+
+ def _on_consolidate_data_clicked(self):
+ selection = self.tree_view.selectionModel()
+ data = self.on_clicked_acquire_item_data(selection)
+ self.signals.on_consolidate_measurement_clicked.emit(data)
+
+ def on_clicked_acquire_item_data(self, selection):
+ index = selection.currentIndex()
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ if item.parent() is not None:
+ return item.data()
+ return None
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ff8638994e2b9b0ee4ac9880aed97c31014e2be
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py
@@ -0,0 +1,50 @@
+from PySide6.QtGui import QIcon, QAction
+from PySide6.QtWidgets import QGroupBox, QWidget
+
+from MainWindow.controller.MainThreadController import MainThreadController
+from MainWindow.view import MainThreadView
+from pathes import image_root
+
+
+class MenuBarDefinition(QWidget):
+
+ def __init__(self, view: MainThreadView):
+ super().__init__()
+ self._view = view
+
+ # self.menubar = self.menuBar()
+ self.init_menu_file()
+ self.init_menu_edit()
+ self.init_menu_run()
+ # help_menu = menubar.addMenu("Help")
+ # help_menu.addAction("About", self.on_about_clicked)
+
+
+
+ def init_menu_file(self):
+ exit_action = QAction(QIcon('exit.png'), '&Exit ', self)
+ exit_action.setShortcut('Ctrl+Q')
+ exit_action.setStatusTip('Exit application')
+ exit_action.triggered.connect(lambda: exit())
+ self._view._ui.menu_file.addAction(exit_action)
+
+ def init_menu_edit(self):
+ pass
+
+ def init_menu_run(self):
+ # self.menu_run = self.menubar.addMenu("Run")
+ self.open_step_trough = QAction('Open &Step Through Window', self)
+ self.open_step_trough.setShortcut('Ctrl+W')
+ self.open_step_trough.setStatusTip('Open Step Through Window')
+ self.open_step_trough.triggered.connect(self._view._on_open_step_through)
+ self._view._ui.menu_run.addAction(self.open_step_trough)
+
+ self.open_train_home_wizard = QAction('&Initial Setup Wizard', self)
+ self.open_train_home_wizard.setShortcut('Ctrl+I')
+ self.open_train_home_wizard.setStatusTip('Open Initial Setup Wizard')
+ self.open_train_home_wizard.setIcon(QIcon(f"{image_root}/icons/setup_wizard.png"))
+ self.open_train_home_wizard.triggered.connect(self._view._on_open_initial_setup_wizard)
+ self._view._ui.menu_run.addAction(self.open_train_home_wizard)
+
+
+
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b40970ba56970d5f9a1d0f24346fcad1a400fb33
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py
@@ -0,0 +1,31 @@
+import numpy as np
+import pandas as pd
+
+import matplotlib
+import matplotlib.pyplot as plt
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QComboBox
+
+matplotlib.use('QT5Agg')
+
+class PlotViewWidget(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ # Create a Matplotlib figure and axes
+ self.figure = plt.figure()
+ self.canvas = FigureCanvas(self.figure)
+ self.ax = self.figure.add_subplot(111)
+
+ self.plot_selection = ""
+
+ # Add the canvas to this PySide6 widget
+ layout = QVBoxLayout(self)
+ layout.addWidget(self.canvas)
+
+ # Set up the initial graph with no data
+ self.ax.set_xlabel('Wavelength')
+ self.ax.set_ylabel('Amplitude')
+ self.ax.set_xlim(0, 1)
+ self.ax.set_ylim(0, 1)
+ self.ax.grid(True)
diff --git a/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py b/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b7bba703a6d25f20070acad74b4ac0e9bf3ca1b
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py
@@ -0,0 +1,108 @@
+import logging
+
+from PySide6.QtCore import QObject, QThread, Slot
+
+from AD2CaptDevice.controller.AD2CaptDeviceController import AD2CaptDeviceController
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Laser.LaserControl.controller import BaseLaserController
+from Prober.controller.ProberController import ProberController
+from MeasurementRoutines.WorkerSignals import WorkerSignals
+
+
+class BaseMeasurementRoutine(QObject):
+
+ def __init__(self, laser: BaseLaserController, ad2device: AD2CaptDeviceController, prober: ProberController,
+ vaut_config: VAutomatorConfig):
+ super().__init__()
+ self.logger = logging.getLogger("Base Measurement Routine")
+ self.vaut_config = vaut_config
+
+ self.ad2device: AD2CaptDeviceController = ad2device
+ self.laser: BaseLaserController = laser
+ self.prober: ProberController = prober
+ self.logger.debug(f"{self.prober.report_kernel_version()}")
+ print(self.prober)
+
+ self.prober_thread = QThread()
+
+ self.signals = WorkerSignals()
+
+ @Slot()
+ def run(self):
+ raise NotImplementedError()
+
+ def _routine(self):
+ raise NotImplementedError()
+
+ def _init_prober_signals(self):
+ '''
+ Connect the signals and disable that a new log is printed (in order to prevent double occuring lines
+ '''
+ self.prober.signals.log_debug.connect(lambda title, desc, details: self._write_debug(desc, print_log=False))
+ self.prober.signals.log_info.connect(lambda title, desc, details: self._write_info(desc, print_log=False))
+ self.prober.signals.log_warning.connect(lambda title, desc, details: self._write_warning(desc, print_log=False))
+ self.prober.signals.log_error.connect(
+ lambda title, desc, details: self._write_error(title, desc, details, print_log=False))
+
+ def _write_debug(self, *msg, print_log=True, **kwargs):
+ if print_log:
+ self.logger.debug(*msg)
+ self.signals.write_log.emit("debug", *msg)
+
+ def _write_info(self, *msg, print_log=True, **kwargs):
+ if print_log:
+ self.logger.info(*msg)
+ self.signals.write_log.emit("info", *msg)
+
+ def _write_warning(self, title, msg, desc, err=None, tb=None, print_log=True, *args, **kwargs):
+ if err is None and tb is None:
+ logmsg_short = f"{desc}."
+ logmsg_full = f"{logmsg_short}"
+ else:
+ logmsg_short = f"{desc}: {err}."
+ logmsg_traceback = f"=== TRACEBACK ===\n{tb.format_exc()}"
+ logmsg_full = f"{logmsg_short}\n\n{logmsg_traceback}"
+ if print_log:
+ self.logger.warning(logmsg_full)
+ self.signals.warning.emit((title, logmsg_short, logmsg_full))
+
+ def _write_error(self, title, desc, e=None, tb=None, print_log=True, *args, **kwargs):
+ if e is None and tb is None:
+ logmsg_short = f"{desc}."
+ logmsg_full = f"{logmsg_short}"
+ else:
+ logmsg_short = f"{desc}: {e}."
+ logmsg_traceback = f"=== TRACEBACK ===\n{tb.format_exc()}"
+ logmsg_full = f"{logmsg_short}\n\n{logmsg_traceback}"
+ if print_log:
+ self.logger.error(logmsg_full)
+ self.signals.error.emit((title, logmsg_short, logmsg_full))
+
+ def write_log(self, msg_type, *args, **kwargs):
+ if msg_type == "debug":
+ self.logger.debug(*args)
+ elif msg_type == "warning":
+ self.logger.warning(*args)
+ elif msg_type == "error":
+ self.logger.error(*args)
+ elif msg_type == "fatal":
+ self.logger.fatal(*args)
+ else:
+ self.logger.info(*args)
+
+ self.signals.write_log.emit(msg_type, *args)
+
+ def register_step(*args, **kwargs):
+ step_name = "Step"
+ if 'step_name' in kwargs:
+ step_name = kwargs['step_name']
+
+ def inner(func):
+ '''
+ do operations with func
+ '''
+ print(f"Registering step for function {func} - {step_name}")
+ return func
+
+ return inner # this is the fun_obj mentioned in the above content
+
diff --git a/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py b/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea4d3d963f407a4cfdbccc1a2bc5004e284a6ac2
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py
@@ -0,0 +1,389 @@
+import logging
+import time
+import traceback
+from datetime import datetime
+
+import pandas as pd
+from PySide6.QtCore import Slot
+
+import mcpy
+from AD2CaptDevice.controller.AD2CaptDeviceController import AD2CaptDeviceController
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.controller.VFSObject import VFSObject
+from ConfigHandler.controller.VASInputFileParser import VASInputFileParser, Structure
+from Laser.LaserControl.controller import BaseLaserController
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.Properties.MeasurementProperties import MPropertiesFindPeaks, \
+ MeasurementProperties, WaveguidePropertiesMZI
+from MeasurementRoutines.BasemeasurementRoutine import BaseMeasurementRoutine
+from Prober.controller.ProberController import ProberController
+from MeasurementData.Properties.WaferProperties import WaferProperties
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+class MeasurementRoutine(BaseMeasurementRoutine):
+
+ def __init__(self, laser: BaseLaserController, ad2device: AD2CaptDeviceController, prober: ProberController,
+ vaut_config: VAutomatorConfig):
+ super().__init__(laser, ad2device, prober, vaut_config)
+
+ self.logger = logging.getLogger("Measurement Routine")
+ # The signals for connecting to the UI
+
+ self.parsed_file = VASInputFileParser()
+
+ self.grouped_structures, self.bookmarks = self.parsed_file.read_file(
+ input_file=self.vaut_config.wafer_config.get_structure_file().absolute
+ )
+ self.number_of_structures = self.parsed_file.num_of_structs
+ self.number_of_runs = self.parsed_file.num_of_runs
+
+ # We need to connect two signals:
+ # Connect the signal if a wavelength sweep starts (from the laser) to a signal that tells our oscilloscope
+ # to start capturing!
+ # self.laser.signals.wavelength_sweep_running.connect(self.ad2device.on_ad2_set_acquisition_changed)
+
+ # Some intermediate Data
+ self.columns = ["wafer_nr", "die_nr", "chuck_col", "chuck_row", "timestamp", "structure_name",
+ "reps", "structure_x_in", "structure_y_in", "structure_x_out",
+ "structure_y_out", "measure_time", "timestamps", "captured_values"]
+ self.siph_data = pd.DataFrame(columns=self.columns)
+ self.siph_data['captured_values'] = self.siph_data['captured_values'].astype(object)
+
+ self.initialization()
+
+ def initialization(self):
+ self.probe_height = 80
+
+ self.logger.info(
+ f"Init Prober Class. Number of runs per die: {self.number_of_runs}, dies {self.vaut_config.wafer_config.dies}\n"
+ f"Measurement CVS File = {self.vaut_config.wafer_config.measurement_output}\n"
+ f"Measurement Mat File = {self.vaut_config.wafer_config.measurement_mat_file}")
+
+ @Slot()
+ def run(self):
+ self.logger.info(f"<< Input file {self.vaut_config.wafer_config.get_structure_file().relative}")
+ self.logger.info(f">> Working directory {self.vaut_config.get_output_directory().relative}")
+ self.logger.info(f">> Log File {self.vaut_config.wafer_config.get_log_file().relative}")
+ self.logger.info(f">> Measurments CVS File {self.vaut_config.wafer_config.get_measurement_output().relative}")
+ self.logger.info(f">> Measurments Mat File {self.vaut_config.wafer_config.get_measurement_mat_file().relative}")
+ self.logger.info(f">> KLayout Bookmark file {self.vaut_config.wafer_config.get_bookmark_file().relative}")
+ self.logger.info(f">> Scope Image File {self.vaut_config.wafer_config.get_scope_image_file().relative}")
+
+ # as long as the connection was successful, we can send some commands.
+ # if it was not successful, an exception is thrown.
+
+ self.logger.warning("*** Check safe height. Contact height must be set.***")
+ # SCI commands return a namedtuple if multiple values are returned.
+ # ReportKernelVersion returns a version number and a description.
+ # You can acess the return values by name or by indexing the tuple.
+ self.logger.info("Everything is set up, starting measuring.")
+
+ self._routine()
+
+ def _routine(self):
+ try:
+ # Initialize the devices
+ self._init_prober_signals()
+ # self._init_laser_signals()
+ # self._init_ad2device_signals()
+
+ self._write_info(
+ f"{pch('=', 50)} Starting measurement {pch('=', 50)}")
+
+ # === Check contact height
+ print(self.prober)
+ contact, overtravel, align_dist, sep_dis, search_gap = self.prober.check_contact_height_set()
+
+ for die_idx, die_no in enumerate(self.vaut_config.wafer_config.dies):
+ # Move to die
+ self.write_log("info", f"Processing die {die_no} (#{die_idx})")
+ self.die_no, self.chuck_col, self.chuck_row = self.prober.move_to_die(die_no)
+
+ if self.die_no is not None and self.chuck_col is not None and self.chuck_row is not None:
+ self.write_log("info", f"Chuck moved to home position. Die {self.die_no} "
+ f"(Col: {self.chuck_col}, Row: {self.chuck_row})")
+ else:
+ # STOP SiPh-Tools
+ self.write_log("fatal", "Chuck could not be moved to home position. Script will be stopped!")
+ raise Exception("Chuck could not be moved to home position. Script will be stopped!")
+
+ # Go to the home position
+ self.write_log("info", "Move chuck to home position (0, 0)")
+ self.prober.move_chuck(0, 0)
+
+ # Iterate through the list of structures
+ for idx_groups, self.groups in enumerate(self.grouped_structures):
+
+ structures: dict = self.grouped_structures[self.groups]
+ idx_struct = 0
+ self.write_log("info", f"New structure group ({idx_groups}): "
+ f"{self.groups}. {len(structures)} structures in group.")
+
+ while idx_struct < len(structures):
+ structure = list(structures.values())[idx_struct]
+ self._measure_structure(die_no, structure, idx_struct)
+ idx_struct += 1
+ continue
+
+
+ except Exception as e:
+ self._write_error(title="Prober initialization error", desc="Could not connect or initialize prober",
+ e=e, tb=traceback)
+
+ # ==================================================================================================================
+ # The individual steps for the Measurement Routine
+ # 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):
+ """
+ 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,
+ the probe is therefore on the correct input position.
+ """
+ x, y = (structure.x_in, structure.y_in)
+ self.write_log("info", f"{fmt} Move input probe/chuck to X: {x}, Y: {y}.")
+ self.prober.move_chuck(x, y)
+ chuck_x, chuck_y, chuck_z = self.prober.read_chuck_position(unit="Microns", pos_ref="Home")
+ self.write_log("info", f"{fmt} Input probe/chuck at position X: {chuck_x}, Y: {chuck_y}, Z: {chuck_z}.")
+ return chuck_x, chuck_y, chuck_z
+
+ def _step_place_output_probe(self, structure, fmt, safe_dist: float = 50):
+ x, y = (structure.x_out, structure.y_out)
+ diff_x, diff_y = (structure.in_out_diff_x, structure.in_out_diff_y)
+ self.write_log("info", f"{fmt} Move second probe to x: {x}, y: {y}) - Difference x: {diff_x}, y: {diff_y}")
+
+ # TODO: CHeck if the structure require a reposition of the probe
+ move_probe2 = True
+
+ if self.structure.in_out_diff_x > safe_dist and move_probe2:
+ self.write_log("debug",
+ f"{fmt} Optical probes in safe distance {x > safe_dist}. Moving output probe x:{diff_x}, y: {diff_y}.")
+ self.prober.opt_if.move_optical_probe(Probe.OUTPUT, diff_x, diff_y)
+ elif self.structure.in_out_diff_x < safe_dist:
+ raise Exception(f"Optical Probe Home not safe! Difference in x-direction < {safe_dist} um.")
+ else:
+ self.write_log("warning", f"Optical Probe not moved. Movement for probe disabled: {move_probe2}")
+
+ def _step_set_probes_to_measurement_height(self, height, fmt):
+ try:
+ self.write_log("info", f"{fmt} Setting probe heights to {height} um")
+ self.prober.opt_if.set_probe_height(Probe.INPUT, height)
+ self.prober.opt_if.set_probe_height(Probe.OUTPUT, height)
+ # self.msg_server.sendSciCommand("FindOpticalProbeHeight",
+ # rparams='0 %s' % self.probe_height)
+ # self.msg_server.sendSciCommand("FindOpticalProbeHeight",
+ # rparams='1 %s' % self.probe_height)
+ except Exception as e:
+ self.write_log("error",
+ f"{fmt} Cannot set probe height to {height}. {e}")
+ self.signals.error.emit((
+ type(e), f"Cannot set probe height to {height}. {e}",
+ traceback.format_exc()
+ ))
+ raise e
+
+ def _step_snap_image(self, scope_file: VFSObject, fmt):
+ # Here we adapt filename of the scope by passing the correct keywords
+ try:
+ self.write_log("info", f"{fmt} Saving scope image to {scope_file.relative}")
+ self.prober.snap_image("eVue2", scope_file.absolute, 2)
+ except Exception as e:
+ self.logger.warning(f"{fmt} Cannot save scope image to {scope_file.relative}: {e}\n\n"
+ f"{traceback.format_exc()}")
+
+ self.signals.warning.emit(type(e),
+ f"Cannot save scope image to {scope_file.relative}. {e}",
+ traceback.format_exc())
+
+ def _step_search_for_light(self, fmt):
+ # TODO: Handle if we cannot find the light
+ self.logger.info(f"{fmt} Searching for light.")
+ self.signals.write_log.emit("info", "Searching for light.")
+ input_power, output_power = self.prober.opt_if.search_for_light()
+ if input_power is None or output_power is None:
+ self.logger.warning(f"{fmt} Cannot find light. Something went wrong.")
+ self.signals.warning.emit("warning", "Cannot find light. Something went wrong.", "")
+ raise Exception('Cannot find light.')
+ else:
+ self.logger.info(f"{fmt} Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+ self.logger.info(f"{fmt} Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+ self.signals.write_log.emit("info",
+ "Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+
+ def _step_capture_transmission(self, rep, fmt):
+ self.logger.info(f"{fmt} Setting up AD2. This may take a while, please wait...")
+ self.signals.write_log.emit("info", "Setting up oscilloscope.")
+
+ #if not self.ad2device.connect_device(0):
+ # self.logger.error(f"{fmt} Could not setup ad2 device.")
+ # self.signals.error.emit("error", "Could not setup ad2 device.", "")
+ # raise Exception("Could not setup ad2 device. Script will be stopped!")
+
+ # *******************
+ # Start the measurement
+ #self.laser.start_wavelength_sweep()
+ #time.sleep(1)
+ #while self.ad2device.model.capturing_finished == False:
+ # print(f"awaiting: {self.ad2device.model.capturing_finished}")
+ # time.sleep(1)
+
+ #captured_values = self.ad2device.model.recorded_samples # Just starts an endless loop
+ #print(len(captured_values))
+ #measure_time = self.ad2device.model.recording_time
+ captured_values, measure_time = self.laser.sweep_and_measure()
+
+ self.write_log("info", f"{self.formatter} Finished data acquisition: {len(captured_values)}. Took {round(measure_time, 5)} seconds.")
+ return measure_time, captured_values
+
+ def _step_create_MeasuredSignal(self, data: pd.DataFrame, data_raw: list, wafer_properties: WaferProperties):
+ # timestamp, measure_time, time_stamps, amplitude
+
+ try:
+ cur_measured_signal = SingleMeasuredData(
+ laser_properties=self.laser.model.laser_properties,
+ ad2_properties=self.ad2device.model.ad2_properties,
+ wafer_properties=wafer_properties,
+ 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=data['timestamp'],
+ measurement_data=data_raw
+ )
+
+ # cur_measured_signal.set_prober_properties(
+ # self.vaut_config.wafer_nr,
+ # self.die_no,
+ # self.chuck_col,
+ # self.chuck_row
+ # )
+ # cur_measured_signal.set_structure_properties(self.structure)
+ # cur_measured_signal.set_ad2_properties(
+ # self.vaut_config.ad2_device_config.get_sample_rate(),
+ # self.vaut_config.ad2_device_config.get_total_samples())
+ #
+ # cur_measured_signal.set_laser_properties(
+ # self.vaut_config.laser_config.get_wavelength_range(),
+ # self.vaut_config.laser_config.get_velocity(),
+ # self.vaut_config.laser_config.get_acceleration())
+
+ return cur_measured_signal
+
+ except Exception as e:
+ self.write_log("error", f"Could not create MeasuredSignal instance from data: {e}")
+ self.signals.error.emit((type(e),
+ f"Could not create MeasuredSignal instance from data: {e}",
+ traceback.format_exc()))
+ raise e
+
+ # Routine for measuring one structure
+ def _measure_structure(self, die_no: int, structure: Structure, structure_idx: int):
+ """Routine for measuring one structure
+
+ """
+ self.structure: Structure = structure
+ self.formatter = f"[Measurement. Die {die_no}]: {self.structure.name} |"
+ timestamp = datetime.now().strftime('%d/%m/%Y %H:%M:%S.%f')
+
+ if not self.structure.enabled:
+ self.write_log("info", f"Structure {self.structure.name} is disabled, skipping!")
+ return
+
+ self.write_log("info", f"{self.formatter} Processing structure {self.structure.name}.")
+ # Report the current structure information to the frontend
+ self.signals.report_info.emit({
+ "die_no": self.die_no, "chuck_col": self.chuck_col,
+ "chuck_row": self.chuck_row, "structure": self.structure.name,
+ "repetition": self.structure.repetitions
+ })
+ self.write_log("info", f"{self.formatter} "
+ f"die_no: {self.die_no}, chuck_col: {self.chuck_col}, "
+ f"chuck_row: {self.chuck_row}, structure: {self.structure.name}, "
+ f"repetition: {self.structure.repetitions}"
+ )
+
+ # 1. Move the first probe/chuck
+ self._step_place_input_probe(self.structure, self.formatter)
+
+ # 2. Move the second probe
+ self._step_place_output_probe(self.structure, self.formatter)
+
+ # 3. Setting the probe height to 80 um
+ self._step_set_probes_to_measurement_height(80, self.formatter)
+
+ # 4. Snap an image
+ # Create the correct file for the scope image
+ # self.vaut_config.wafer_config.get_scope_image_file().set_obj(
+ # keywords={"{die}": self.die_no, "{structure}": self.structure.name, "{it}": 1})
+ self._step_snap_image(self.vaut_config.wafer_config.get_scope_image_file(
+ keywords={"{die}": self.die_no, "{structure}": self.structure.name}), self.formatter)
+
+ # Search for the light
+ self._step_search_for_light(self.formatter)
+
+ amplitude = []
+ time_stamps = []
+ rep = 1
+
+ while rep <= self.structure.repetitions:
+ # *******************
+ # Stop the measurement
+ # For displaying the data in the GUI
+ measure_time, captured_values = self._step_capture_transmission(rep, self.formatter)
+ data = [[
+ self.vaut_config.wafer_nr, self.die_no, self.chuck_col,
+ self.chuck_row, timestamp, str(self.structure), rep,
+ self.structure.x_in, self.structure.y_in,
+ self.structure.x_out, self.structure.y_out,
+ measure_time, str(time_stamps), captured_values
+ ]]
+ self.siph_data = pd.concat([self.siph_data, pd.DataFrame(data, columns=self.columns)])
+
+ try:
+ self.siph_data.to_csv(str(self.vaut_config.wafer_config.get_measurement_output()))
+ self.siph_data.to_excel(
+ str(self.vaut_config.wafer_config.get_measurement_output()).replace('csv', 'xlsx'))
+ except Exception as e:
+ self._write_error("Write SiPh", f"Could not write sphi data to file "
+ f"{self.vaut_config.wafer_config.get_measurement_output()}", e,
+ traceback)
+ self.signals.error.emit((type(e),
+ f"Could not write sphi data to file "
+ f"{self.vaut_config.wafer_config.get_measurement_output()}: {e}",
+ traceback.format_exc()))
+
+ wafer_properties = WaferProperties(
+ wafer_number=self.vaut_config.wafer_nr,
+ structure_name=self.structure.name,
+ die_nr=self.die_no,
+ chuck_col=self.chuck_col,
+ chuck_row=self.chuck_row,
+ structure_in=(self.structure.x_in, self.structure.y_in),
+ structure_out=(self.structure.x_out, self.structure.y_out),
+ repetitions=rep)
+
+ cur_measured_signal = self._step_create_MeasuredSignal(
+ self.siph_data,
+ captured_values,
+ wafer_properties)
+
+ cur_measured_signal._save_mat_file(
+ filename=self.vaut_config.wafer_config.get_measurement_mat_file(keywords={"{die}": self.die_no,
+ "{structure}": self.structure.name,
+ "{it}": f"rep_{rep + 1}"}).absolute
+ )
+
+
+ rep += 1
+ self.logger.info(f"Repetition {rep}/{self.structure.repetitions} measured successfully!")
+ self.signals.routine_iteration_finished.emit(cur_measured_signal, rep)
+ # Report the progress to the frontend
+ self.write_log("info", "[OK] Continuing with next structure.")
+ # idx_struct = idx_struct + 1
diff --git a/src/FlexSensor/MeasurementRoutines/WorkerSignals.py b/src/FlexSensor/MeasurementRoutines/WorkerSignals.py
new file mode 100644
index 0000000000000000000000000000000000000000..50eda1e84b4859872c1b22f55582d5a0642f22b6
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/WorkerSignals.py
@@ -0,0 +1,23 @@
+from PySide6.QtCore import QObject, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class WorkerSignals(QObject):
+
+ finished = Signal()
+
+ error = Signal(tuple)
+
+ warning = Signal(tuple)
+
+ result = Signal(object)
+
+ progress = Signal(float)
+
+ # Reports the measured data and the iteration number
+ routine_iteration_finished = Signal(SingleMeasuredData, int)
+
+ write_log = Signal(str, str)
+
+ report_info = Signal(dict)
diff --git a/src/FlexSensor/MeasurementRoutines/__init__.py b/src/FlexSensor/MeasurementRoutines/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui b/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..8cae92507faa3ed421f4ea9019cfe5552ca16be0
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MeasurementControlFlow</class>
+ <widget class="QWidget" name="MeasurementControlFlow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QListView" name="listView_control_flow"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/MeasurementRoutines/ressources/convert.sh b/src/FlexSensor/MeasurementRoutines/ressources/convert.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c317f21e29daef33cbd1dba83f08f1e10c242004
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/ressources/convert.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Convert .ui files to .py files
+for ui in *.ui; do
+ pyside6-uic $ui > ../view/Ui_${ui%.*}.py
+done
+ pyside6-rcc ../../resources.qrc -o ../../resources_rc.py
diff --git a/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py b/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ec6b4ba0aae77f186b423b109b20db74583d0fa
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py
@@ -0,0 +1,9 @@
+from MeasurementRoutines.view.Ui_MeasurementControlFlow import Ui_MeasurementControlFlow
+
+
+class MeasurementControlFlow():
+ def __init__(self, measurementRoutine: BaseMeasurementRoutine):
+ # Init the UI file
+ self._ui = Ui_MeasurementControlFlow()
+ self._ui.setupUi(self)
+
diff --git a/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py b/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb1b0e958f3426e2f913b70b87cb3e284891723b
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'MeasurementControlFlow.ui'
+##
+## Created by: Qt User Interface Compiler version 6.5.2
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QGridLayout, QListView, QSizePolicy,
+ QWidget)
+
+class Ui_MeasurementControlFlow(object):
+ def setupUi(self, MeasurementControlFlow):
+ if not MeasurementControlFlow.objectName():
+ MeasurementControlFlow.setObjectName(u"MeasurementControlFlow")
+ MeasurementControlFlow.resize(400, 300)
+ self.gridLayout_2 = QGridLayout(MeasurementControlFlow)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.gridLayout = QGridLayout()
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.listView_control_flow = QListView(MeasurementControlFlow)
+ self.listView_control_flow.setObjectName(u"listView_control_flow")
+
+ self.gridLayout.addWidget(self.listView_control_flow, 0, 0, 1, 1)
+
+
+ self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
+
+
+ self.retranslateUi(MeasurementControlFlow)
+
+ QMetaObject.connectSlotsByName(MeasurementControlFlow)
+ # setupUi
+
+ def retranslateUi(self, MeasurementControlFlow):
+ MeasurementControlFlow.setWindowTitle(QCoreApplication.translate("MeasurementControlFlow", u"Form", None))
+ # retranslateUi
+
diff --git a/src/FlexSensor/Prober/__init__.py b/src/FlexSensor/Prober/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9885c767677d0fc7299511b1dfe724dd43e186d
--- /dev/null
+++ b/src/FlexSensor/Prober/__init__.py
@@ -0,0 +1,20 @@
+import os
+
+if os.environ.get('VELOX_SIM') is not None:
+ print("Velox Simulator")
+ from Prober.velox_api.simulator import VeloxSimulator as velox_api
+ from Prober.velox_api.simulator.VeloxSimulator import (MessageServerInterface, SetChuckHome, SetMapHome,
+ ReadChuckPosition, ReadChuckHeights, MoveChuck,
+ SnapImage, GetDieDataAsColRow, StepToDie, ReportKernelVersion)
+else:
+ import Prober.velox_api.velox as velox_api
+ from Prober.velox_api.velox import (MessageServerInterface, SetChuckHome, SetMapHome,
+ ReadChuckPosition, ReadChuckHeights, MoveChuck,
+ SnapImage, GetDieDataAsColRow, StepToDie, ReportKernelVersion)
+
+from Prober.model.ProberModel import ProberModel as Model
+from Prober.view.ProberControlWindow import ProberControlWindow as ControlWindow
+from Prober.model.ProberModel import ProberSignals as Signals
+from Prober.controller.ProberController import ProberController as Controller
+from Prober.controller.ProberController import Probe as Probe
+from Prober.controller.OpticalProbesPosition import OpticalProbesPosition as ProbePosition
diff --git a/src/FlexSensor/Prober/controller/MapFileParser.py b/src/FlexSensor/Prober/controller/MapFileParser.py
new file mode 100644
index 0000000000000000000000000000000000000000..570944889faa3228452576403bfa3f93a8857ddf
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/MapFileParser.py
@@ -0,0 +1,33 @@
+from pathlib import Path
+
+
+class MapFileParser:
+
+ def __init__(self, path: str):
+ print(path)
+ self._map_path = Path(path)
+ with open(self._map_path, 'r') as file:
+ self.result = self.parse_content(file.read())
+
+ def parse_content(self, content):
+ result = {}
+ current_section = None
+
+ lines = content.split("\n")
+ for line in lines:
+ line = line.strip()
+ if line.startswith("[") and line.endswith("]"):
+ current_section = line[1:-1]
+ elif "=" in line and current_section is not None:
+ key, value = line.split("=", 1)
+ result.setdefault(current_section, {})
+ result[current_section][key] = value
+
+ return result
+
+
+if __name__ == "__main__":
+ parsed_map = MapFileParser("../Wafermapary1_48dies.map")
+ print(parsed_map.result["Header"]["Description"]) # Output: Wafer Map File
+ print(parsed_map.result["Wafer"]["Diameter"]) # Output: 200
+ print(parsed_map.result["Bin"]["0"]) # Output: 1,a0,00C000,1,0,0,0,0
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/controller/OpticalInterface.py b/src/FlexSensor/Prober/controller/OpticalInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d1cb934953988128ad9365d85a7de13305083b2
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/OpticalInterface.py
@@ -0,0 +1,277 @@
+import logging
+
+from Prober.model.OpticalInterfaceModel import OpticalInterfaceModel
+from Prober.model.OpticalInterfaceStoredData import OpticalInterfaceStoredData
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+
+
+
+
+
+
+
+
+
+
+
+class OpticalInterface(object):
+
+ def __init__(self, prober_signals, msg_server):
+ self.stored = OpticalInterfaceStoredData()
+ self.signals = prober_signals
+ self.msg_server = msg_server
+ self.logger = logging.getLogger("Optical Interface")
+ self.logger.info("Optical Interface initialized")
+
+ # ==================================================================================================================
+ # pythonized api calls
+ # ==================================================================================================================
+
+ def enable_flight_height_control(self, enable_in=True, enable_out=True):
+ # Disable Flight Height Control
+ for probe_num, val in enumerate((int(enable_in), int(enable_out))):
+ cmd = 'TrackOpticalProbeHeight'
+ rparams = f"{probe_num} {val}"
+
+ enable = bool(val)
+ enable_desc = 'Enable' if enable else 'Disable'
+ probe_desc = 'first probe/input probe' if probe_num == 0 else 'second probe/output probe'
+ command_desc = f'{cmd}({rparams})'
+ self.logger.info(f"[OptIF Task] - {enable_desc} `Flight Height Control` "
+ f"for {probe_desc}. Issuing command '{command_desc}'")
+ self.signals.log_info.emit("OptIF", f" {enable_desc} 'Flight Height Control' "
+ f"for {probe_desc}.", None)
+ self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+ def set_probe_height(self, probe: int, height):
+ cmd = 'FindOpticalProbeHeight'
+ rparams = f"{probe} {height}"
+
+ probe_desc = 'first probe/input probe' if probe == 0 else 'second probe/output probe'
+ command_desc = f'{cmd}({rparams})'
+
+ self.logger.info(f"[OptIF Task] - Move {probe_desc} height to {height} um. "
+ f"Issuing command '{command_desc}'")
+ self.signals.log_info.emit("OptIF Task", f" Move {probe_desc} height to {height} um.", None)
+ self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+ def move_optical_probe(self, probe: int, x, y, pos_ref='H'):
+ """
+ Move selected probe motor in XY.
+ :param probe 0=Input, 1=Output (I)
+ :param x motor command [um] (D)
+ :param y motor command [um] (D)
+ :param pos_ref R=Relative, H=Home, Z=Zero (C)
+ """
+ cmd = 'MoveOpticalProbe'
+ rparams = f"{probe} {x} {y} {pos_ref}"
+ command_desc = f'{cmd}({rparams})'
+ self.logger.info(f"[OptIF Task] - Move selected probe motor. "
+ f"Issuing command '{command_desc}'")
+ self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+ def move_pzt(self, probe: int, x, y, z, pos_ref='H'):
+ """
+ Pythonized command for SiP Remote Interface 'MovePZT'
+ Move selected PZT.
+ :param probe: 0=Input, 1=Output (I)
+ :param x: x PZT command [um] (D)
+ :param y: y PZT command [um] (D)
+ :param z: z PZT command [um] (D)
+ :param pos_ref: PosRef R=Relative, H=Home, Z=Zero (C)
+ """
+ cmd = "MovePZT"
+ rparams = f"{probe} {x} {y} {z} {pos_ref}"
+ self.logger.info(f"[OptIF Task] - Move selected PZT.")
+ return self._send_command(cmd, rparams=rparams,
+ desc=f"{cmd}(probe={probe}, x={x}, y={y}, z={z}, posref={pos_ref})")
+
+ def recenter_optical_probe(self, probe: int):
+ cmd = 'RecenterOpticalProbe'
+ rparams = f"{probe}"
+
+ probe_desc = 'first probe/input probe' if probe == 0 else 'second probe/output probe'
+ command_desc = f'{cmd}({rparams})'
+
+ self.logger.info(f"[OptIF Task] - Recenter {probe_desc}. "
+ f"Issuing command '{command_desc}'")
+ self.signals.log_info.emit("OptIF Task", f"Recenter {probe_desc}.", None)
+
+ self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+ def area_scan(self, probe_in: bool = True, probe_out: bool = True):
+ cmd = 'AreaScan'
+ probe_in, probe_out = (int(probe_in), int(probe_out))
+ rparams = f"{probe_in} {probe_out}"
+
+ if probe_in == 1 and probe_out == 1:
+ probe_desc = 'input and output probe'
+ elif probe_in == 1 and probe_out == 0:
+ probe_desc = 'first probe/input probe'
+ elif probe_in == 0 and probe_out == 1:
+ probe_desc = 'second probe/output probe'
+ else:
+ raise ValueError("area_scan requires at least one probe to be selected.")
+
+ command_desc = f'{cmd}({rparams})'
+
+ self.logger.info(f"[OptIF Task] - Performing area scan on {probe_desc}. "
+ f"Issuing command '{command_desc}'")
+ self.signals.log_info.emit("OptIF Task", f"Performing area scan on {probe_desc}", None)
+
+ x_1, x_2, y_1, y_2, input_power, output_power = self.msg_server.sendSciCommand(cmd, rparams=rparams)
+ return x_1, x_2, y_1, y_2, self.conv_pwr(input_power), self.conv_pwr(output_power)
+
+ def set_optical_probe_home(self, probe: int) -> (int, int, int, int, int, int):
+ cmd = 'SetOpticalProbeHome'
+ rparams = f"{probe}"
+ return self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+ def read_optical_probe_pos(self, probe, pos_ref='H') -> (float, float, float, float, float, float):
+ """
+ Pythonized command for SiP Remote Interface 'ReadOpticalProbePos'
+ Read optical probe position.
+ :param probe: 0=Input, 1=Output (I)
+ :param pos_ref: H=Home, Z=Zero (C)
+ :return:
+ x1: x motor position [um]
+ y1: y motor position [um]
+ z1: z motor position [um]
+ x2: x motor PZT [um]
+ y2: y PZT position [um]
+ z2: x PZT position [um]
+ """
+ cmd = "ReadOpticalProbePos"
+ rparams = f"{probe} {pos_ref}"
+ self.logger.info(f"[OptIF Task] - Reading optical probe position. ")
+ return self._send_command(cmd, rparams=rparams, desc=f"{cmd}(probe={probe}, posref={pos_ref})")
+
+
+ # ==================================================================================================================
+ # Custom implementations I
+ # ==================================================================================================================
+ def _send_command(self, cmd: str, rparams: str = None, desc: str = None):
+
+ issuing_command = f'{cmd}({rparams})'
+ if desc is not None:
+ self.logger.debug(f"Issuing command {desc} -> '{issuing_command}'")
+ else:
+ self.logger.debug(f"Issuing command '{issuing_command}'")
+
+ self.signals.log_info.emit("OptIF Task", f"Issuing command '{issuing_command}'", None)
+ r = self.msg_server.sendSciCommand(cmd, rparams=rparams)
+ self.logger.debug(f"Command returned '{r}'")
+ return r
+
+ # ==================================================================================================================
+ # Custom implementations II
+ # ==================================================================================================================
+ def conv_pwr(self, power: list | str | float | int) -> float:
+ """
+ Area scan return different types for the power values, this function can convert it.
+ """
+ try:
+ if isinstance(power, list):
+ power = float(power[0])
+ elif isinstance(power, str):
+ if "na" == power.lower:
+ power = -80
+ else:
+ power = float(power)
+ else:
+ power = float(power)
+ except Exception as e:
+ power = -80
+ print(f"Cant convert <{power}>: {e}")
+ return float(power)
+
+ def _recenter_and_scan(self) -> (float, float, float, float, float, float):
+ self.recenter_optical_probe(Probe.INPUT)
+ self.recenter_optical_probe(Probe.OUTPUT)
+ x_1, x_2, y_1, y_2, input_power, output_power = self.area_scan(True, True)
+ return float(x_1), float(x_2), float(y_1), float(y_2), self.conv_pwr(input_power), self.conv_pwr(
+ 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.signals.log_debug.emit("OptIF Task", f"*** Search for light ***", None)
+
+ # Recenter the probes, perform an area scan, recenter again.
+ self.logger.info(f"[OptIF Task] - Recenter optical probes and performing area scan (1/2).")
+ self.signals.log_info.emit("OptIF Task", f"Recenter optical probes (1/2).", None)
+ self._recenter_and_scan()
+
+ self.logger.info(f"[OptIF Task] - Recenter optical probes and performing area scan (2/2).")
+ self.signals.log_info.emit("OptIF Task", f"Recenter optical probes (2/2).", None)
+ x_1, x_2, y_1, y_2, input_power, output_power = self._recenter_and_scan()
+
+ # Now we need to verify the power
+ self.logger.info(f"[OptIF Task] - Verifying power. Probe input power: {input_power}. "
+ f"Probe output power {output_power}. "
+ f"Abortion criteria is {threshold}/{threshold_areascan} or {retries} retries.")
+ self.signals.log_info.emit("OptIF Task", f"Probe input power: {input_power}. "
+ f"Probe output power {output_power}.", None)
+ while (
+ ((input_power < threshold_areascan and output_power >= threshold) or
+ (output_power < threshold_areascan and input_power >= threshold)) and
+ retries > 0
+ ):
+ self.logger.info(f"[OptIF Task] - Input power ({input_power}) or output power ({output_power}) "
+ f"too low but signal found. Trying area scan again ({retries - 1} "
+ f"retrie(s) left). Threshold is {threshold_areascan}")
+ self.signals.log_info.emit("OptIF Task",
+ f"Input power ({input_power}) or output power ({output_power}) "
+ f"too low but signal found. ", None)
+ 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.signals.log_debug.emit("OptIF Task", f"*** Search for light completed***", None)
+ return input_power, output_power
+
+ # ==================================================================================================================
+ # Store and load functions
+ # ==================================================================================================================
+ def store_optical_probe_motor_pos(self) -> (float, float, float, float, float, float):
+ """
+ Stores the current motor position of the optical probe .
+ """
+ self.stored.motor_in_x, self.stored.motor_in_y, self.stored.motor_in_z, \
+ _, _, _ = self.read_optical_probe_pos(0)
+
+ self.stored.motor_out_x, self.stored.motor_out_y, self.stored.motor_out_z, \
+ _, _, _ = self.read_optical_probe_pos(1)
+
+ def store_optical_probe_pzt_pos(self) -> (float, float, float, float, float, float):
+ """
+ Stores the current PZT position of the optical probe .
+ """
+ _, _, _, self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z = self.read_optical_probe_pos(0)
+
+ _, _, _, self.stored.pzt_out_x, self.stored.pzt_out_y, self.stored.pzt_out_z = self.read_optical_probe_pos(1)
+
+ def store_optical_probe_pos(self) -> (float, float, float, float, float, float):
+ """
+ Stores the current motor position of the optical probe .
+ """
+ self.stored.motor_in_x, self.stored.motor_in_y, self.stored.motor_in_z, \
+ self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z = self.read_optical_probe_pos(0)
+
+ self.stored.motor_out_x, self.stored.motor_out_y, self.stored.motor_out_z, \
+ self.stored.pzt_out_x, self.stored.pzt_out_y, self.stored.pzt_out_z = self.read_optical_probe_pos(1)
+
+ def restore_optical_probe_motor_pos(self, probe: int) -> (float, float, float, float, float, float):
+ self.move_optical_probe(probe, self.stored.motor_in_x, self.stored.motor_in_y, pos_ref='H')
+ return self.read_optical_probe_pos(probe)
+
+ def restore_optical_probe_pzt_pos(self, probe: int) -> (float, float, float, float, float, float):
+ self.move_pzt(probe, self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z, pos_ref='H')
+ return self.read_optical_probe_pos(probe)
+
+ # ==================================================================================================================
+ # Store and load functions
+ # ==================================================================================================================
+
diff --git a/src/FlexSensor/Prober/controller/OpticalProbesPosition.py b/src/FlexSensor/Prober/controller/OpticalProbesPosition.py
new file mode 100644
index 0000000000000000000000000000000000000000..19e061486ebbf6887f9f7ad90bfd226d4b8d5b34
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/OpticalProbesPosition.py
@@ -0,0 +1,27 @@
+import sys
+import logging
+
+
+class OpticalProbesPosition:
+
+ def __init__(self, input: tuple, output: tuple):
+ self.INPUT: ProbePosition = ProbePosition(input)
+ self.OUT: ProbePosition = ProbePosition(output)
+ self.logger = logging.getLogger('OpticalProbesPosition')
+
+
+ def __str__(self):
+ return f"INPUT: {self.INPUT} | OUT: {self.OUT}"
+
+
+class ProbePosition:
+
+ def __init__(self, position: tuple):
+ self.x, self.y, self.z = position
+
+ def __str__(self):
+ return f"x:{self.x} - y:{self.y} - z:{self.z}"
+
+ def __substract__(self, other):
+ pass
+
diff --git a/src/FlexSensor/Prober/controller/ProberController.py b/src/FlexSensor/Prober/controller/ProberController.py
new file mode 100644
index 0000000000000000000000000000000000000000..7486b757787535dd513f8cdd5fdc2d9c975cb130
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/ProberController.py
@@ -0,0 +1,411 @@
+import logging
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Prober.controller.OpticalInterface import OpticalInterface
+import Prober
+from Prober.model.ProberModel import ProberModel
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+class ProberController:
+ def __init__(self, model: ProberModel, vaut_config: VAutomatorConfig, *args, **kwargs):
+
+ self.vaut_config = vaut_config
+ self.model = model
+
+ self.model.wafer_map = self.vaut_config.wafer_config.wafermap_file
+
+ self.logger = logging.getLogger("Prober")
+ self.signals = Prober.Signals()
+ self.msg_server = Prober.MessageServerInterface()
+
+ # Optical Interface Control hexapods and piezos
+ self.opt_if = OpticalInterface(self.signals, self.msg_server)
+ self.logger.info("Prober initialized")
+
+ self.model.version = self.report_kernel_version()
+ self.get_die_as_col_row()
+ self.read_chuck_position()
+ self.model.connected = True
+
+ # ==================================================================================================================
+ # Velox API Calls.
+ # Some Wrappers to the official Velox API calls
+ # ==================================================================================================================
+ def set_chuck_home(self, mode: str = '0', unit: str = 'Y', x_value: float = 0, y_value: float = 0):
+ """ Velox API Call. Sets wafer and die home position, which can be used later as coordinate system
+ for movements.
+ Keyword arguments:
+ mode: str -- '0' use the current position or the given value otherwise. (default "0")
+ unit: str -- Sets the unit (Y: 'Microns' or I 'Mils'). Required if mode is not set to default (Y).
+ (default 'Microns')
+ x_value: float -- Required if mode is not set to V. (default 0)
+ y_value: float -- Required if mode is not set to V. (default 0)
+ Command Timeout: 5000
+ """
+ self.logger.info(f"[Prober Task] - Set Chuck home. Issuing command 'SetChuckHome({mode})'")
+ self.signals.log_info.emit("Prober Report", f"Set Chuck Home.", None)
+ Prober.SetChuckHome(str(mode), str(unit), x_value, y_value)
+
+ def set_map_home(self, col=0, row=0):
+ """ Velox API Call. If the command has no parameters it sets the current position as home position
+ both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+ home position using the given die coordinates.
+ Keyword arguments:
+ col: int -- Column (optional). (default 0)
+ row: int -- Row (optional). (default 0)
+ Command Timeout: 10000
+ """
+ self.logger.info(f"[Prober Task] - Set Map home to col {col} and row {row}. "
+ f"Issuing command 'SetMapHome({col}, {row})'")
+ self.signals.log_info.emit("Prober Report", f"Map Home set to {col}, {row}.", None)
+ Prober.SetMapHome(col, row)
+
+ def read_chuck_position(self, unit: str = "Microns", pos_ref: str = "Home", comp: str = "Default") -> (float, float, float):
+ """ Velox API Call. Returns the current chuck stage position in X, Y and Z.
+ Args:
+ unit:str = "Microns"
+ pos_ref:str = "Home"
+ comp:str = "Default"
+ Returns:
+ X:float
+ Y:float
+ Z:float
+ Command Timeout: 5000
+ """
+ self.model._chuck_x, self.model._chuck_y, self.model._chuck_z = Prober.ReadChuckPosition(Unit=unit, PosRef=pos_ref)
+ self.logger.info(f"[Prober Report] - "
+ f"Current Chuck position X:{self.model._chuck_x} Y:{ self.model._chuck_y} Z:{self.model._chuck_z}")
+ self.signals.log_info.emit("Prober Report",
+ f"Current Chuck position "
+ f"X:{self.model._chuck_x} "
+ f"Y:{ self.model._chuck_y} "
+ f"Z:{self.model._chuck_z}", None)
+ return float(self.model._chuck_x), float(self.model._chuck_y), float(self.model._chuck_z)
+
+ def check_contact_height_set(self) -> (float, float, float, float, float):
+ """ Velox API Call. Returns the current settings used for the chuck Z movement. `Contact` is the
+ contact-height from zero in default compensation. The other heights are relative
+ to this. If no contact is set, an error will be raised.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ SearchGap:Decimal
+ Command Timeout: 5000
+ """
+ self.logger.debug("[Prober Task] - Check if contact height is set. Issuing command 'ReadChuckHeights'")
+ self.signals.log_debug.emit("Prober Task", "Check if contact height is set. Issuing command 'ReadChuckHeights'",
+ None)
+ contact, overtravel, align_dist, sep_dis, search_gap = Prober.ReadChuckHeights()
+
+ if contact == -1:
+ self.logger.error("[Prober Task] - Contact height not set, please set it before running this script. "
+ "Script will be stopped.")
+ raise Exception("Contact height not set, please set it before running this script. Script will be stopped.")
+
+ self.logger.debug(f"[Prober Task] - Contact height set to {contact}")
+ self.signals.log_debug.emit("Prober Task", f"Contact height set to {contact}", None)
+
+ return float(contact), float(overtravel), float(align_dist), float(sep_dis), float(search_gap)
+
+ def move_chuck(self, x_value: float = 0, y_value: float = 0,
+ pos_ref: str = "H", unit: str = "Y", velocity: float = 100, comp: str = "D"):
+ """ Velox API Call. Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+ height or higher, Interlock and Auto Z flags will be analyzed and stage will
+ behave correspondingly - can move to separation first or return an error:
+ Keyword arguments:
+ x_value:float -- X Value (optional). (default 0)
+ y_value:float -- Y Value (optional). (default 0)
+ pos_ref:str -- "H: Home", "Z: Zero", "C: Center", "R: Current Position". (default "H: Home")
+ unit:str -- "Y: Microns", "I: Mils", "X: Index", "J: Jog". (default "M: Microns")
+ velocity:float -- Velocity in percent. (default 100)
+ comp:str
+ "D: Default": Use the default compensation. Uses "Technology" by default.
+ "T: Technology": Use Prober, offset and Technology compensation. (default)
+ "O: Offset": Use Prober and Offset compensation.
+ "P: Prober" Use only Prober compensation.
+ "N: None": Does not use compensation.
+ (default "D: Default")
+ Command Timeout: 30000
+ """
+ self.logger.debug(f"[Prober Task] - Move Chuck to x: {x_value} y: {y_value}. "
+ f"Issuing command 'MoveChuck({x_value}, {y_value}, {pos_ref}, {unit}, {velocity}, {comp})'")
+ self.signals.log_debug.emit("Prober Task", f"Move Chuck to x: {x_value} y: {y_value}", None)
+ Prober.MoveChuck(x_value, y_value, pos_ref, unit, velocity, comp)
+
+ def snap_image(self, mount_pos: str = "eVue2", full_path: str = "./Image.bmp", snap_shot_mode: int = 2):
+ """
+ Velox API Call. Saves the currently displayed image to the specified file. The image is stored
+ in the requested file format (bmp, jpg or png). By default. it will save the raw
+ camera image and an image with the overlays that are currently visible on the
+ camera view. Using a parameter, one can decide to only save either raw image,
+ overlay image or both. By Specifying 'ALL' as the mount position, the captured
+ screenshot will consist of the currently selected camera layout without
+ providing the raw image. If MountPos and FullPath are empty then the current
+ camera view with overlays is copied to the clipboard.
+ API Status: published
+ Args:
+ mount_pos:str -- Mount position of camera from which the image will be taken:
+ 'Scope', 'eVue1', 'eVue2', 'eVue3', 'Chuck', 'Platen', 'ContactView', or 'All'.
+ (default "eVue2")
+
+ (If you use ‘Scope’ on a system with eVue, the image will be from eVue2).
+ If set to ‘All’ the currently visible camera layout will be captured in the screenshot
+ "eVue2".
+ full_path:str -- Path where the image will be stored. (default: "./Image.bmp")
+ snap_shot_mode:int -- Type of snapshot (default 2)
+ 0 – Raw Image from camera
+ 1 – Screenshot of camera window including overlays;
+ 2 – Both images
+ Example:SnapImage Scope C:/Temp/Image.bmp
+ """
+ self.logger.debug(f"[Prober Task] - Save scope image {mount_pos} to {full_path} (mode: {snap_shot_mode}). "
+ f"Issuing command 'SnapImage({mount_pos}, {full_path}, {snap_shot_mode})'")
+ self.signals.log_debug.emit("Prober Task",
+ f"Save scope image {mount_pos} to {full_path} (mode: {snap_shot_mode}).", None)
+ Prober.SnapImage(mount_pos, full_path, snap_shot_mode)
+
+ def report_kernel_version(self):
+ v = Prober.ReportKernelVersion()
+ self.model.kernel_version = str(v.Version) + "." + str(v.Description)
+ return str(v.Version) + "." + str(v.Description)
+
+ def get_die_as_col_row(self):
+ # Read the die data: die number, col, row
+ self.model.die, self.model.die_col, self.model.die_row, bin, res = Prober.GetDieDataAsColRow()
+ self.logger.info(f"[Prober Report] - Current die number: {self.model.die} "
+ f"(col: {self.model.die_col}, row: {self.model.die_row})")
+ self.signals.log_info.emit("Prober Report", f"Current die number: {self.model.die} "
+ f"(col: {self.model.die_col}, row: {self.model.die_row})", None)
+ return self.model.die, self.model.die_col, self.model.die_row
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def move_to_die(self, die_num=0) -> (float, float, float):
+ '''
+ Move to the specified die and sets the home position accordingly
+ '''
+
+ # TODO: check if die is in the correct position and check if height is correct
+ self.logger.debug(f"[Prober Task] - {pch('*', 20)} Moving to die {die_num} {pch('*', 20)}")
+ self.signals.log_debug.emit("Prober Task", f"*** Moving to die {die_num} ***", None)
+
+ # We need to make sure that our fiber height is correct
+ # TODO: Check fiber height - this is important! IMPLEMENT HERE
+ # ...
+ # ...
+ # raise NotImplementedError("Check fiber hight not implemented yet")
+
+ # Move to die
+ # Disable the flight height control
+ self.opt_if.enable_flight_height_control(enable_in=False, enable_out=False)
+
+ # FindOpticalProbeHeight(0, 100)
+ # FindOpticalProbeHeight(1, 100)
+
+ # Step to the specified die
+ self.logger.info(f"[Prober Task] - Step to the specified die {die_num}. Issuing command 'StepToDie({die_num})'")
+ self.signals.log_info.emit("Prober Task", f"Step to the specified die {die_num}", None)
+ Prober.StepToDie(die_num)
+
+ # 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)
+
+ # 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()
+
+ # Set the current chuck and map to home
+ self.set_chuck_home()
+ self.set_map_home(self.model.die_col, self.model.die_row)
+
+ # For reducing errors, read the chuck position
+ self.model._chuck_x, self.model._chuck_y, self.model._chuck_z = self.read_chuck_position(unit="Microns", pos_ref="Home")
+
+ self.logger.info(f"[Prober Task] - {pch('*', 20)} MOVING TO DIE COMPLETE {pch('*', 20)}")
+ self.signals.log_info.emit("Prober Report", f"MOVING TO DIE COMPLETE", None)
+ return self.model.die, self.model.die_col, self.model.die_row
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+
+ def try_finding_light(self, input_power, output_power, threshold=-70):
+ ran_in = [0, 5, -5, 10, -10, 15, -15, 20, -20, 25, 30, 35, 40, -25, -30, -35, -40]
+ ran_out = ran_in
+ # steps = 5
+
+ input_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='0')
+ input_power = self.conv_result_power(input_power)
+
+ output_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='1')
+ output_power = self.conv_result_power(output_power)
+
+ for x_pos_1 in ran_in:
+ for y_pos_1 in ran_in:
+ try:
+ self.msg_server.sendSciCommand("MoveOpticalProbe",
+ rparams='0 %s %s R' % ((float(x_pos_1)), (float(y_pos_1))))
+ except Exception as e:
+ self.write_log("error", "Can't move probe to (%s, %s)" % (x_pos_1, y_pos_1))
+ self.write_log("error", e)
+ continue
+
+ for x_pos_2 in ran_out:
+ for y_pos_2 in ran_out:
+ self.write_log("debug",
+ f"{self.formatter} Moving realtivly: Probe 1 X({float(x_pos_1)}) Y({float(y_pos_1)}) "
+ f"| Probe 2 X({float(x_pos_2)}) Y({float(y_pos_2)}) | Power I:{input_power} O:{output_power}")
+
+ self.msg_server.sendSciCommand("MoveOpticalProbe",
+ rparams='1 %s %s R' % ((float(x_pos_2)), (float(y_pos_2))))
+
+ input_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='0')
+ output_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='1')
+ input_power = self.conv_result_power(input_power)
+ output_power = self.conv_result_power(output_power)
+
+ if (float(input_power) > -72) or (float(output_power) > -72):
+ try:
+ self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+ self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='0')
+ self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='1')
+ self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+ self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='0')
+ self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='1')
+ self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+ if (float(input_power) > threshold) or (float(output_power) > threshold):
+ self.write_log("debug", f"Power I:{input_power} O:{output_power}. Continuing.")
+ return True
+ except Exception as e:
+ self.write_log(f"warning {e}")
+
+ self.write_log("debug",
+ f"{self.formatter} Moving back: Probe 1 X({(-1) * float(x_pos_1)}) Y({(-1) * float(y_pos_1)}) "
+ f"| Probe 2 X({(-1) * float(x_pos_2)}) Y({(-1) * float(y_pos_2)}) | Power I:{input_power} O:{output_power}")
+ self.msg_server.sendSciCommand("MoveOpticalProbe", rparams='0 %s %s R' % (
+ ((-1) * float(x_pos_1)), ((-1) * float(y_pos_1))))
+ self.msg_server.sendSciCommand("MoveOpticalProbe", rparams='1 %s %s R' % (
+ ((-1) * float(x_pos_2)), ((-1) * float(y_pos_2))))
+
+ self.write_log("warning", "No light found.")
+ return False
+
+ def store_hexapod_position():
+ """
+ Stores the hexpods and nanocube position for later retrieval
+ """
+ pass
+
+
+ # msgServer.sendSciCommand("MoveOpticalProbe", rparams='0 %s %s R' % ( (-1)*(float(x_pos_1)), (-1)*(float(y_pos_1))))
+
+ def get_hexapod_values(self):
+ # before performing an area scan, store the current position
+ try:
+ motor_x_1, motor_y_1, motor_z_1, pzt_x_1, pzt_y_1, pzt_z_1 = self.msg_server.sendSciCommand(
+ "ReadOpticalProbePos", rparams='0 H')
+ motor_x_2, motor_y_2, motor_z_2, pzt_x_2, pzt_y_2, pzt_z_2 = self.msg_server.sendSciCommand(
+ "ReadOpticalProbePos", rparams='1 H')
+ self.write_log("info",
+ "([%s]: %s): Storing reference values for motor 1 (%s, %s, %s) Storing values for PZT 1 (%s, %s, %s). "
+ % (self.die_no, self.structure, motor_x_1, motor_y_1, motor_z_1, pzt_x_1, pzt_y_1, pzt_z_1)
+ )
+ self.write_log("info",
+ "([%s]: %s): Storing reference values for motor 2 (%s, %s, %s) Storing values for PZT 2 (%s, %s, %s). "
+ % (self.die_no, self.structure, motor_x_2, motor_y_2, motor_z_2, pzt_x_2, pzt_y_2, pzt_z_2)
+ )
+ except Exception as e:
+ self.write_log("warning", "([%s]: %s): Can't store reference values for motor 1 and 2." % (
+ self.die_no, self.structure))
+ self.write_log("warning", e)
+
+ motor_pos = {
+ 'motor_1': {
+ 'x': motor_x_1, 'y': motor_y_1, 'z': motor_z_1
+ },
+ 'motor_2': {
+ 'x': motor_x_2, 'y': motor_y_2, 'z': motor_z_2
+ }
+ }
+
+ pzt_pos = {
+ 'pzt_1': {
+ 'x': pzt_x_1, 'y': pzt_y_1, 'z': pzt_z_1
+ },
+ 'pzt_2': {
+ 'x': pzt_x_2, 'y': pzt_y_2, 'z': pzt_z_2
+ }
+ }
+
+ return motor_pos, pzt_pos
+
+ def _write_debug(self, description, title=None, details=None):
+ if details is None and title is None:
+ self.logger.debug(f"{description}.")
+ self.signals.log_debug.emit(None, description, None)
+ elif details is not None and title is None:
+ self.logger.debug(f"{description}: {details}")
+ self.signals.log_debug.emit(None, description, details)
+ elif details is None and title is not None:
+ self.logger.debug(f"[{title}] - {description}")
+ self.signals.log_debug.emit(None, description, None)
+ else:
+ self.logger.debug(f"[{title}] - {description}: {details}")
+ self.signals.log_debug.emit(title, description, details)
+
+ def _write_info(self, description, title=None, details=None):
+ if details is None and title is None:
+ self.logger.info(f"{description}.")
+ self.signals.log_info.emit(None, description, None)
+ elif details is not None and title is None:
+ self.logger.info(f"{description}: {details}")
+ self.signals.log_info.emit(None, description, details)
+ elif details is None and title is not None:
+ self.logger.info(f"[{title}] - {description}")
+ self.signals.log_info.emit(None, description, None)
+ else:
+ self.logger.info(f"[{title}] {description}: {details}")
+ self.signals.log_info.emit(title, description, details)
+
+ def _write_warning(self, description, title=None, details=None):
+ if details is None and title is None:
+ self.logger.warning(f"{description}.")
+ self.signals.log_warning.emit(None, description, None)
+ elif details is not None and title is None:
+ self.logger.warning(f"{description}: {details}")
+ self.signals.log_warning.emit(None, description, details)
+ elif details is None and title is not None:
+ self.logger.warning(f"[{title}] - {description}")
+ self.signals.log_warning.emit(None, description, None)
+ else:
+ self.logger.warning(f"[{title}] - {description}: {details}")
+ self.signals.log_warning.emit(title, description, details)
+
+ def _write_error(self, description, title=None, details=None):
+ if details is None and title is None:
+ self.logger.error(f"{description}.")
+ self.signals.log_error.emit(None, description, None)
+ elif details is not None and title is None:
+ self.logger.error(f"{description}: {details}")
+ self.signals.log_error.emit(None, description, details)
+ elif details is None and title is not None:
+ self.logger.error(f"[{title}] - {description}")
+ self.signals.log_error.emit(None, description, None)
+ else:
+ self.logger.error(f"{title}. {description}: {details}")
+ self.signals.log_error.emit(title, description, details)
+
+ # ==================================================================================================================
+ #
+ # ==================================================================================================================
+ def __del__(self):
+ self.msg_server.__exit__()
+ self.logger.info("Message Server closed!")
diff --git a/src/FlexSensor/Prober/model/OpticalInterfaceModel.py b/src/FlexSensor/Prober/model/OpticalInterfaceModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..ecd51bbe534740b116077af4914d21a76c25b512
--- /dev/null
+++ b/src/FlexSensor/Prober/model/OpticalInterfaceModel.py
@@ -0,0 +1,25 @@
+class OpticalInterfaceSignals():
+ pass
+
+
+
+class OpticalInterfaceModel():
+ def __init__(self):
+ # Motor position
+ self._motor_out_x: float = 0.0
+ self._motor_out_y: float = 0.0
+ self._motor_out_z: float = 0.0
+
+ self._motor_in_x: float = 0.0
+ self._motor_in_y: float = 0.0
+ self._motor_in_z: float = 0.0
+
+ # PZT position
+ self._pzt_out_x: float = 0.0
+ self._pzt_out_y: float = 0.0
+ self._pzt_out_z: float = 0.0
+
+ self._pzt_in_x: float = 0.0
+ self._pzt_in_y: float = 0.0
+ self._pzt_in_z: float = 0.0
+
diff --git a/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py b/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fd4b13302a1b614ac01368aebc4e164d76d4aa2
--- /dev/null
+++ b/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py
@@ -0,0 +1,116 @@
+class OpticalInterfaceStoredData:
+ def __init__(self):
+ self._motor_out_x: float = 0.0
+ self._motor_out_y: float = 0.0
+ self._motor_out_z: float = 0.0
+
+ self._motor_in_x: float = 0.0
+ self._motor_in_y: float = 0.0
+ self._motor_in_z: float = 0.0
+
+ # PZT position
+ self._pzt_out_x: float = 0.0
+ self._pzt_out_y: float = 0.0
+ self._pzt_out_z: float = 0.0
+
+ self._pzt_in_x: float = 0.0
+ self._pzt_in_y: float = 0.0
+ self._pzt_in_z: float = 0.0
+
+ @property
+ def motor_out_x(self):
+ return self._motor_out_x
+
+ @motor_out_x.setter
+ def motor_out_x(self, value):
+ self._motor_out_x = value
+
+ @property
+ def motor_out_y(self):
+ return self._motor_out_y
+
+ @motor_out_y.setter
+ def motor_out_y(self, value):
+ self._motor_out_y = value
+
+ @property
+ def motor_out_z(self):
+ return self._motor_out_z
+
+ @motor_out_z.setter
+ def motor_out_z(self, value):
+ self._motor_out_z = value
+
+ @property
+ def motor_in_x(self):
+ return self._motor_in_x
+
+ @motor_in_x.setter
+ def motor_in_x(self, value):
+ self._motor_in_x = value
+
+ @property
+ def motor_in_y(self):
+ return self._motor_in_y
+
+ @motor_in_y.setter
+ def motor_in_y(self, value):
+ self._motor_in_y = value
+
+ @property
+ def motor_in_z(self):
+ return self._motor_in_z
+
+ @motor_in_z.setter
+ def motor_in_z(self, value):
+ self._motor_in_z = value
+
+ @property
+ def pzt_out_x(self):
+ return self._pzt_out_x
+
+ @pzt_out_x.setter
+ def pzt_out_x(self, value):
+ self._pzt_out_x = value
+
+ @property
+ def pzt_out_y(self):
+ return self._pzt_out_y
+
+ @pzt_out_y.setter
+ def pzt_out_y(self, value):
+ self._pzt_out_y = value
+
+ @property
+ def pzt_out_z(self):
+ return self._pzt_out_z
+
+ @pzt_out_z.setter
+ def pzt_out_z(self, value):
+ self._pzt_out_z = value
+
+ @property
+ def pzt_in_x(self):
+ return self._pzt_in_x
+
+ @pzt_in_x.setter
+ def pzt_in_x(self, value):
+ self._pzt_in_x = value
+
+ @property
+ def pzt_in_y(self):
+ return self._pzt_in_y
+
+ @pzt_in_y.setter
+ def pzt_in_y(self, value):
+ self._pzt_in_y = value
+
+ @property
+ def pzt_in_z(self):
+ return self._pzt_in_z
+
+ @pzt_in_z.setter
+ def pzt_in_z(self, value):
+ self._pzt_in_z = value
+
+
diff --git a/src/FlexSensor/Prober/model/ProberModel.py b/src/FlexSensor/Prober/model/ProberModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..4552abbd0ae40a995bc1e89af7215d52dea2d836
--- /dev/null
+++ b/src/FlexSensor/Prober/model/ProberModel.py
@@ -0,0 +1,164 @@
+from pathlib import Path
+
+from PySide6.QtCore import QObject, Signal
+
+from MeasurementData.Properties.WaferProperties import WaferProperties
+
+
+class ProberSignals(QObject):
+ '''
+ Defines the signals available from a running prober thread.
+ The signals are always constructed for proagating it's status
+ to a Message Bix with
+ Signal(title, description, details)
+ '''
+
+ connected_changed = Signal(bool)
+ version_changed = Signal(str)
+ wafer_map_changed = Signal(Path)
+
+ die_changed = Signal(int)
+ curr_die_row_changed = Signal(int)
+ curr_die_col_changed = Signal(int)
+
+ chuck_x_changed = Signal(float)
+ chuck_z_changed = Signal(float)
+ chuck_y_changed = Signal(float)
+
+ errors_changed = Signal(list)
+ warnings_changed = Signal(list)
+
+
+
+
+ log_debug = Signal(str, str, str)
+ log_info = Signal(str, str, str)
+ log_warning = Signal(str, str, str)
+ log_error = Signal(str, str, str)
+
+
+class ProberModel:
+
+ def __init__(self):
+ self.signals = ProberSignals()
+
+ self._connected: bool = False
+ self._version: str = "Unknown Version"
+
+ self._die: int = 0
+ self._die_row: int = 0
+ self._die_col: int = 0
+
+ self._chuck_x: float = 0
+ self._chuck_y: float = 0
+ self._chuck_z: float = 0
+
+ self._errors: list = []
+ self._warnings: list = []
+
+ self._wafer_map = None
+
+ @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
+
+ @connected.setter
+ def connected(self, value: bool):
+ self._connected = value
+ self.signals.connected_changed.emit(value)
+
+ @property
+ def version(self) -> str:
+ return self._version
+
+ @version.setter
+ def version(self, value: str):
+ self._version = value
+ self.signals.version_changed.emit(value)
+
+ @property
+ def wafer_map(self) -> Path:
+ return self._wafer_map
+
+ @wafer_map.setter
+ def wafer_map(self, value: Path):
+ self._wafer_map = value
+ self.signals.wafer_map_changed.emit(value)
+
+ @property
+ def die(self) -> int:
+ return self._die
+
+ @die.setter
+ def die(self, value: int):
+ self._die = value
+ self.signals.die_changed.emit(value)
+
+ @property
+ def die_row(self) -> int:
+ return self._die_row
+
+ @die_row.setter
+ def die_row(self, value: int):
+ self._die_row = value
+ self.signals.curr_die_row_changed.emit(value)
+
+ @property
+ def die_col(self) -> int:
+ return self._die_col
+
+ @die_col.setter
+ def die_col(self, value: int):
+ self._die_col = value
+ self.signals.curr_die_col_changed.emit(value)
+
+ @property
+ def chuck_x(self) -> float:
+ return self._chuck_x
+
+ @chuck_x.setter
+ def chuck_x(self, value: float):
+ self._chuck_x = float(value)
+ self.signals.chuck_x_changed.emit(self._chuck_x)
+
+ @property
+ def chuck_y(self) -> float:
+ return self._chuck_y
+
+ @chuck_y.setter
+ def chuck_y(self, value: float):
+ self._chuck_y = float(value)
+ self.signals.chuck_y_changed.emit(self._chuck_y)
+
+ @property
+ def chuck_z(self) -> float:
+ return self._chuck_z
+
+ @chuck_z.setter
+ def chuck_z(self, value: float):
+ self._chuck_z = float(value)
+ self.signals.chuck_z_changed.emit(self.chuck_z)
+
+ @property
+ def errors(self) -> list:
+ return self._errors
+
+ @errors.setter
+ def errors(self, value: list):
+ self._errors = value
+ self.signals.errors_changed.emit(value)
+
+ @property
+ def warnings(self) -> list:
+ return self._warnings
+
+ @warnings.setter
+ def warnings(self, value: list):
+ self._warnings = value
+ self.signals.warnings_changed.emit(value)
diff --git a/src/FlexSensor/Prober/model/WaferProperties.py b/src/FlexSensor/Prober/model/WaferProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..1038b55c5b3be60812bf4d418ba77517815ba0e0
--- /dev/null
+++ b/src/FlexSensor/Prober/model/WaferProperties.py
@@ -0,0 +1,94 @@
+import numpy as np
+from numpy import ndarray
+
+from generics.GenericProperties import GenericProperties
+
+
+class WaferProperties(GenericProperties):
+ def __init__(self,
+ wafer_number: str, structure_name: str,
+ die_nr: int, chuck_col: int, chuck_row: int,
+ structure_in: tuple, structure_out: tuple,
+ repetitions: int
+ ):
+ super().__init__()
+ self._structure_name = self.to_str(structure_name)
+ self._wafer_number = self.to_str(wafer_number)
+
+ self._die_number = self.to_int(die_nr[0])
+ self._chuck_col = self.to_int(chuck_col[0])
+ self._chuck_row = self.to_int(chuck_row[0])
+
+ self._structure_in = self.to_tuple(structure_in)
+ self._structure_out = self.to_tuple(structure_out)
+ self._structure_x_in = int(self._structure_in[0])
+ self._structure_y_in = int(self._structure_in[1])
+ self._structure_x_out = int(self._structure_out[0])
+ self._structure_y_out = int(self._structure_out[1])
+
+ self._repetitions: int = self.to_int(repetitions)
+
+ @property
+ def repetition(self):
+ return int(self._repetitions)
+
+ @property
+ def chuck_col(self):
+ return int(self._chuck_col)
+
+ @property
+ def chuck_row(self):
+ return int(self._chuck_row)
+
+ @property
+ def wafer_number(self) -> str:
+ return str(self._wafer_number)
+
+ @property
+ def structure_x_in(self):
+ return int(self._structure_x_in)
+
+ @property
+ def structure_y_in(self):
+ return int(self._structure_y_in)
+
+ @property
+ def structure_x_out(self):
+ return int(self._structure_x_out)
+
+ @property
+ def structure_name(self):
+ return str(self._structure_name)
+
+ @property
+ def die_number(self) -> int:
+ return int(self._die_number)
+
+ @property
+ def structure_y_out(self):
+ return int(self._structure_y_out)
+
+ @property
+ def structure_in(self):
+ return tuple(self._structure_in)
+
+ @property
+ def structure_out(self):
+ return tuple(self._structure_out)
+
+ @property
+ def chuck_row(self):
+ return int(self._chuck_row)
+
+ def fields(self) -> dict:
+ return {
+ 'wafer_number': self.wafer_number,
+ 'die_number': self.die_number,
+ 'structure_name': self.structure_name,
+ 'repetition': self.repetition,
+ 'structure_in': self.structure_in,
+ 'structure_out': self.structure_out,
+ 'chuck_col': self.chuck_col,
+ 'chuck_row': self.chuck_row
+
+ }
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/MANIFEST.in b/src/FlexSensor/Prober/velox_api/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..f592b1ce090a55402214a78fad5143a82491c31c
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/MANIFEST.in
@@ -0,0 +1,5 @@
+include README.rst
+include readme.txt
+include Velox Python Interface.rtf
+include velox/samples/*
+include velox/sci/*
diff --git a/src/FlexSensor/Prober/velox_api/PKG-INFO b/src/FlexSensor/Prober/velox_api/PKG-INFO
new file mode 100644
index 0000000000000000000000000000000000000000..93ab8ec31d442401d75ee1f3672a53e5c9359ab9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/PKG-INFO
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: velox
+Version: 3.0.0.266
+Summary: Python 2.7+ and 3.5+ interface for Velox
+Home-page: UNKNOWN
+Author: Formfactor
+Author-email: UNKNOWN
+License: See Formfactor Velox Product License.
+Description: UNKNOWN
+Platform: UNKNOWN
diff --git a/src/FlexSensor/Prober/velox_api/README.rst b/src/FlexSensor/Prober/velox_api/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7e8b3f301ecfd8f8f8af7929f1953d1e74f4e672
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/README.rst
@@ -0,0 +1,29 @@
+Installation
+===============
+Copy the velox.tar.gz file to a convenient location and open a command prompt there.
+
+To install, use PIP:
+> python -m pip install velox.tar.gz
+
+NOTE: You must use the full file extension to avoid getting any modules named
+Velox from the public Python repository.
+
+Usage Overview
+===============
+The velox folder contains the modules for interfacing with the Velox Message Server APIs
+via SCI Commands (see documentation for the Velox Integration Toolkit).
+
+This folder contains the ``__init__.py`` file that automatically imports the correct
+module based on the version of Python running at the time.
+
+Your code should:
+------------------
+
+``import velox``
+
+The __init__.py will load an SCI module appropriate for either Python 2.7+ or Python 3.5+
+based on the version of Python being executed.
+
+The ``velox.sci27.py`` or ``velox.sci35.py`` module will import the ``vxmessageserver.py``
+
+
diff --git a/src/FlexSensor/Prober/velox_api/readme.txt b/src/FlexSensor/Prober/velox_api/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ce665530c759145afb22d5f1bf29fd237d7d9e08
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/readme.txt
@@ -0,0 +1,31 @@
+Installation
+===============
+Copy the velox.zip file to a convenient location and open a command prompt there.
+
+To install, use PIP:
+> python -m pip install velox.tar.gz
+
+NOTE: You must use the full file extension to avoid getting any modules named
+Velox from the public Python repository.
+
+Usage Overview
+===============
+The velox folder contains the modules for interfacing with the Velox Message Server APIs
+via SCI Commands (see documentation for the Velox Integration Toolkit).
+
+This folder contains the ``__init__.py`` file that automatically imports the correct
+module based on the version of Python running at the time.
+
+Your code should:
+------------------
+
+``import velox``
+
+The __init__.py will load an SCI module appropriate for either Python 2.7+ or Python 3.5+
+based on the version of Python being executed.
+
+The ``velox.sci27.py`` or ``velox.sci35.py`` module will import the ``vxmessageserver.py``
+
+
+
+
diff --git a/src/FlexSensor/Prober/velox_api/setup.cfg b/src/FlexSensor/Prober/velox_api/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..8bfd5a12f85b8fbb6c058cf67dd23da690835ea0
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/setup.cfg
@@ -0,0 +1,4 @@
+[egg_info]
+tag_build =
+tag_date = 0
+
diff --git a/src/FlexSensor/Prober/velox_api/setup.py b/src/FlexSensor/Prober/velox_api/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec20e5fcd8171c0593854e1a28e3270a187bb745
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/setup.py
@@ -0,0 +1,13 @@
+from setuptools import setup
+
+setup(
+ name='velox',
+ version='3.0.0.266',
+ packages=['velox'],
+ url='',
+ license='See Formfactor Velox Product License.',
+ author='Formfactor',
+ author_email='',
+ description='Python 2.7+ and 3.5+ interface for Velox',
+ include_package_data=True
+)
diff --git a/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py b/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py
new file mode 100644
index 0000000000000000000000000000000000000000..d847ac3a11b51549c03a6fb7fa4706c79a2f645a
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py
@@ -0,0 +1,12426 @@
+import random
+import time
+
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite.
+The module was auto-generated from the commands.info.xml file on 2019-11-09.
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():'
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection.
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+ # Your Code: try some SCI Commands - such as:
+ response = velox.ReportKernelVersion()
+ print ('The kernel version is', response.Version, 'and', response.Description)
+
+"""
+def EchoData(TestCmd:str=""):
+ """
+ Test Command for the Kernel Communication. Like a ping command, the given text
+ string is returned unchanged.
+ API Status: published
+ Args:
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:EchoData Test
+ """
+ rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module:str=""):
+ """
+ Returns the version information of the kernel or the control box code. The
+ "Version" value contains version number and revision level of the actual Kernel
+ implementation. The text string contains a code description, version number and
+ the revision date.
+ API Status: published
+ Args:
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:ReportKernelVersion K
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+ global ReportKernelVersion_Response
+ if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+ return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+ """
+ Returns an actual status information of the prober.
+ API Status: published
+ Returns:
+ FlagsBusy:int
+ FlagsContact:int
+ Mode:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProberStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+ global ReadProberStatus_Response
+ if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+ return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn:int="", Stage:str=""):
+ """
+ Toggles the motor power for quiet probing. In most applications this feature is
+ not required. However, for special measurements it may be necessary to reduce
+ the noise of the system. Quiet on turns off the motor power for all stages (or
+ the one specified with the optional parameter). Quiet off will turn on the motor
+ power of all stages (or the one specified with the optional parameter) for
+ subsequent movements. A move command will also turn on the motor power of the
+ moved stage automatically. For automatical switching of the quiet mode refer to
+ Auto Quiet functionality. Sending 'EnableMotorQuiet 1' will enable the quiet
+ mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+ mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+ quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+ disable the quiet mode for the scope stage.
+ API Status: published
+ Args:
+ WantQuietModeOn:int = 0
+ Stage:str = "None"
+ Command Timeout: 10000
+ Example:EnableMotorQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn:int=""):
+ """
+ Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+ stations with wafer vacuum sensors in case no wafer was detected.
+ API Status: published
+ Args:
+ WantChuckVacuumOn:int = 0
+ Command Timeout: 10000
+ Example:SetChuckVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn:int=""):
+ """
+ Toggles the microscope light channel of the peripheral output board and all
+ cameras. Notifications: 7
+ API Status: published
+ Args:
+ WantIlluminatorOn:int = 2
+ Command Timeout: 5000
+ Example:SetMicroLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode:int="", PulseWidthRed:int="", PulseWidthGreen:int="", PulseWidthYellow:int="", PulseWidthBlue:int="", PulseWidthWhite:int=""):
+ """
+ This command controls the beacon channel of the peripheral output board. All
+ lights can be switched on, off, or blinking. Setting an interval to zero means,
+ that the corresponding light will be statically on or off. The minimum blinking
+ interval is 50ms.
+ API Status: published
+ Args:
+ FlagsMode:int = 0
+ PulseWidthRed:int = 1000
+ PulseWidthGreen:int = 0
+ PulseWidthYellow:int = 0
+ PulseWidthBlue:int = 0
+ PulseWidthWhite:int = 0
+ Command Timeout: 5000
+ Example:SetBeaconStatus 1 1000
+ """
+ MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel:int="", WantOutputOn:int="", PulseTime:int=""):
+ """
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: published
+ Args:
+ Channel:int = 1
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetOutput 4 0
+ """
+ MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+ """
+ Stops all Prober movements immediately. The response status value of any pending
+ movement will signify that the stop command was executed.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAllMovements
+ """
+ MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker:int="", PulseWidth:int=""):
+ """
+ Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+ For correct function, the inkers have to be linked to default outputs.
+ API Status: published
+ Args:
+ FlagsInker:int = 0
+ PulseWidth:int = 50
+ Command Timeout: 10000
+ Example:InkDevice 1 40
+ """
+ MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+ """
+ Returns the current positioner configuration. The output pattern is: 1. Type
+ Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+ Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+ 2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+ Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+ 11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+ API Status: published
+ Returns:
+ TypePositioner1:int
+ TypePositioner2:int
+ TypePositioner3:int
+ TypePositioner4:int
+ TypePositioner5:int
+ AxisPositioner1:int
+ AxisPositioner2:int
+ AxisPositioner3:int
+ AxisPositioner4:int
+ AxisPositioner5:int
+ TypePositioner6:int
+ AxisPositioner6:int
+ Command Timeout: 5000
+ Example:ReadProbeSetup
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+ global ReadProbeSetup_Response
+ if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+ return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+ """
+ Returns the system options which are currently enabled at the prober.
+ API Status: published
+ Returns:
+ Name:str
+ System:str
+ ChuckXY:int
+ ChuckZ:int
+ ChuckTheta:int
+ ScopeXY:int
+ ScopeZ:int
+ EdgeSensor:int
+ OperationalMode:str
+ Turret:int
+ TemperatureChuck:int
+ AuxSiteCount:int
+ PlatenXY:int
+ PlatenZ:int
+ LoaderGateState:str
+ NucleusType:str
+ Command Timeout: 10000
+ Example:ReadSystemStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+ global ReadSystemStatus_Response
+ if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+ return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode:str=""):
+ """
+ If 'R' is sent, it sets the external mode of the kernel. This disables most of
+ the control box functions (except the LOCAL function key). Otherwise, this
+ command re-enables all functions of the control box.
+ API Status: published
+ Args:
+ Mode:str = "L"
+ Command Timeout: 5000
+ Example:SetExternalMode L
+ """
+ MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage:str="", WantStageLock:int="", Application:str=""):
+ """
+ Enables or disables the stage lock functionality. Stages which are locked can't
+ be moved in any way. If the joystick controller is locked, the display and the
+ keys are deactivated. The name of the application can be stored by using the
+ Application Name parameter and is shown in lock-caused error messages.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ WantStageLock:int = 1
+ Application:str = ""
+ Command Timeout: 10000
+ Example:SetStageLock C 0 WaferMap
+ """
+ MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel:int="", Type:str=""):
+ """
+ Returns the actual status of the specified input channel, output channel or edge
+ sensor. The signal table is described in the Hardware Manual. Each used IO-board
+ has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+ channel numbers. Beyond this range there are pseudo channels, which are used for
+ special purposes. Pseudo channels:
+ API Status: published
+ Args:
+ Channel:int = 1
+ Type:str = "Input"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadSensor 11 I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+ return int(rsp[0])
+
+def GetStageLock(Stage:str=""):
+ """
+ Reads whether stages or joystick controller are locked.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ Returns:
+ Locks:int
+ Application:str
+ Command Timeout: 10000
+ Example:GetStageLock C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+ global GetStageLock_Response
+ if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+ return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets bottomside mode. In this mode the Z axis is reverse and the
+ command MoveChuckLoad is not allowed.
+ API Status: internal
+ Args:
+ WantBackSideMode:int = 0
+ Command Timeout: 5000
+ Example:SetBackSideMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+ """
+ Returns the current side mode.
+ API Status: published
+ Returns:
+ IsBackSideModeOn:int
+ Command Timeout: 5000
+ Example:GetBackSideMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+ return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode:int=""):
+ """
+ Switches off all LEDs on the Control Box, on the positioners, and on the screen
+ of the Control Box and also the light of the cameras.
+ API Status: published
+ Args:
+ WantSetDarkMode:int = 0
+ Command Timeout: 5000
+ Example:SetDarkMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+ """
+ Returns the current mode of the light sources.
+ API Status: published
+ Returns:
+ IsDarkMode:int
+ Command Timeout: 5000
+ Example:GetDarkMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+ return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera:str="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Connect or disconnect the chuck camera to the chuck stage. The command is only
+ available for the Prober type PA300BEP.
+ API Status: internal
+ Args:
+ ConnectCamera:str = "ParkPos"
+ Velocity:Decimal = 100
+ Command Timeout: 300000
+ Example:DockChuckCamera P 75
+ """
+ MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current selected stage of the joystick controller.
+ API Status: internal
+ Returns:
+ Stage:str
+ Command Timeout: 5000
+ Example:ReadCBoxStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current stage of the joystick controller.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:SetCBoxStage C
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current setting of the joystick controllers position monitor for the
+ secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ PosRef:str
+ Unit:str
+ Command Timeout: 5000
+ Example:ReadCBoxPosMonConf C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+ global ReadCBoxPosMonConf_Response
+ if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+ return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage:str="", PosRef:str="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Configures the joystick controller position monitor for the secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetCBoxPosMonConf C Z Y
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CBoxSpeed:str
+ Command Timeout: 5000
+ Example:ReadCBoxCurrSpeed C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage:str="", CBoxSpeed:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CBoxSpeed:str = "Speed4"
+ Command Timeout: 5000
+ Example:SetCBoxCurrSpeed C 3
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck stage to the specified X,Y position without waiting for the move
+ to be finished If chuck Z is in contact height or higher, the chuck will drop to
+ separation.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveChuckAsync 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the scope stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveScopeAsync 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the probe stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def ReadChuckStatus():
+ """
+ Returns the current chuck status. Every bit in the bit fields works like a
+ boolean value: One <1> means true/on and zero <0> means false/off.
+ Its counted from LSB to MSB. - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+ HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+ EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+ ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta All parameters
+ are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+ accessed by M_pbIsInitX).
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsVacuumOn:int
+ PresetHeight:str
+ LoadPos:str
+ IsLiftDown:int
+ CameraConnection:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+ global ReadChuckStatus_Response
+ if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+ return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the current chuck stage position in X, Y and Z.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+ global ReadChuckPosition_Response
+ if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+ return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit:str=""):
+ """
+ Returns the current settings used for the chuck Z movement. `Contact` is the
+ contact-height from zero in default compensation. The other heights are relative
+ to this. If no contact is set, the value will be -1.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ SearchGap:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+ global ReadChuckHeights_Response
+ if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+ return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ Machine Coordinate System: Chuck X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+ X, Y, Z, Theta All flags can be accessed by indirect members. Initializes the
+ chuck stage and resets current coordinate system. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 150000
+ Example:InitChuck 7 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue:float="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+ height or higher, Interlock and Auto Z flags will be analyzed and stage will
+ behave correspondingly - can move to separation first or return an error:
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MoveChuck 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck stage in index steps. This command modifies Die Home Position.
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue:Decimal="", YValue:Decimal="", Unit:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck stage to the specified X, Y sub-site position. Die home position
+ is defined by destination position of last successful MoveChuck or
+ MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+ you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+ back to die home position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckSubsite 200 200 Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity:Decimal=""):
+ """
+ Performs a movement of chuck Z axis to preset contact height or will return
+ error if no contact height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckContact 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity:Decimal=""):
+ """
+ Moves the chuck Z axis to the align height. If no Contact height is set will
+ return an error.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity:Decimal=""):
+ """
+ Moves the chuck Z axis to the separation height. Returns error if no Contact
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition:str=""):
+ """
+ Moves the Chuck stage in X, Y, Z and Theta to the load position.
+ API Status: published
+ Args:
+ LoadPosition:str = "First"
+ Command Timeout: 60000
+ Example:MoveChuckLoad 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck Z axis to the specified height. If contact is set, only moves up
+ to contact height will be allowed. If overtravel is enabled - up to overtravel
+ height.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 60000
+ Example:MoveChuckZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck Z axis to the specified height and sets contact. The move stops
+ immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+ been found and an old one was set before the old contact will not get lost, it
+ will be reset.
+ API Status: published
+ Args:
+ Height:Decimal = 100
+ PosRef:str = "Relative"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 60000
+ Example:SearchChuckContact 1000 R Y 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+ return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ Moves the chuck stage in velocity mode. The motion continues until the
+ StopChuckMovement command is received, or the end limit is reached.
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveChuckVelocity + + 0 100 30 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop:int=""):
+ """
+ Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+ API Status: published
+ Args:
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:StopChuckMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel:int="", AutoZ:int="", Interlock:int="", ContactSearch:int="", EdgeInterlock:int="", QuietContact:int=""):
+ """
+ Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+ is made from 6 flags and you can control all of them using this command. Every
+ flag can be turned on by using value 1 or turned off by using value 0. If you do
+ not want to change a flag - use value of 2.
+ API Status: published
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ ContactSearch:int = 2
+ EdgeInterlock:int = 2
+ QuietContact:int = 2
+ Command Timeout: 5000
+ Example:SetChuckMode 2 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets wafer and die home position, which can be used later as coordinate system
+ for movements.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the wafer index size. Normally the size of one die.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetChuckIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation. A predefined contact search gap is able to write. No data
+ in the optional parameters sets contact height at current position. If Mode is
+ '0', contact height can be set at current position. The levels O, A, S and T
+ support no Mode '0'. If Mode is 'V' and no value for height is specified -
+ default 0 will be used, what potentially can be not what you expect. If Mode is
+ 'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+ 'R'.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHeight C V Y 5000.
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit:str=""):
+ """
+ The command gets the current die size which is stored in the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+ global ReadChuckIndex_Response
+ if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+ return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+ """
+ Moves the Chuck to the Transfer Position. If the movement starts in Load
+ Position (where it's possible to pull out the chuck) the handling of the Add On
+ Platen or the Pin Chuck is integrated.
+ API Status: published
+ Command Timeout: 90000
+ Example:MoveChuckTransfer
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift:int=""):
+ """
+ Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+ motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveChuckLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX:Decimal="", ScaleY:Decimal=""):
+ """
+ Thermo drifts of the wafer will be compensated. The compensation is not
+ persistent, (power off - this compensation is deleted). The algorithm works as
+ an additional one. This is for an iterative usage, so: 1. `ResetProber H` 2.
+ `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5` will result in a
+ scale of 2.25 in both directions. The thermal scale can also be reset using the
+ command 'SetChcukThermoValue 20 C'
+ API Status: published
+ Args:
+ ScaleX:Decimal = 1
+ ScaleY:Decimal = 1
+ Command Timeout: 5000
+ Example:SetChuckThermoScale 1.000005 1.0000045
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+ """
+ Read the linear scaling value of the chuck.
+ API Status: published
+ Returns:
+ ScaleX:Decimal
+ ScaleY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoScale
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+ global ReadChuckThermoScale_Response
+ if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+ return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature:Decimal="", Unit:str="", ExpCoeffX:Decimal="", ExpCoeffY:Decimal=""):
+ """
+ Set a temperature and optional the expansion coefficient. The temperature for
+ normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+ set the temperature directly the controller calculates the stage difference in
+ the coordinate system. For the calculation use the set coefficient of expansion
+ from the controller. The default coefficient of expansion is based on silicon:
+ 2.33E-06 1/K.
+ API Status: published
+ Args:
+ Temperature:Decimal = 0
+ Unit:str = "Celsius"
+ ExpCoeffX:Decimal = 0
+ ExpCoeffY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckThermoValue 250 C 2.43 2.32
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit:str=""):
+ """
+ Read the current temperature (either set or calculated) for the thermal scaling.
+ With SetChuckThermoScale in use, the value will be calculated by the current
+ scale and the expansion factor of silicium. The temperature that is read with
+ this command is not identical to the current chuck temperature.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ Temperature:Decimal
+ ExpCoeffX:Decimal
+ ExpCoeffY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoValue C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+ global ReadChuckThermoValue_Response
+ if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+ return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ChuckTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetChuckTableID ChuckTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+ return int(rsp[0])
+
+def MoveChuckTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move the chuck to the next stored table site.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckTablePoint 3 10 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the table site information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadChuckTablePoint 10 250 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+ global ReadChuckTablePoint_Response
+ if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the chuck table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearChuckTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of chuck table site points in the in the Kernel. If Start
+ Point is -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearChuckTablePoint 5 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+ global ClearChuckTablePoint_Response
+ if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is moved to slowly attach a wafer that is at ambient temperature while
+ the chuck is hot. The command acts similar to MoveChuckTransfer when moving
+ out of Load 2 but will use a much slower Z velocity. This is only supported
+ for BnR-machines (CM300 and Summit200) at the moment.
+ API Status: internal
+ Args:
+ MoveTimeMs:Decimal = 30000
+ Command Timeout: 300000
+ Example:AttachAmbientWafer
+ """
+ MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+ """
+ Returns the actual status of the chuck Theta axis.
+ API Status: published
+ Returns:
+ IsInit:int
+ FlagsLimit:int
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadThetaStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+ global ReadThetaStatus_Response
+ if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+ return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit:str="", PosRef:str=""):
+ """
+ Returns the actual Theta position.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ PosRef:str = "Home"
+ Returns:
+ Position:Decimal
+ Command Timeout: 5000
+ Example:ReadThetaPosition D Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+ return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus:int="", FlagsMoveRange:int=""):
+ """
+ Performs an initialization move and resets the coordinate system of the Theta
+ axis.
+ API Status: published
+ Args:
+ FlagsDoPlus:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitTheta 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck Theta axis to the specified position. The positive direction is
+ counter-clockwise.
+ API Status: published
+ Args:
+ Position:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Degrees"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveTheta 1000. R E
+ """
+ MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+ clockwise. The motion continues until the StopThetaMovement command is received,
+ or the end limit (error condition) is reached. This command is mostly used for
+ joystick movements that do not have a target destination.
+ API Status: published
+ Args:
+ Polarity:str = "Fixed"
+ Velocity:Decimal = 0
+ Command Timeout: 240000
+ Example:MoveThetaVelocity + 67
+ """
+ MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+ """
+ Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+ treated as a smooth stop rather than an emergency stop.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopThetaMovement
+ """
+ MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode:str="", Unit:str="", Position:Decimal=""):
+ """
+ Sets the chuck Theta position to home. This position is usable as reference
+ position for other commands.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Degrees"
+ Position:Decimal = 0
+ Command Timeout: 5000
+ Example:SetThetaHome 0
+ """
+ MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance:Decimal="", TriggerEveryNthCycle:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts moving the chuck from the current position with Velocity [%] over
+ ZDistance (sign is important, as a negative sign will move chuck down during
+ scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+ be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+ until the ZDistance has been reached. Command returns number of positions and
+ all compensated Z Positions from Zero, where the trigger was sent.
+ API Status: internal
+ Args:
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 3
+ Velocity:Decimal = 10
+ Returns:
+ NumberOfPositions:int
+ TriggerPositions:str
+ Command Timeout: 60000
+ Example:ScanChuckZ 300 3 1.5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+ global ScanChuckZ_Response
+ if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+ return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+ """
+ Moves the chuck Z axis to a z height considered safe. This is either the lower
+ Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+ API Status: published
+ Command Timeout: 60000
+ Example:MoveChuckZSafe
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The mode manages the way the platen behaves when it is in contact height. Platen
+ mode is made up from 5 flags and the user can control all of them by using this
+ command. Every flag can be turned on by setting value 1 or turned off by setting
+ value 0. If no change for a flag is wanted, use the value of 2.
+ API Status: internal
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Command Timeout: 5000
+ Example:SetPlatenMode 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen to the high (0) or low = lifted (1) position. This initiates
+ motion; the actual movement may take some seconds.
+ API Status: internal
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MovePlatenLift 1
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Searches contact height using the edge sensor using a z movement of the platen
+ stage
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ CompLayer:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+ return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current platen status.
+ API Status: internal
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ PresetHeight:str
+ IsLiftDown:int
+ Command Timeout: 10000
+ Example:ReadPlatenStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+ global ReadPlatenStatus_Response
+ if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+ return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the platens X, Y and Z axes. The default
+ compensation is the currently selected compensation for the stage.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+ global ReadPlatenPosition_Response
+ if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+ return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual settings for the probe Z movement.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+ global ReadPlatenHeights_Response
+ if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+ return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the platens X, Y and Z axes. Currently the initialization in
+ negative direction and the move range scan are not supported.
+ API Status: internal
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitPlaten 4
+ """
+ MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the specified height. If contact is set, only moves
+ up to contact height will be allowed. If overtravel is enabled - up to
+ overtravel height.
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MovePlatenZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a movement of platen Z axis to preset contact height or returns an
+ error, if no contact height is set.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenContact 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the align height. If no contact height is set, the
+ command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the separation height. If no contact height is set,
+ the command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen stage in velocity mode. The motion continues until the
+ StopPlatenMovement command is received, or the software fence is reached.
+ API Status: internal
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 240000
+ Example:MovePlatenVelocity + + 0 67 50 0
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the movement of a set of platen axes immediately.
+ API Status: internal
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 10000
+ Example:StopPlatenMovement 4
+ """
+ MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation height. A command without data sets contact height at
+ current position.
+ API Status: internal
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 10000
+ Example:SetPlatenHeight C V Y 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the current status of the manual platen. THis is only supported for
+ Nucleus and Summit200.
+ API Status: internal
+ Returns:
+ IsUp:int
+ IsDown:int
+ IsSafe:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+ global ReadManualPlatenState_Response
+ if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+ return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+ """
+ Returns the current scope status.
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsScopeLiftUp:int
+ PresetHeight:str
+ IsScopeLight:int
+ FlagsMode:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadScopeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+ global ReadScopeStatus_Response
+ if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+ return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual scope stage position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadScopePosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+ global ReadScopePosition_Response
+ if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+ return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit:str=""):
+ """
+ Returns the actual settings of the focus height, align gap, and separation gap
+ for the scope Z axis.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ FocusHeight:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+ global ReadScopeHeights_Response
+ if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+ return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+ the Direction default is XY in minus and Z in plus. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 240000
+ Example:InitScope 3 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 70000
+ Example:MoveScope 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves the microscope stage in index steps. If no PositionReference byte is
+ passed the scope will step relative to the wafer home position. ('R' means the
+ step relative to current position).
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the microscope Z axis to the specified height. Default velocity is 100%.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 120000
+ Example:MoveScopeZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode:int="", FollowMode:int=""):
+ """
+ Scope mode is made up of two flags which can be controlled using this command.
+ Each flag can be turned on by using value 1 or turned off by using value 0. If
+ you do not want to change a flag, use value of 2.
+ API Status: published
+ Args:
+ QuietMode:int = 2
+ FollowMode:int = 2
+ Command Timeout: 5000
+ Example:SetScopeMode 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ Moves the microscope stage in velocity mode. The motion continues until the
+ StopScopeMovement command is received, or the end limit (error condition) is
+ reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+ in minus direction '0' Do not change this axis
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveScopeVelocity + + 0 67 100 0
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop:int=""):
+ """
+ Stops scope movement for the given axis. A smooth stop is executed, no emergency
+ stop.
+ API Status: published
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 5000
+ Example:StopScopeMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the scope Home position in X and Y. It identifies the scope coordinate
+ system for later movements. Usually this position is identical to the die home
+ location.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the microscope index size. Normally set in relation to the wafer index
+ size.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetScopeIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ This command defines scope focus height and the corresponding gaps for alignment
+ or separation. No data sets focus height at current position.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHeight F 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit:str=""):
+ """
+ Returns the actual scope stage index values in X and Y.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+ global ReadScopeIndex_Response
+ if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+ return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity:Decimal=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 25000
+ Example:MoveScopeFocus 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity:Decimal=""):
+ """
+ Moves the Scope Z axis to the alignment height. If no focus height is set an
+ error will bereturned.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 10000
+ Example:MoveScopeAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity:Decimal=""):
+ """
+ Moves the scope Z axis to the separation height. Returns an error if no focus
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveScopeSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift:int=""):
+ """
+ Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+ initiates the motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveScopeLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current status of the motorized turret.
+ API Status: internal
+ Returns:
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadTurretStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+ return int(rsp[0])
+
+def SelectLens(Lens:int=""):
+ """
+ Parfocality and para-centricity are adjusted according to the stored values.
+ This can be used with manual turrets to compensate for XYZ differences between
+ lenses.
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 30000
+ Example:SelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ScopeTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetScopeTable ScopeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+ return int(rsp[0])
+
+def MoveScopeTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeTablePoint 10 5 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the scope table site Information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadScopeTablePoint 2 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+ global ReadScopeTablePoint_Response
+ if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+ """
+ Returns the number of the current microscope lens.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:ReadCurrentLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+ return int(rsp[0])
+
+def SetScopeTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the scope table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearScopeTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of scope table site points in the Kernel. If Start Point is
+ -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearScopeTablePoint 2 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+ global ClearScopeTablePoint_Response
+ if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+ """
+ Returns the number of silos in the scope fence. Will be zero if no silos are
+ configured.
+ API Status: published
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadScopeSiloCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+ return int(rsp[0])
+
+def ReadProbeStatus(Probe:int=""):
+ """
+ Returns the current positioner's status.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Returns:
+ ProbeEcho:int
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ Side:str
+ PresetHeight:str
+ IsLiftUp:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProbeStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+ global ReadProbeStatus_Response
+ if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+ return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe:int="", Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual positioner's position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadProbePosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+ global ReadProbePosition_Response
+ if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+ return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe:int="", Unit:str=""):
+ """
+ Returns the actual settings for the probe Z movement.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+ global ReadProbeHeights_Response
+ if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe:int="", Side:str=""):
+ """
+ Defines the orientation of the positioner's coordinate system and turns the
+ Y-axis of the probe coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Side:str = "Left"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:OrientProbe 1 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+ return int(rsp[0])
+
+def InitProbe(Probe:int="", FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int="", FlagsInitInPlace:int=""):
+ """
+ Performs an initialization move and resets the coordinate system of the given
+ positioner.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ FlagsInitInPlace:int = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 120000
+ Example:InitProbe 1 7 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+ return int(rsp[0])
+
+def MoveProbe(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbe 1 1000. 1000. R Y 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeIndex(Probe:int="", XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeIndex 1 1 1 R 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+ return int(rsp[0])
+
+def MoveProbeContact(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+ height is set, the kernel will return a 'Contact height not set' error.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeContact 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeAlign(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves the given ProbeHeads Z axis to the align height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeAlign 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeSeparation(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeSeparation 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeZ(Probe:int="", Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves a given ProbeHeads Z axis to a defined Z height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeZ 1 1000. R Y 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeLift(Probe:int="", SetLift:int=""):
+ """
+ Moves the positioner to the lower (0) or upper = lifted (1) position. The
+ command initiates the motion only, the whole movement may take some seconds.
+ API Status: published
+ Args:
+ Probe:int = 1
+ SetLift:int = 1
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:MoveProbeLift 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+ return int(rsp[0])
+
+def MoveProbeVelocity(Probe:int="", PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ '+' Move this axis into plus direction '-' Move this axis into minus direction
+ '0' Do not change this axis
+ API Status: published
+ Args:
+ Probe:int = 1
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeVelocity 1 + + Z 67 100 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+ return int(rsp[0])
+
+def StopProbeMovement(Probe:int="", FlagsStop:int=""):
+ """
+ Stops positioner movement for the given axes immediately. A smooth stop is
+ performed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsStop:int = 7
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:StopProbeMovement 1 7
+ """
+ rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+ return int(rsp[0])
+
+def SetProbeMode(Probe:int="", Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+ """
+ The mode manages the way the chuck behaves when it is in contact height.
+ Positioner mode is made up from 5 flags and the user can control all of them by
+ using this command. Every flag can be turned on by setting value 1, or turned
+ off by setting value 0. Use the value 2 if no change for a flag is needed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeMode 1 2 2 2 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+ return int(rsp[0])
+
+def SetProbeHome(Probe:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the positioner's Home position in X and Y. This position identifies the
+ probe coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetProbeIndex(Probe:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the positioner's index size or the location of the reference die relative
+ to the home die.
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetProbeHeight(Probe:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align, load and separation height. No data sets contact height at current
+ position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadProbeIndex(Probe:int="", Unit:str=""):
+ """
+ Returns the current positioner's wafer index values or the current positioner's
+ index positions for X and Y.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+ global ReadProbeIndex_Response
+ if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+ return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe:int="", NewLEDState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the positioner LED On or Off.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ NewLEDState:int = 0
+ Returns:
+ ProbeEcho:int
+ LEDState:int
+ Command Timeout: 5000
+ Example:SetProbeLED 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+ global SetProbeLED_Response
+ if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+ return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe:int="", TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the ID of a stored probe table or creates a new table. The ID is unique
+ for the name and the probe. The table itself has a string name. This name is not
+ case sensitive. The command has to be used before all other table commands can
+ be used. Access to tables is possible only with an ID Number (name dependent).
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableName:str = "ProbeTable"
+ Returns:
+ ProbeEcho:int
+ TableID:int
+ Command Timeout: 5000
+ Example:GetProbeTableID 1 ProbeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+ global GetProbeTableID_Response
+ if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+ return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 1
+ PointID:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeTablePoint 3 14 10 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+ return int(rsp[0])
+
+def ReadProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the data from a point of a stored table in the Kernel.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadProbeTablePoint 2 4 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+ global ReadProbeTablePoint_Response
+ if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+ return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+ point with this index loaded, the Kernel returns an error. Number of positions
+ and number of tables are dependet on the internal memory. All positions are
+ stored persistent, that means after switching power on or off the positions are
+ still available. The table starts with point number 1 and ends with the ID 16.
+ The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ProbeEcho:int
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ global SetProbeTablePoint_Response
+ if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+ return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe:int="", TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+ is a negative value, the whole table will be deleted.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ProbeEcho:int
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearProbeTablePoint 3 4 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+ global ClearProbeTablePoint_Response
+ if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+ return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index:int=""):
+ """
+ Move the scope to the reference position of the given silo. The reference
+ position should be - if not defined otherwise - 200 um above the safe z-height
+ in the center of the scope.
+ API Status: published
+ Args:
+ Index:int = 1
+ Command Timeout: 70000
+ Example:MoveScopeSilo 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index:int="", X:Decimal="", Y:Decimal="", Z:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the reference position of a silo. The next time the scope moves to this
+ silo, it woll go to this position. The Referenceposition must be inside the silo
+ in xy and above the lower Z-Fence of the silo. Setting the reference position
+ directly on the fence in x, y or z typically leads to errors. Try to keep a
+ safety margin.
+ API Status: internal
+ Args:
+ Index:int = 1
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeSiloReference 1 1000 2000 3000
+ """
+ MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a chuck Theta axis rotation to align the wafer to the chuck
+ X,Y movements. It can be used to perform a two point alignment with
+ P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line. The units of
+ the distances are not important - but both distances should use the same unit.
+ If one or both distances are zero, the command does not return an error and
+ instead ignore this alignment
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignChuckTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a virtual rotation of the scope coordinate system to align
+ the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of X and Y distances:
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignScopeTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe:int="", XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a rotation of the coordinate system of given probe to align
+ the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of Y and Y distances:
+ API Status: published
+ Args:
+ Probe:int = 1
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:AlignProbeTheta 1 10000 10 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+ return int(rsp[0])
+
+def AlignCardTheta(Angle:Decimal="", Unit:str="", PosRef:str=""):
+ """
+ This command causes a rotation of the chuck coordinate system to align the chuck
+ X, Y axis to the probecard. The polarity of the data determines a left or a
+ right rotation of the chuck coordinate system.
+ API Status: published
+ Args:
+ Angle:Decimal = 0
+ Unit:str = "Degrees"
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignCardTheta 2.5 D R
+ """
+ MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit:str=""):
+ """
+ Returns the angle between the chuck-coordinate-system and the probecard-
+ coordinate-system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadCardTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit:str=""):
+ """
+ Returns the current chuck alignment angle which is identical to the current
+ value of theta rotation.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit:str=""):
+ """
+ Returns the scope's alignment angle, which is the angle between the chuck
+ coordinate system and the scope coordinate system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe:int="", Unit:str=""):
+ """
+ Returns the actual positioner's alignment angle, which is the angle between the
+ chuck coordinate system and the positioner coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Degrees"
+ Returns:
+ ProbeEcho:int
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeTheta 1 D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+ global ReadProbeTheta_Response
+ if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+ return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the preset speeds, which are used by the joystick controller for moving a
+ single stage. The speeds can be read for XY, for Z and for Theta axis
+ separately. Jog timing and index timing are the times, the joystick controller
+ waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "X"
+ Returns:
+ JogTime:Decimal
+ Speed2:Decimal
+ Speed3:Decimal
+ Speed4:Decimal
+ IndexTime:Decimal
+ Command Timeout: 5000
+ Example:ReadJoystickSpeeds S Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+ global ReadJoystickSpeeds_Response
+ if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+ return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage:str="", JogTime:Decimal="", Speed2:Decimal="", Speed3:Decimal="", Speed4:Decimal="", IndexTime:Decimal="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the preset speeds, which are used by the joystick controller for moving a
+ single stage. After setting, the speeds can be selected by pressing the Speed n
+ buttons at the controller. The speeds must be set separately for XY, for Z and
+ for Theta axis. Jog timing and index timing are the times, the joystick
+ controller waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ JogTime:Decimal = 0
+ Speed2:Decimal = 0
+ Speed3:Decimal = 0
+ Speed4:Decimal = 0
+ IndexTime:Decimal = 0
+ Axis:str = "X"
+ Command Timeout: 5000
+ Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open:int=""):
+ """
+ Opens or closes the loader gate. Automatic handling systems can load wafers to
+ the chuck through the gate.
+ API Status: published
+ Args:
+ Open:int = 0
+ Command Timeout: 5000
+ Example:SetLoaderGate 0
+ """
+ MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+ """
+ Returns whether the system detected a wafer. This feature can be used if the
+ probe station is equipped with a vacuum sensor and while vacuum is activated.
+ API Status: published
+ Returns:
+ SensedByVac:str
+ Command Timeout: 5000
+ Example:ReadWaferStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage:str=""):
+ """
+ Returns the number of times this stage moved to contact since the last time the
+ counter was reset.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadContactCount C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+ return int(rsp[0])
+
+def ResetContactCount(Stage:str=""):
+ """
+ Resets the contact counter for the specified stage to zero. Notifications: 23
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:ResetContactCount C
+ """
+ MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command enables the manual mode on Elite/Summit/S300 systems. This mode
+ will allow to move the chuck using the knobs.
+ API Status: internal
+ Args:
+ Enable:int = 1
+ Command Timeout: 10000
+ Example:SetManualMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of the manual mode on Elite/Summit/S300 stations.
+ API Status: internal
+ Returns:
+ Enable:int
+ Command Timeout: 10000
+ Example:GetManualMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+ return int(rsp[0])
+
+def GetAxisReverse(Stage:str="", Axis:str=""):
+ """
+ Allows reading if an axis is reverse.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ IsReverse:int
+ Command Timeout: 5000
+ Example:GetAxisReverse C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+ return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor:int="", Enable:int=""):
+ """
+ Enables/disables the use of an edge sensor.
+ API Status: published
+ Args:
+ EdgeSensor:int = 1
+ Enable:int = 1
+ Command Timeout: 5000
+ Example:EnableEdgeSensor 1 1
+ """
+ MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel:str="", WantOutputOn:int="", PulseTime:int=""):
+ """
+ Controls the kernel valve driver signals and can be used to drive the outputs.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetTypedOutput WaferVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel:str=""):
+ """
+ Returns the status of the specified input channel, output channel, or edge
+ sensor.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadTypedSensor EmoIn I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+ return int(rsp[0])
+
+def MoveCoolDownPosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck to the cool down position that is defined in KernelSetup. The
+ cooldown position is used to move the chuck away in XY while the robot is in the
+ chamber and tries to get a hot wafer.
+ API Status: internal
+ Command Timeout: 30000
+ Example:MoveCoolDownPosition
+ """
+ MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the cycling speeds - these are the speeds that are used by
+ the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CycleJog:int
+ CycleSpeed2:int
+ CycleSpeed3:int
+ CycleSpeed4:int
+ CycleIndex:int
+ Command Timeout: 5000
+ Example:ReadJoystickSpeedsCycle S
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+ global ReadJoystickSpeedsCycle_Response
+ if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+ return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage:str="", CycleJog:int="", CycleSpeed2:int="", CycleSpeed3:int="", CycleSpeed4:int="", CycleIndex:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets the cycling speeds - these are the speeds that are used by the
+ USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CycleJog:int = 0
+ CycleSpeed2:int = 0
+ CycleSpeed3:int = 0
+ CycleSpeed4:int = 0
+ CycleIndex:int = 0
+ Command Timeout: 5000
+ Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows sending low level AUCS commands to the ECX box stage. Only
+ applies to Elite/Summit/S300 stations.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 60000
+ Example:SendAUCSCommand "MM 1 0 INIT 0"
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage:str="", Compensation:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command allows reading if a specific type of compensation is enabled or
+ disabled. Returns an error if this type of compensation is not available for
+ this stage.
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Returns:
+ Enabled:int
+ Active:int
+ Command Timeout: 5000
+ Example:ReadCompensationStatus C A
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+ global ReadCompensationStatus_Response
+ if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+ return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode:int="", WantNotification:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deprecated. All Kernel notifications are now enabled by default.
+ API Status: internal
+ Args:
+ NotificationCode:int = 0
+ WantNotification:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId:int="", Value1:Decimal="", Value2:Decimal="", Value3:Decimal=""):
+ """
+ This is not a regular command. Asynchronous notifications will be sent from the
+ Kernel controller to the host system only. All notifications can be switched off
+ and on, except the Prober reset notification (ID01). /warning This is a stub
+ implementation without appropriate handling
+ API Status: published
+ Args:
+ NotificationId:int = 0
+ Value1:Decimal = 0
+ Value2:Decimal = 0
+ Value3:Decimal = 0
+ Command Timeout: 5000
+ Example:AlertNotification 31 195000 160000 0
+ """
+ MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage:str="", Compensation:str="", Status:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables a compensation mode for the specified stage
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Status:int = -1
+ Command Timeout: 5000
+ Example:SetCompensationStatus C A 1
+ """
+ MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command gets the value "Value" for the parameter "Parameter". The unit is
+ parameter specific.
+ API Status: internal
+ Args:
+ ControllerInfo:str = "Unknown"
+ Returns:
+ Value:Decimal
+ Command Timeout: 1000
+ Example:GetControllerInfo HasScanChuckZ
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+ return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ In unprotected mode a number of security features like software fence and
+ initialization necessity are deactivated. Unprotected mode is
+ deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+ anytime before resets the timer back to 5 minutes. It is not necessary to
+ deactivate it before. **WARNING**: If unprotected mode is enabled, even the
+ most basic safety- and sanity-checks are skipped. Any movement may cause
+ irreparable damage to the prober or attached hardware.
+ API Status: internal
+ Args:
+ OperationalMode:str = "ProtectedMode"
+ Command Timeout: 5000
+ Example:SetOperationalMode P
+ """
+ MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured Nano-chamber-state.
+ API Status: internal
+ Returns:
+ NanoChamberState:str
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the NanoChamber-state.
+ API Status: internal
+ Args:
+ NanoChamberState:str = "Free"
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows to force activate/deactivate the camera cool output or to let it be set
+ automatically by purge control.
+ API Status: internal
+ Args:
+ State:int = 2
+ Command Timeout: 10000
+ Example:SetCameraCool 0
+ """
+ MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the chuck vacuum and forces it to be on. This command ignores the
+ vacuum sensor and timeout.
+ API Status: internal
+ Command Timeout: 10000
+ Example:ActivateChuckVacuum
+ """
+ MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns a point from the matrix compensation table for the
+ specified axis from the kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ Returns:
+ XVal:Decimal
+ YVal:Decimal
+ Command Timeout: 5000
+ Example:ReadMatrixValues C 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+ global ReadMatrixValues_Response
+ if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+ return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int="", XVal:Decimal="", YVal:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Downloads a point of the matrix compensation table for a specified stage to the
+ kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ XVal:Decimal = 0
+ YVal:Decimal = 0
+ Command Timeout: 5000
+ Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+ """
+ MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage:str="", Type:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+ only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Returns:
+ Enable:int
+ Command Timeout: 5000
+ Example:ReadMEAStatus C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+ return int(rsp[0])
+
+def LoadMEAFile(Stage:str="", Type:int="", Load:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Load the MEA file for a stage (Nucleus legacy stations only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Load:int = 0
+ Command Timeout: 5000
+ Example:LoadMEAFile C 0 1
+ """
+ MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The command returns the positions of the actual software limits (end of move
+ range) for each axis of the specified stage in microns. If the Theta stage is
+ selected Z1 and Z2 include the values for the Theta limits.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ ZLowValue:Decimal
+ ZHighValue:Decimal
+ X1Value:Decimal
+ Y1Value:Decimal
+ X2Value:Decimal
+ Y2Value:Decimal
+ X3Value:Decimal
+ Y3Value:Decimal
+ X4Value:Decimal
+ Y4Value:Decimal
+ Command Timeout: 5000
+ Example:ReadSoftwareLimits C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+ global ReadSoftwareLimits_Response
+ if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+ return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage:str="", AuxID:int="", FenceForm:str="", XBase:Decimal="", YBase:Decimal="", XDist:Decimal="", YDist:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets types and dimensions of technological software fences. It can
+ also be used for enabling and disabling the software fence.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ FenceForm:str = "None"
+ XBase:Decimal = 0
+ YBase:Decimal = 0
+ XDist:Decimal = 0
+ YDist:Decimal = 0
+ Command Timeout: 10000
+ Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage:str="", AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the type and the dimensions of an actual set technological
+ software fence. In case of a rectangular software fence, X and Y coordinates of
+ the four edge points of the fence are given back. In case of a circular software
+ fence, X and Y coordinates of the center point and the radius are given back.
+ All other return values are filled with zeros. All position values are in
+ microns from zero.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ Returns:
+ FenceForm:str
+ XValue1:Decimal
+ YValue1:Decimal
+ XValue2:Decimal
+ YValue2:Decimal
+ XValue3:Decimal
+ YValue3:Decimal
+ XValue4:Decimal
+ YValue4:Decimal
+ Command Timeout: 10000
+ Example:GetSoftwareFence C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+ global GetSoftwareFence_Response
+ if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+ return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage:str="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands reads if the Z-Fence is activated and the currently set Z-fence
+ values for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CompLayer:str = "Default"
+ Returns:
+ Enabled:int
+ ZLow:Decimal
+ ZHigh:Decimal
+ Command Timeout: 10000
+ Example:GetZFence S
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+ global GetZFence_Response
+ if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+ return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage:str="", Enabled:int="", ZLow:Decimal="", ZHigh:Decimal="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands sets Z-Fence and the Z-fence values for the specified stage.
+ Values are stored uncompensated internally and set default compensated as
+ default.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Enabled:int = 0
+ ZLow:Decimal = 0
+ ZHigh:Decimal = 0
+ CompLayer:str = "Default"
+ Command Timeout: 10000
+ Example:SetZFence S 1 5000 10000
+ """
+ MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the Prober and replaces the current configuration with a formerly
+ written recovery file. If no recovery file was written, the configuration is
+ reset to the version of the last Prober restart. For ProberBench electronics,
+ 'H' will restart the Operating system, 'S' will only restart the Kernel
+ application. For Windows Kernel, 'H' and 'S' are identical.
+ API Status: internal
+ Args:
+ Mode:str = "S"
+ Command Timeout: 20000
+ Example:ResetProber S
+ """
+ MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reboots the operation system inside the Joystick Controller and restarts the
+ functionality. The restart will need a time of around 20 seconds.
+ API Status: internal
+ Args:
+ ResetMode:str = "S"
+ Command Timeout: 20000
+ Example:ResetCBox S
+ """
+ MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage:str="", LocationType:str="", AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The Home Position on the Chuck or ProbeHead Z axis is also called contact
+ height. The Home Position on the Scope Z axis is also called focus height.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ LocationType:str = "Center"
+ AuxID:int = 0
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadStageLocations C C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+ global ReadStageLocations_Response
+ if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+ return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters.
+ and requires the GetNextDatum command.
+ API Status: internal
+ Args:
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 10000
+ Example:GetDataIterator 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+ global GetDataIterator_Response
+ if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ Attributes:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:GetNextDatum 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+ global GetNextDatum_Response
+ if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+ return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:SetDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ PathName:str = ""
+ Returns:
+ Attributes:int
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:GetDatum Chuck:AlignGap
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+ global GetDatum_Response
+ if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+ return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 5000
+ Example:SetRecoveryDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the motion recording. The recording parameters are set in dynamic
+ kernel setup.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStart C
+ """
+ MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Checks the motion recording status for one stage.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Returns:
+ IsReady:int
+ SizeCh0Raw:int
+ SizeCh0Comp:int
+ SizeCh1Raw:int
+ SizeCh1Comp:int
+ SizeCh2Raw:int
+ SizeCh2Comp:int
+ SizeCh3Raw:int
+ SizeCh3Comp:int
+ Command Timeout: 10000
+ Example:TraceStatus C
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+ global TraceStatus_Response
+ if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+ return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller:str="", Channel:int="", PointOne:int="", IsCompress:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a collection of five data pairs. A pair is the index and the value of a
+ recording point. If the stream is empty or at the end the index is 1 and the
+ value 0. The index is relative to the start of the motion recording. The
+ recording is clocked by the motion controller cycle. The cycle time is contained
+ in the Kernel setup. In the raw stream all recorded trace points are contained.
+ But in the compressed stream only the non-linear depending trace points are
+ contained. To reload the recording points the stream must be reset to the first
+ recording point.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ PointOne:int = 1
+ IsCompress:int = 1
+ Returns:
+ Point1:int
+ Value1:int
+ Point2:int
+ Value2:int
+ Point3:int
+ Value3:int
+ Point4:int
+ Value4:int
+ Point5:int
+ Value5:int
+ Command Timeout: 10000
+ Example:TraceGetData C 0 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+ global TraceGetData_Response
+ if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+ return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller:str="", Channel:int="", NewPos:int="", IsCompress:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the index position in the raw or compressed stream for the next call of the
+ command TraceGetData.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ NewPos:int = 0
+ IsCompress:int = 1
+ Command Timeout: 10000
+ Example:TraceSetDataPosition C 0 1000 1
+ """
+ MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the motion recording.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStop C
+ """
+ MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage:str="", XValue:Decimal="", YValue:Decimal="", ZGap:Decimal="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set a point for the Z height profile. If this profile is enabled, the Z height
+ depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+ Positive values are elevated spots, negative values are hollows. The height
+ profile is used to adjust the Z height. The adjusted Z height at a X and Y
+ position is derivated from the nearest profile point. The Z contact level will
+ be calculated from the contact height and the stored Z gap at this point. See
+ GetZProfilePoint for details.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZGap:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ ValueCount:int
+ Command Timeout: 5000
+ Example:SetZProfilePoint C 5000 5000 -3 H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+ return int(rsp[0])
+
+def ReadZProfilePoint(Stage:str="", Index:int="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a single point and the corresponding Z gap of the Z height profile. The
+ different z profiles are: - transient: meant to be used on a per-wafer-basis,
+ default - persistent: configured once, stays in memory - persistent-offset: same
+ as persistent, active when offset is enabled - scratch: not used internaly. Can
+ be used to translate KernelDatums <-> ZProfile-Points
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Index:int = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ XValue:Decimal
+ YValue:Decimal
+ ZGap:Decimal
+ ValueCount:int
+ Command Timeout: 5000
+ Example:ReadZProfilePoint C 1 H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+ global ReadZProfilePoint_Response
+ if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+ return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clears all profile points. See GetZProfile for type description.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZProfileType:int = 0
+ Command Timeout: 5000
+ Example:ClearZProfile C
+ """
+ MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index:int=""):
+ """
+ Returns the definition of a silo. If the type is rectangle, center means
+ _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+ API Status: published
+ Args:
+ Index:int = 1
+ Returns:
+ Type:str
+ CenterX:Decimal
+ CenterY:Decimal
+ Radius:Decimal
+ Pos2X:Decimal
+ Pos2Y:Decimal
+ ZHigh:Decimal
+ RefX:Decimal
+ RefY:Decimal
+ RefZ:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeSilo 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+ global ReadScopeSilo_Response
+ if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+ return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName:str=""):
+ """
+ Alerts applications if the project file was changed.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName:str=""):
+ """
+ Alerts applications to save the current project. This notification _MUST_ only
+ be invoked by CommonCommands. Sending this notification directly _WILL_ give
+ erroneous results.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel:str="", UserName:str="", VeloxLocked:int=""):
+ """
+ Alerts applications of new access level.
+ API Status: published
+ Args:
+ AccessLevel:str = "Engineer"
+ UserName:str = ""
+ VeloxLocked:int = 0
+ Command Timeout: 5000
+ Example:NewAccessLevel 1
+ """
+ MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled:int="", AnnualDaysLeft:int="", VeloxProEnabled:int="", VueTrackEnabled:int="", VueTrack4PEnabled:int="", ReAlignEnabled:int="", AutomationEnabled:int="", IdToolsEnabled:int="", IVistaEnabled:int="", IVistaProEnabled:int="", LaserCutterEnabled:int="", SiPToolsEnabled:int="", AutoRfEnabled:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener about the licensed Velox features. Is sent cyclically by
+ CommonCommands.
+ API Status: internal
+ Args:
+ AnnualEnabled:int = 1
+ AnnualDaysLeft:int = 460
+ VeloxProEnabled:int = 0
+ VueTrackEnabled:int = 0
+ VueTrack4PEnabled:int = 0
+ ReAlignEnabled:int = 0
+ AutomationEnabled:int = 0
+ IdToolsEnabled:int = 0
+ IVistaEnabled:int = 0
+ IVistaProEnabled:int = 0
+ LaserCutterEnabled:int = 0
+ SiPToolsEnabled:int = 0
+ AutoRfEnabled:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName:str="", SecName:str="", NewRegistered:int=""):
+ """
+ Alerts applications that an application is registered or unregistered on
+ MsgServer.
+ API Status: published
+ Args:
+ AppName:str = "SharedTest"
+ SecName:str = "SharedTest"
+ NewRegistered:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications of a change of the current alignment mode
+ API Status: internal
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ Example:AlignmentModeChange OnAxis
+ """
+ MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum:int="", Type:str="", Result:str="", Desc:str=""):
+ """
+ An example of Kernel Connection Status is "Windows Socket Error Number and
+ Error Description."
+ API Status: published
+ Args:
+ ControllerNum:int = 1
+ Type:str = "Socket"
+ Result:str = "Disconnected"
+ Desc:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage:str="", Compensation:str="", Enabled:int="", Active:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Compensation:str = "None"
+ Enabled:int = 0
+ Active:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage:str="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation level has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Comp:str = "None"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status:str="", PlatenSafe:int="", Height:Decimal="", HeightMax:Decimal="", HeightRelative:Decimal="", SafeHeight:Decimal="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the combined-z-move-system
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ PlatenSafe:int = 0
+ Height:Decimal = 0
+ HeightMax:Decimal = 0
+ HeightRelative:Decimal = 0
+ SafeHeight:Decimal = 0
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the machine state
+ API Status: internal
+ Args:
+ MachineState:str = "Off"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if the user requests a chuck vacuum change
+ API Status: internal
+ Args:
+ VacuumState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if software stop was activated or deactivated
+ API Status: internal
+ Args:
+ SoftwareStopState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet:int="", Stage:str="", IsStageQuiet:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs if the overall quiet mode changes and about changes of single stages
+ API Status: internal
+ Args:
+ IsQuiet:int = 0
+ Stage:str = "None"
+ IsStageQuiet:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies that a configuration item has changed by some application
+ API Status: internal
+ Args:
+ ParameterChanged:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs that a new working stage is active
+ API Status: internal
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage:str="", Axis:str="", State:str="", AdditionalStateInfo:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the user Interface and Kernel if the state of the axis has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ State:str = "NotExisting"
+ AdditionalStateInfo:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the stage status has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an input channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an output channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage:str="", Axis:str="", Initialized:int="", PositiveLimit:int="", NegativeLimit:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener that an axis status has changed. Currently used to notify
+ the Kernel about the init state of a BnR axis.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Initialized:int = 0
+ PositiveLimit:int = 0
+ NegativeLimit:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+ AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+ when stepping.
+ API Status: internal
+ Args:
+ AutoXYModeOn:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+ handle this so it doesn't have to poll OpticalControl for the current zoom
+ level.
+ API Status: internal
+ Args:
+ ZoomLevel:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO:str="", ValuePercent:Decimal="", UnderOverflow:int="", Error:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state or value of an analog input or output channel
+ has changed.
+ API Status: internal
+ Args:
+ AnalogIO:str = "AO_PurgeDewPoint"
+ ValuePercent:Decimal = 0
+ UnderOverflow:int = 0
+ Error:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum:int="", ControllerInfo:str="", Value:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies the listener about changed controller info. Currently used to inform
+ Toolbar about the battery state of the BnR controller.
+ API Status: internal
+ Args:
+ ControllerNum:int = 1
+ ControllerInfo:str = "BatteryOK"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage:str="", XorT:Decimal="", Y:Decimal="", Z:Decimal="", CommandedXorT:Decimal="", CommandedY:Decimal="", CommandedZ:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by BnR controller if a axis position has changed. Currently
+ used to notify the Kernel about the new axis position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XorT:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ CommandedXorT:Decimal = 0
+ CommandedY:Decimal = 0
+ CommandedZ:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType:str="", Info:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Generic Information Notification
+ API Status: internal
+ Args:
+ InfoType:str = ""
+ Info:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX:int="", DieY:int="", XFromHome:Decimal="", YFromHome:Decimal="", CurSite:int="", LastSiteIndex:int=""):
+ """
+ Alerts applications that WaferMap has a new position.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ XFromHome:Decimal = 0
+ YFromHome:Decimal = 0
+ CurSite:int = 1
+ LastSiteIndex:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+ """
+ Alerts applications that a wafer's parameters have been changed.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+ the identifier for the button as defined for the guided workflow.
+ API Status: internal
+ Args:
+ TargetIdent:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State:str="", Error:int="", ErrorDescription:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when the cooling or heating process was terminated successfully or
+ incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+ COOL DOWN, WARMUP) and sends the error code and error message.
+ API Status: internal
+ Args:
+ State:str = "IDLE"
+ Error:int = 0
+ ErrorDescription:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent when Spectrum VS project has finished loading.
+ API Status: internal
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access:str="", FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent when a probe card file is loaded.
+ API Status: internal
+ Args:
+ Access:str = "L"
+ FileName:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+ """
+ Alerts applications that the TTL Test is ready.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State:str="", SubState:str="", Message:str="", Error:int=""):
+ """
+ Notification sent when VeloxPro changes its running state.
+ API Status: published
+ Args:
+ State:str = "Unknown"
+ SubState:str = "Unknown"
+ Message:str = ""
+ Error:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent during wafer stepping process. It updates the progress
+ information. 'Progress' is the relationship of dies tested to dies to be tested.
+ API Status: internal
+ Args:
+ ProgressPercent:Decimal = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader:int="", UseAutoWafer:int="", WaferSizes:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent to notify the listener about usage of Loader, usage of
+ fully/semiautomatic mode and supported wafer sizes of process station.
+ API Status: internal
+ Args:
+ UseLoader:int = 0
+ UseAutoWafer:int = 0
+ WaferSizes:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by loader to display a message on the process station.
+ API Status: internal
+ Args:
+ Message:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename:str="", Option:int=""):
+ """
+ Asks if the current project should be saved and then brings up the Open Project
+ window which opens the selected project file if the user clicks ok.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Option:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+ """
+ Brings up the Save Project window which saves the project if the user clicks ok.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer:str=""):
+ """
+ Brings up the Login window and sends a New Access Level alert if the user enters
+ a valid password.
+ API Status: published
+ Args:
+ LevelToOffer:str = "1"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+ """
+ Returns the current software status. The server holds and maintains the software
+ status. Status can be changed by using any of the following commands:
+ BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+ UnloadWafer, ResumeProbing
+ API Status: published
+ Returns:
+ DummyCommonMode:int
+ RunningMode:str
+ AccessLevel:str
+ ExternalMode:int
+ LicenseDaysLeft:int
+ MKH:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStatus")
+ global GetStatus_Response
+ if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+ return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Licensing window.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current license information.
+ API Status: internal
+ Returns:
+ AnnualEnabled:int
+ AnnualDaysLeft:int
+ VeloxProEnabled:int
+ VueTrackEnabled:int
+ VueTrack4PEnabled:int
+ ReAlignEnabled:int
+ AutomationEnabled:int
+ IdToolsEnabled:int
+ IVistaEnabled:int
+ IVistaProEnabled:int
+ LaserCutterEnabled:int
+ SiPToolsEnabled:int
+ AutoRfEnabled:int
+ SecsGemEnabled:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+ global GetLicenseInfo_Response
+ if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+ return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+ """
+ Returns the current project file.
+ API Status: published
+ Returns:
+ ProjectFilename:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+ """
+ Returns the Velox software version as string.
+ API Status: published
+ Returns:
+ SoftwareVersion:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename:str=""):
+ """
+ The OpenProject command opens the specified project.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application:str=""):
+ """
+ Checks the server to see if the application "AppName" is registered with the
+ server.
+ API Status: published
+ Args:
+ Application:str = ""
+ Returns:
+ IsAppRegistered:int
+ Command Timeout: 5000
+ Example:IsAppRegistered WaferMap
+ """
+ rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+ return int(rsp[0])
+
+def SaveProject(ProjectFilename:str=""):
+ """
+ Saves the current data to the project file.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType:str=""):
+ """
+ Returns the path for either the applications/data or project files.
+ API Status: published
+ Args:
+ PathType:str = "User"
+ Returns:
+ SoftwarePath:str
+ Command Timeout: 5000
+ Example:GetSoftwarePath User
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command.
+ API Status: internal
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:CCSelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command. Probably no longer used.
+ API Status: internal
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+ return int(rsp[0])
+
+def CCMoveAuxSite(AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calls the Kernel command MoveAuxSite to move the chuck to the
+ position of a given AUX site. For the transfer move a safe height is used. If
+ AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+ Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+ command AlignAux is executed after MoveAuxSite to align the site automatically.
+ The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+ installed. AUX ID in the response is the ID of the new active site.
+ API Status: internal
+ Args:
+ AuxID:int = 1
+ Command Timeout: 200000
+ """
+ MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName:str="", AllowMediaReuse:int="", SkipAlignAux:int="", SkipReturnMove:int=""):
+ """
+ This command moves to the single cleaning site, executes CleanProbeTip, moves to
+ the contact verify site, and then moves to contact. Returns an error if the
+ clean or verify sites aren't defined.
+ API Status: published
+ Args:
+ SequenceName:str = ""
+ AllowMediaReuse:int = 0
+ SkipAlignAux:int = 0
+ SkipReturnMove:int = 0
+ Command Timeout: 1800000
+ Example:ExecuteCleaningSequence "DeepClean"
+ """
+ MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+ """
+ Get the active alignment mode (either on axis or off axis).
+ API Status: published
+ Returns:
+ AlignmentMode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode:str=""):
+ """
+ Sets the active alignment mode (either on axis or off axis).
+ API Status: published
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName:str=""):
+ """
+ Gets the Velox user data: name, full name, group, access level. If the
+ commanded user name is empty, the data of the current user will be responded
+ API Status: published
+ Args:
+ CmdUserName:str = ""
+ Returns:
+ UserName:str
+ LongUserName:str
+ UserGroup:str
+ AccessLevel:str
+ VeloxLocked:int
+ Command Timeout: 5000
+ Example:GetLoginData
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+ global GetLoginData_Response
+ if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+ return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to warn user of chuck initialization for Nucleus stations.
+ Allows user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to allow saving project before shutting down Velox. Allows
+ user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCal command to WinCal.
+ API Status: internal
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCheckAutoRFStability command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Returns:
+ StabilityPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+ return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCloseRFStabilityReport command to WinCal.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+ reference. The ISS index is the IssIdxMap index as returned from
+ WinCalGetIssListForAuxSite.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+ as 1 if stage and positioners at home.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ AllRefAtHome:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+ return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+ information for the given aux site ID.
+ API Status: internal
+ Args:
+ AuxID:int = 0
+ Returns:
+ IssIdx:int
+ IssPN:str
+ IssDescription:str
+ IssEnabled:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+ global WinCalGetIssForAuxSite_Response
+ if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+ return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetNameAndVersion command to WinCal.
+ API Status: internal
+ Returns:
+ ServerName:str
+ Version:str
+ MajorVersion:int
+ MinorVersion:int
+ Revision:int
+ Build:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+ global WinCalGetNameAndVersion_Response
+ if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+ return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+ monitor portion of the current calibration setup.
+ API Status: internal
+ Returns:
+ MonitorPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+ return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing:Decimal="", ResetTrace:int="", AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+ the currently selected calibration setup. Resets the controller used in WinCal
+ for validataion.
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ ResetTrace:int = 1
+ AllowMove:int = 1
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+ return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMeasureMonitorReference command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumValidationPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumValidationPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+ return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumValidationPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumValidationPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumMonitoringPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+ return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumMonitoringPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumRepeatabilityPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+ return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumRepeatabilityPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidate command to WinCal. Performs the validation step of the
+ currently selected calibration setup in WinCal.
+ API Status: internal
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+ return int(rsp[0])
+
+def WinCalGetValidationSetup(Port:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+ parameters.
+ API Status: internal
+ Args:
+ Port:int = 1
+ Returns:
+ StandardType:str
+ StandardPorts:int
+ StandardCompareType:int
+ StructureType:str
+ PostCorrect:int
+ PostCorrectMatching:int
+ AutoConfigure:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+ global WinCalGetValidationSetup_Response
+ if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+ return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+ without the validation step
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+ windows
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+ index it will return a string with the reference information
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ ReferenceInfo:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+ if WinCal has unapplied changes
+ API Status: internal
+ Args:
+ ShowErrors:int = 0
+ Returns:
+ HasUnappliedChanges:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+ return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+ indicated by the index, reference as being the current location
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Save Project as Template window which saves the project template
+ if the user clicks ok.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the New Project from Template dialog which allows the user to select a
+ template and create a new project.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns Max Ports and Number of probes connected to a port
+ API Status: internal
+ Returns:
+ MaxPorts:int
+ NumPortsConnectedtoProbes:int
+ Command Timeout: 1000
+ Example:WinCalGetNumPortsAndProbes
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+ global WinCalGetNumPortsAndProbes_Response
+ if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+ return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the properties from one probe, based on the passed in index. Pass in a
+ physical VNA port number that is less than or equal to Max Probes from the call
+ to CalGetNumPortsAndProbes
+ API Status: internal
+ Args:
+ VnaPortNum:int = 1
+ Returns:
+ IsSelected:int
+ BaseProbe:str
+ Options:str
+ PhysicalOrient:str
+ IsDual:int
+ IsSymmetric:int
+ SignalConfig:str
+ SelectedPitch:int
+ Command Timeout: 1000
+ Example:WinCalGetProbeInfoForPort 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+ global WinCalGetProbeInfoForPort_Response
+ if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+ return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current state of the machine.
+ API Status: internal
+ Returns:
+ MachineState:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the help about dialog for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid:int="", TimeoutMs:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ TimeoutMs:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the last four project files that were opened.
+ API Status: internal
+ Returns:
+ ProjectFile1:str
+ ProjectFile2:str
+ ProjectFile3:str
+ ProjectFile4:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+ global GetLastFourProjects_Response
+ if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+ return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command:str=""):
+ """
+ Sends the WinCalExecuteCommand command to WinCal and returns the response
+ string.
+ API Status: published
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will return an error if its called with any other parameter as 0.
+ API Status: internal
+ Args:
+ TurnOnDemoMode:int = 1
+ Command Timeout: 5000
+ Example:SetDemoMode 0
+ """
+ MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Override a command with a demo response. The command will not reach its
+ destination but the supplied demo response will be returned. An active overide
+ for a command will be removed if the provided timeout is negative. Format: [ID]
+ [Time] [ErrorCode]:[Response] - Id: command id in hex withoud leding 0x - Time:
+ time in ms between command and response, negativ to reset demo mode for this
+ command - Errorcode: 0 for success, everything else indicates an error -
+ Response: response string
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 5000
+ Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+ """
+ MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will always return 0.
+ API Status: internal
+ Returns:
+ DemoModeOn:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+ return int(rsp[0])
+
+def ResetNetworkPort(Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+ tries to connect to (IP address and listen port of Kernel socket). Dummy
+ implementation for Kernel to support backwards.
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 10000
+ Example:ResetNetworkPort 192.168.3.1 10000
+ """
+ MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum:int="", Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets status information about the connection NetworkDriver to Kernel. Socket
+ Error is the Windows socket error, Description the Windows socket error
+ description. If Socket Error is 0, the description 'Registered' informs that the
+ Kernel is ready to receive Remote Commands.
+ API Status: internal
+ Args:
+ ClientNum:int = 1
+ Param:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:GetNDriverClientStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID:int="", TimeoutMilliSec:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows specifying a separate command timeout for a single instance
+ of a command. This is especially useful if the application that receives a
+ command knows how long a command will take. This command had been added for
+ SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+ 5s.
+ API Status: internal
+ Args:
+ CmdID:int = 0
+ TimeoutMilliSec:int = 1000
+ Command Timeout: 5000
+ Example:OverrideCommandTimeout 3234 20000
+ """
+ MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shutdown all Velox applications in an ordered fashion. When this command returns
+ success, all non-mandatory apps are closed and the mandatory ones will follow
+ shortly
+ API Status: internal
+ Args:
+ IgnorePID:int = 0
+ Command Timeout: 120000
+ Example:ShutdownVelox
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Registration of an application can be delayed. To trigger this behavior,
+ RegisterProberApp has to be called with flag 3 set (0x04). From
+ RegisterProberApp to the time this command is sent, the application can send
+ commands but can't receive commands. This is necessary because some application
+ have to communicate with others during initialization and can not handle
+ commands properly during this time. The command group is necessary because of
+ architectural reasons (By design, the command receiver does not now the sender
+ of a command).
+ API Status: internal
+ Args:
+ CommandGroup:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos:Decimal="", YPos:Decimal="", NumberOfPoints:int="", NumberOfEPoints:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+ only) and pauses after it (even in the automatic mode)
+ API Status: internal
+ Args:
+ XPos:Decimal = 0
+ YPos:Decimal = 0
+ NumberOfPoints:int = 0
+ NumberOfEPoints:int = 0
+ Command Timeout: 60000
+ Example:StepFirstZProfilePoint 10000 20000 5 5
+ """
+ MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calculates a delta value for the current point and then moves to
+ the specified point (if it's presented) or to the next one. Note, that in case
+ of the automatic Z detecting a return ZDelta parameter is a value for the
+ current point, but in case of the semiautomatic mode the command returns ZDelta
+ as a value for a previous tested point. If the profiling is finished this
+ command will return #807 error (End of the profile). Point indices are started
+ from 1 (1 is first, 2 is second, and so on).
+ API Status: internal
+ Args:
+ Point:int = 0
+ Returns:
+ XPos:Decimal
+ YPos:Decimal
+ Delta:Decimal
+ CurPoint:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 60000
+ Example:StepNextZProfilePoint 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+ global StepNextZProfilePoint_Response
+ if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+ return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode:str="", SepSpeed:Decimal="", ProfileSensor:str="", Stage:str="", SearchSpeed:Decimal="", Gap:Decimal="", Units:str="", ClearElectronics:int="", ClearRefZ:int="", Inaccuracy:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets some Z Profile Program Options remotely.
+ API Status: internal
+ Args:
+ ProfileMode:str = "S"
+ SepSpeed:Decimal = 25
+ ProfileSensor:str = "E"
+ Stage:str = "C"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ Units:str = "Y"
+ ClearElectronics:int = 1
+ ClearRefZ:int = 1
+ Inaccuracy:Decimal = 0
+ Command Timeout: 10000
+ Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return predefined settings of the Z Profile Program.
+ API Status: internal
+ Returns:
+ ProfileMode:str
+ SepSpeed:Decimal
+ ProfileSensor:str
+ Stage:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ Units:str
+ ClearElectronics:int
+ ClearRefZ:int
+ Inaccuracy:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileOptions
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+ global GetZProfileOptions_Response
+ if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+ return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command opens the file inside of the Z Profiling.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 240000
+ Example:OpenZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+ global OpenZProfileFile_Response
+ if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves the current profile in the specified file.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:SaveZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+ global SaveZProfileFile_Response
+ if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read a profile from the ProberBench Electronics II to the application. Return a
+ number of available points.
+ API Status: internal
+ Args:
+ NewOrigin:str = "Z"
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:ReadZProfile H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+ return int(rsp[0])
+
+def SetZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Uploads the current profile to the ProberBench Electronics II. Returns a number
+ of written points.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:SetZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+ return int(rsp[0])
+
+def CloseZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Z-Profiling application.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseZProfiling
+ """
+ MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X:Decimal="", Y:Decimal="", PosRef:str="", Units:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets new start point for the profile. All points of the profile will be shifted
+ accordingly.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Command Timeout: 10000
+ Example:SetZProfileStartPoint 0 0 H Y
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the profiling process. If this status is true it means the
+ process is started.
+ API Status: internal
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ Example:GetZProfilingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+ return int(rsp[0])
+
+def StopZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the profiling process.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos:str="", X:Decimal="", Y:Decimal="", Z:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an origin for the profile. If the origin position is H the command ignores
+ X and Y parameters. If Z is None the command clears Z value of the origin.
+ Otherwise it tries to extract a double value from the string and set it.
+ API Status: internal
+ Args:
+ Pos:str = "H"
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:str = "None"
+ Command Timeout: 10000
+ Example:SetZProfileOrigin H 0 0 None
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current parameters of the profile origin. If the origin Z has no value
+ the return string for it will be None, otherwise it consists a double value of
+ the profile Z.
+ API Status: internal
+ Returns:
+ Pos:str
+ X:Decimal
+ Y:Decimal
+ Z:str
+ Command Timeout: 10000
+ Example:GetZProfileOrigin
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+ global GetZProfileOrigin_Response
+ if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+ return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Command Timeout: 10000
+ Example:StartZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 36000000
+ Example:ZProfileWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+ global ZProfileWafer_Response
+ if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+ return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef:str="", Units:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current start point of the profile by using given units and a
+ reference position.
+ API Status: internal
+ Args:
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileStartPoint H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+ global GetZProfileStartPoint_Response
+ if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+ return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X:Decimal="", Y:Decimal="", After:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Adds new point to the profile at the end (default) or after the given point.
+ Returns an index of new point and a number of all points in the profile. Point
+ indices are started from 1.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ After:int = 0
+ Returns:
+ Index:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:AddZProfilePoint 50000 50000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+ global AddZProfilePoint_Response
+ if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+ return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deletes the point from the profile. Returns a number of all and enabled points
+ in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:DeleteZProfilePoint 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+ global DeleteZProfilePoint_Response
+ if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+ return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index:int="", Status:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ Example:SetZProfilePointStatus 11 E
+ """
+ MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ Example:GetZProfilePointStatus 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ All points are covered by triangles, each vertex of the triangle is a point of
+ the profile. The centers of the triangles are new points of the profile. If all
+ three vertexes of the triangle are tested points the new point will be marked as
+ tested also and has Z value equal to average Z of all three vertexes. Otherwise
+ the new point will be marked as untested. The command returns a number of points
+ in the profile after the update.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:PreciseZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+ return int(rsp[0])
+
+def CloseTableView():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the TableView application.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+ If no Site no is specified the chuck will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+ return int(rsp[0])
+
+def StepChuckSubsite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+ table view. If no Subsite no. is specified the chuck will step automatically to
+ the next logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+ return int(rsp[0])
+
+def StepScopeSite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the microscope stage to the requested Site no. of the scope table view. If
+ no Site no is specified the scope will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+ return int(rsp[0])
+
+def StepProbeSite(Probe:int="", Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the specified probe to the requested Site no. of the Probe no table view.
+ If no Site no. is specified the Probe no. will step automatically to the next
+ logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Site:int = -1
+ Returns:
+ ProbeRet:int
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+ global StepProbeSite_Response
+ if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+ return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual chuck site position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+ global ReadChuckSitePosition_Response
+ if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+ return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+ global ReadScopeSitePosition_Response
+ if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+ return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Returns:
+ ProbeRet:int
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+ global ReadProbeSitePosition_Response
+ if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+ return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the chuck subsite position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+ global ReadChuckSubsitePosition_Response
+ if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+ return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins:int="", RecalcRoute:int=""):
+ """
+ Steps the chuck to the first die of the wafer map. Returns the row and column
+ number of the actual die location after the move is completed. If ClearBins is
+ 1, all binning data will be cleared from dies. If yes the route will be
+ recalculated. All dies marked to skip during the last test (marked to skip with
+ SetDieStatus) will be eliminated from the route.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ DieX:int
+ DieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+ global StepFirstDie_Response
+ if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+ return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Steps the chuck to the specified x,y die location of the wafer map. If no
+ command data is passed, the chuck automatically steps to the next logical wafer
+ map die location. Returns the row and column number of the actual die location
+ after the move is completed. In addition, the SubDie location, and total number
+ of SubDies is also returned. If Site (i.e. SubDie) is -1, the chuck will move
+ to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+ If sent without parameters, it will literally 'step to the next die'. When using
+ this command from shared code, use SendWithoutParameter().
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+ global StepNextDie_Response
+ if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin:int="", CDieX:int="", CDieY:int=""):
+ """
+ Assigns the bin information to the wafer map at the current die, unless a row
+ and column is specified. Inks the device if the real time inking option (of the
+ wafer map) is enabled.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 30000
+ Example:BinMapDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+ global BinMapDie_Response
+ if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+ return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins:str=""):
+ """
+ Assigns the pass or fail information to the actual bin value. Redundant to
+ SetBinCode.
+ API Status: published
+ Args:
+ Bins:str = ""
+ Command Timeout: 10000
+ Example:AssignMapBins PFFFFFF
+ """
+ MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+ """
+ Steps the chuck back the number of consecutive failed dies (goes back to the
+ last known good die) and returns the number of consecutive failed dies.
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+ return int(rsp[0])
+
+def StepFailedForward():
+ """
+ Steps the chuck forward the number of consecutive failed dies (goes to next
+ untested die).
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+ return int(rsp[0])
+
+def ReadMapPosition(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+ the first value is 1, not 0. M_pnCurSite returns the currently selected
+ Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+ ReadMapPosition) has been included for legacy support. ReadMapPosition2 is
+ the preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+ global ReadMapPosition_Response
+ if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+ """
+ Returns the actual wafer map yield data information.
+ API Status: published
+ Returns:
+ TotalDies:int
+ TestedDies:int
+ Passed:int
+ Failed:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+ global ReadMapYield_Response
+ if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+ return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Bins the current die and steps the chuck to the next selected die location of
+ the wafer map (default) or steps to the specified Column and Row position, if
+ these values are passed. In contrast to StepNextDie, the BinStepDie command
+ will only step from die to die while staying on the current subdie. It will not
+ step through the subdies so it cannot be used for subdie stepping.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ Example:BinStepDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+ global BinStepDie_Response
+ if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX:int="", DieY:int=""):
+ """
+ If the command has no parameters it sets the current position as home position
+ both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+ home position using the given die coordinates.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName:str="", FileType:str=""):
+ """
+ Saves current map file with specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ FileType:str = "m"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode:str=""):
+ """
+ Enables or disables an external mode for the application. In the external mode,
+ all controls are disabled. The application handles all its remote commands in
+ both modes. Special interactive modes can also be turned on.
+ API Status: published
+ Args:
+ Mode:str = ""
+ Returns:
+ ModeType:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType:str=""):
+ """
+ Returns whether the application is in external mode or not.
+ API Status: published
+ Args:
+ ModeType:str = ""
+ Returns:
+ Mode:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number:str=""):
+ """
+ Specifies the wafer number.
+ API Status: published
+ Args:
+ Number:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+ """
+ Returns the wafer number for the current wafer.
+ API Status: published
+ Returns:
+ Number:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID:str=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+ """
+ Returns the wafer ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID:str=""):
+ """
+ Specifies the product ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+ """
+ Displays the product ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProductID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+ """
+ Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+ number of dies which were inked during the inker run.
+ API Status: published
+ Returns:
+ InkedDies:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+ return int(rsp[0])
+
+def CloseWaferMap():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Wafer Map application.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+ """
+ Gets the number of dies in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedDies:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+ return int(rsp[0])
+
+def GetSelectedDieCoords(Die:int=""):
+ """
+ Given the index of a selected die in the range [1..NumSelectedDies], returns the
+ column and row indices for the selected die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+ global GetSelectedDieCoords_Response
+ if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+ return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset:Decimal="", YOffset:Decimal="", CDieX:int="", CDieY:int=""):
+ """
+ Moves to a user-specified offset within a die. The optional col row params can
+ be used to specify the die. If they are omitted, WaferMap moves to the specified
+ offset within the next selected die.
+ API Status: published
+ Args:
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+ global StepNextDieOffset_Response
+ if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+ return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+ the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+ (0-based) or -1 if no Subdie is currently selected. This command is the
+ preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+ global ReadMapPosition2_Response
+ if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site:int=""):
+ """
+ Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+ not 1. This command is the preferred method for deleting a selected
+ subdie.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+ return int(rsp[0])
+
+def DeleteAllSubDie():
+ """
+ Deletes all subdies for all dies.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX:int="", DieY:int=""):
+ """
+ Returns a label from the wafer map at the current die, unless a row and column
+ are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label:str="", DieX:int="", DieY:int=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a row and column are
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site:int=""):
+ """
+ Steps the chuck to the specified SubDie number relative to the current die
+ origin of the wafer map. Returns the SubDie number of the actual die location
+ after the move is completed and the total number of subdies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+ global StepNextSubDie_Response
+ if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+ return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName:str=""):
+ """
+ Opens a Wafer Map file.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result:str="", DieX:int="", DieY:int=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX:int="", DieY:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result:str="", DieX:int="", DieY:int="", Site:int=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die and the
+ current subdie, unless a subdie, row, and column are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX:int="", DieY:int="", Site:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die and current
+ subdie, unless a row, column, and subdie are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Assigns the bin information for the current subdie in the current die, unless a
+ subdie, row, and column are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+ global BinSubDie_Response
+ if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site:int="", X:Decimal="", Y:Decimal="", Label:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ X:Decimal
+ Y:Decimal
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+ global GetSubDieData_Response
+ if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+ return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the home die location of the WaferMap.
+ API Status: internal
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+ global GetMapHome_Response
+ if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+ return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+ """
+ Returns the parameters for the current wafer.
+ API Status: published
+ Returns:
+ MapType:str
+ XIndex:Decimal
+ YIndex:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+ global GetMapDims_Response
+ if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+ return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are percentages.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth:Decimal="", DieHeight:Decimal="", Columns:int="", Rows:int=""):
+ """
+ Creates the rectangle wafer with specified parameters.
+ API Status: published
+ Args:
+ DieWidth:Decimal = 0
+ DieHeight:Decimal = 0
+ Columns:int = 0
+ Rows:int = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber:int="", Site:int=""):
+ """
+ Steps the chuck to the die location specified by the die number of the wafer
+ map. If no command data is passed, the chuck automatically steps to the next
+ logical wafer map die location. Returns the row and column number of the actual
+ die location after the move is completed. In addition, the SubDie location, and
+ total number of SubDies is also returned.
+ API Status: published
+ Args:
+ DieNumber:int = -1
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+ global StepToDie_Response
+ if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift:int=""):
+ """
+ Returns parameters of the map coordinate system.
+ API Status: published
+ Args:
+ UseOrientationCornerForShift:int = 0
+ Returns:
+ Orientation:int
+ OriginShiftX:int
+ OriginShiftY:int
+ UseAlphas:int
+ UseIOs:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+ global GetMapOrientation_Response
+ if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+ return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation:int="", OriginShiftX:int="", OriginShiftY:int="", UseAlphas:int="", UseIOs:int="", UseOrientationCornerForShift:int=""):
+ """
+ Sets up new map origin and new coordinate system after that.
+ API Status: published
+ Args:
+ Orientation:int = 0
+ OriginShiftX:int = 0
+ OriginShiftY:int = 0
+ UseAlphas:int = 0
+ UseIOs:int = 1
+ UseOrientationCornerForShift:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX:int="", DieY:int="", Status:str=""):
+ """
+ Sets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX:int="", DieY:int=""):
+ """
+ Gets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site:int="", Status:str=""):
+ """
+ Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+ not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site:int=""):
+ """
+ Returns the SubDie status. The SubDie collection is 0-based, the first value is
+ 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin:int=""):
+ """
+ Returns the Die size from the current map.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Returns:
+ Chars:str
+ Color:int
+ Status:str
+ Inker1:int
+ Inker2:int
+ Inker3:int
+ Inker4:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+ global GetBinCode_Response
+ if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+ return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin:int="", Chars:str="", Color:int="", Status:str="", Inker1:int="", Inker2:int="", Inker3:int="", Inker4:int=""):
+ """
+ Appends the Bin information to a bin code.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Chars:str = ""
+ Color:int = 0
+ Status:str = ""
+ Inker1:int = 0
+ Inker2:int = 0
+ Inker3:int = 0
+ Inker4:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex:int=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Number is absent it uses the current die
+ on the wafer.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+ global GetDieDataAsNum_Response
+ if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+ return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex:int="", Bin:int="", Result:str=""):
+ """
+ Sets the Die Information. If the Die Number is invalid it returns an error.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+ global GetSubDieDataAsNum_Response
+ if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+ return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex:int="", Site:int="", Bin:int="", Result:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX:int="", CDieY:int=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Column and Row are absent it uses the
+ current die on the wafer.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+ global GetDieDataAsColRow_Response
+ if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+ return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX:int="", DieY:int="", Bin:int="", Result:str=""):
+ """
+ Sets the Data in the Row Column format. If the Die is invalid it returns an
+ error.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+ global GetSubDieDataAsColRow_Response
+ if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+ return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX:int="", DieY:int="", Site:int="", Bin:int="", Result:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll:int="", DoEdgeDies:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables all dies.
+ API Status: internal
+ Args:
+ DoSelectAll:int = 0
+ DoEdgeDies:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current WaferMap Filename.
+ API Status: internal
+ Returns:
+ Name:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapName")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID:str=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+ """
+ Returns the Lot ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLotID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins:int="", RecalcRoute:int=""):
+ """
+ Steps the chuck to the first die cluster of the cluster map. If clusters are not
+ defined, the first Die is used. Returns the row and column information of the
+ actual cluster and die location after the move is completed. Switches to remote
+ control if the "Disable Velox" flag is set in the external options window.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+ global StepFirstCluster_Response
+ if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX:int="", CClusterY:int=""):
+ """
+ Steps the chuck to the specified x,y cluster die location of the cluster map. If
+ no command data is passed, the chuck automatically steps to the next logical
+ cluster map location. If clusters are not defined, the Die information is used.
+ Returns the row and column number of the actual die location after the move is
+ completed.
+ API Status: published
+ Args:
+ CClusterX:int = 0
+ CClusterY:int = 0
+ Returns:
+ RClusterX:int
+ RClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+ global StepNextCluster_Response
+ if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode:str="", StartColumn:str="", StartRow:str="", MoveParam:str=""):
+ """
+ Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+ is done for the shortest move way for the station.
+ API Status: published
+ Args:
+ MoveMode:str = "B"
+ StartColumn:str = "L"
+ StartRow:str = "T"
+ MoveParam:str = "H"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+ """
+ Returns the specified move path for the probe station inside the Wafer Map.
+ API Status: published
+ Returns:
+ MoveMode:str
+ StartColumn:str
+ StartRow:str
+ MoveParam:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+ global GetMapRoute_Response
+ if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+ return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters:int="", ClusterWidth:int="", ClusterHeight:int="", TestIncomplete:int=""):
+ """
+ Specifies the clusters parameters.
+ API Status: published
+ Args:
+ UseClusters:int = 0
+ ClusterWidth:int = 1
+ ClusterHeight:int = 1
+ TestIncomplete:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+ """
+ Returns current clusters parameters.
+ API Status: published
+ Returns:
+ UseClusters:int
+ ClusterWidth:int
+ ClusterHeight:int
+ TestIncomplete:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+ global GetClusterParams_Response
+ if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+ return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+ """
+ Deletes current wafer map, sub dies and binning information; then creates new
+ wafer map with defaults parameters.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X:Decimal="", Y:Decimal="", Label:str=""):
+ """
+ Adds new subdie at the end of the table.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+ return int(rsp[0])
+
+def DeleteSubDie(Site:int=""):
+ """
+ Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+ not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+ for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+ support. DeleteSubDie2 is the preferred method for deleting a selected
+ subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+ dies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+ return int(rsp[0])
+
+def GetNumSelectedClusters():
+ """
+ Gets the number of clusters in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedClusters:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+ return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex:int=""):
+ """
+ Given the index of a selected cluster in the range [1..NumSelectedClusters],
+ returns the column and row indices for the selected cluster.
+ API Status: published
+ Args:
+ ClusterIndex:int = 0
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+ global GetSelectedClusterCoords_Response
+ if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+ return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int=""):
+ """
+ Gets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int="", Status:str=""):
+ """
+ Sets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName:str=""):
+ """
+ Opens a Bin Code Table file (.bct) with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName:str=""):
+ """
+ Saves bin code table to a file with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize:int=""):
+ """
+ Sets size of the bin code table. This is the size of bins used in statistics and
+ binning.
+ API Status: published
+ Args:
+ BinsSize:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+ """
+ Gets size of the bin code table.
+ API Status: published
+ Returns:
+ BinsSize:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+ return int(rsp[0])
+
+def StepFailedClusterBack():
+ """
+ Steps the chuck the consecutive failed clusters back (goes back to the last
+ known good cluster) and returns the number of consecutive failed clusters.
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+ return int(rsp[0])
+
+def StepFailedClusterForward():
+ """
+ Steps the chuck the consecutive failed clusters forward and returns the number
+ of consecutive failed clusters (goes to next untested cluster).
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+ return int(rsp[0])
+
+def GoToWaferHome():
+ """
+ Moves the chuck to the wafer home position.
+ API Status: published
+ Command Timeout: 6000000
+ """
+ MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+ """
+ Returns a number of all units marked to test. Note that TestSites is a number of
+ all sites for all dies.
+ API Status: published
+ Returns:
+ ClustersCount:int
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+ global GetWaferInfo_Response
+ if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+ return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster:int=""):
+ """
+ Returns a number of all dies and sites marked to test in the given cluster.
+ API Status: published
+ Args:
+ Cluster:int = 0
+ Returns:
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+ global GetClusterInfo_Response
+ if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+ return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die:int=""):
+ """
+ Returns a number of sites marked to test in the given die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+ return int(rsp[0])
+
+def ConvertToAlphas(Start:int="", Finish:int=""):
+ """
+ Returns a string of the alpha column coordinates for the given range divided by
+ spaces.
+ API Status: published
+ Args:
+ Start:int = 0
+ Finish:int = 0
+ Returns:
+ Alphas:str
+ Command Timeout: 240000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer:str=""):
+ """
+ Sets new active layer.
+ API Status: published
+ Args:
+ Layer:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+ """
+ Returns current active layer.
+ API Status: published
+ Returns:
+ Layer:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX:Decimal="", RefY:Decimal=""):
+ """
+ Sets a new reference point for the die. This point is NOT used for die stepping,
+ nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+ GUI setting, the Die Reference Point can be set to be more representative of the
+ actual reference location within the die. A setting of (0.0, 0.0) is defined as
+ the upper left corner of the die. All subdie coordinates are relative to upper
+ left corner of the die.
+ API Status: published
+ Args:
+ RefX:Decimal = 0
+ RefY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+ """
+ Returns current reference point for the die. For details see SetDieRefPoint
+ command.
+ API Status: published
+ Returns:
+ RefX:Decimal
+ RefY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+ global GetDieRefPoint_Response
+ if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+ return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+ """
+ Clears all binning data in the wafer map.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State:str="", Window:str=""):
+ """
+ Has sense in the application only (not for ActiveX controls). It shows or hides
+ a window. All parameters are case-insensitive.
+ API Status: published
+ Args:
+ State:str = "s"
+ Window:str = "setup"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin:int="", ButtonStatus:int=""):
+ """
+ Sets the current bin for the application. Second parameter allows to enable or
+ disable "Mark with Bin" mode in the application.
+ API Status: published
+ Args:
+ Bin:int = 0
+ ButtonStatus:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+ """
+ Returns the current bin in the application.
+ API Status: published
+ Returns:
+ Bin:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+ return int(rsp[0])
+
+def ReadClusterPosition(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual wafer map cluster position. If the cluster probing is
+ disabled, the command will assume a cluster of size 1x1.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ ClusterWidth:int
+ ClusterHeight:int
+ EnabledDies:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+ global ReadClusterPosition_Response
+ if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+ return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are percentages.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+ global GetWaferMapParams_Response
+ if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+ """
+ Creates a rectangular wafermap with specified parameters.
+ API Status: published
+ Returns:
+ DieWidth:Decimal
+ DieHeight:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+ global GetRectMapParams_Response
+ if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+ return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X:Decimal="", Y:Decimal=""):
+ """
+ Tries to find an appropriate position in the wafer for the current chuck
+ position. X and Y describe the chuck position of the wafer center relatively to
+ the chuck zero position. If the wafer position is found the command sets it as
+ the wafer map home position and sets the current chuck position as the chuck
+ home position. If there is no corresponding wafer position the command returns
+ error 701. Command is used by AutoAlign for the BuildMap feature.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor:str="", SearchSpeed:Decimal="", Gap:Decimal="", SuccessRatio:Decimal="", ProfDistX:Decimal="", ProfDistY:Decimal=""):
+ """
+ Sets some WaferMap profiling options remotely.
+ API Status: published
+ Args:
+ ProfileSensor:str = "e"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ SuccessRatio:Decimal = 75
+ ProfDistX:Decimal = 0
+ ProfDistY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+ """
+ Returns predefined settings of the WaferMap profiling options.
+ API Status: published
+ Returns:
+ ProfileSensor:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ SuccessRatio:Decimal
+ ProfDistX:Decimal
+ ProfDistY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+ global GetWaferProfileOptions_Response
+ if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+ return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue:int=""):
+ """
+ Starts the profiling process. To determine the current profiling state, use
+ GetWaferProfilingStatus command.
+ API Status: published
+ Args:
+ DoContinue:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+ """
+ Returns status of the profiling process. If this status is true, the process is
+ started.
+ API Status: published
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+ return int(rsp[0])
+
+def StopWaferProfiling():
+ """
+ Stops the profiling process.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+ """
+ Profiles the wafer and returns a status of the profiling as an error code.
+ API Status: published
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Profiles the wafer and returns a status of the profiling as an error code.
+ Executes profiling using the off axis camera
+ API Status: internal
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX:int="", DieY:int="", Site:int=""):
+ """
+ Returns a label from the wafer map at the current die and current subdie, unless
+ a row, column, and subdie are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label:str="", DieX:int="", DieY:int="", Site:int=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, row, and column are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns a label from the wafer map the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label:str="", CDieIndex:int="", Site:int=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex:int=""):
+ """
+ Returns a label from the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label:str="", CDieIndex:int=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the XY offset from the reference position of the Home Die to wafer
+ center in chuck coordinates.
+ API Status: internal
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+ global GetHomeDieOffset_Response
+ if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+ return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are microns.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are microns.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+ global GetWaferMapParams2_Response
+ if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle:int=""):
+ """
+ This command sets the Wafer Test Angle. This is different from the notch angle
+ and allows rotating the WaferMap.
+ API Status: published
+ Args:
+ Angle:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+ """
+ This returns the Wafer Test Angle. This is different from the notch angle and
+ allows rotating the WaferMap.
+ API Status: published
+ Returns:
+ Angle:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+ return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName:str="", ClearMap:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads the Pre-Mapped Dies Table file with specified name.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ ClearMap:int = 1
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX:int="", DieY:int=""):
+ """
+ This command is valid when a PreMapped Dies Table has been loaded. Returns
+ values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+ specified. Returns actual (as measured during the Pre-Mapping) x, y, z, and
+ theta die positions. Also returns whether or not Z and Theta are being used.
+ This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+ PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+ returned.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ UseZ:int
+ UseTheta:int
+ ActualX:Decimal
+ ActualY:Decimal
+ ActualZ:Decimal
+ Theta:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+ global GetPreMappedDieInfo_Response
+ if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+ return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result:str="", CDieIndex:int=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns a measurement result from the wafer map the current die and the current
+ subdie, unless a subdie, and die number are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result:str="", CDieIndex:int="", Site:int=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die at the
+ current subdie, unless a subdie, and die number are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables edge dies for test
+ API Status: internal
+ Args:
+ Enable:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows access to read any data item in Spectrum explorer. GetSpectrumData
+ AlignWafer/ProjectData/Mark1/ChuckPosition/X GetSpectrumData Chuck
+ Camera/Camera Settings/Shutter
+ API Status: internal
+ Args:
+ DataPath:str = ""
+ Returns:
+ Value:str
+ Command Timeout: 6000
+ Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows changing any data item in Spectrum explorer. Works independent of access
+ level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+ SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+ API Status: internal
+ Args:
+ PathAndValue:str = ""
+ Command Timeout: 6000
+ Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName:str="", XY:int="", Z:int="", Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the current chuck and microscope position and sets them as
+ new controller or chuck and microscope positions. The command was originally used
+ by ReAlignWizard but may be removed in the future because of direct access to
+ tooldata within Spectrum.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XY:int = 1
+ Z:int = 0
+ Model:int = -1
+ Command Timeout: 60000
+ Example:ReadVMPosition AlignWafer 1 0 0
+ """
+ MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName:str="", XYChuck:int="", ZChuck:int="", XYScope:int="", ZScope:int="", Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command moves to trained stages positions of a requested tool. Command is
+ used by ReAlignWizard to move to the trained positions for AutoAlign and
+ DetectWaferHeight.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XYChuck:int = 1
+ ZChuck:int = 1
+ XYScope:int = 0
+ ZScope:int = 0
+ Model:int = -1
+ Command Timeout: 120000
+ Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+ """
+ MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome:int="", AutoEdgeFind:int="", FileName:str=""):
+ """
+ ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+ to determine the contour of it. The data will be memorized as xy coordinates of
+ contour points referenced to the home position. These Points are written to a
+ file after tracking the shape.
+ API Status: published
+ Args:
+ SetHome:int = 1
+ AutoEdgeFind:int = 0
+ FileName:str = ""
+ Command Timeout: 600000
+ Example:ShapeTracker 1
+ """
+ MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition:int="", Synchronize:int="", ChuckX:Decimal="", ChuckY:Decimal=""):
+ """
+ Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+ focused on the trained chuck position or the manual adjusted reference position.
+ This tool uses the FindFocus tool with its own Range.
+ API Status: published
+ Args:
+ SetStartPosition:int = 0
+ Synchronize:int = 0
+ ChuckX:Decimal = -1
+ ChuckY:Decimal = -1
+ Returns:
+ PositionX:Decimal
+ PositionY:Decimal
+ WaferHeight:Decimal
+ SynchGap:Decimal
+ ZOffset:Decimal
+ Stage:str
+ Command Timeout: 300000
+ Example:DetectWaferHeight 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+ global DetectWaferHeight_Response
+ if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+ return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command checks if a plugin is trained and returns a string of error/warning
+ messages including information about what is not trained, setup for the tool to
+ run.
+ API Status: internal
+ Args:
+ Plugin:str = ""
+ Returns:
+ PluginAvailable:int
+ Message:str
+ Command Timeout: 1000
+ Example:CheckSpectrumPlugin AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+ global CheckSpectrumPlugin_Response
+ if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+ return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue:int="", SkipSettingHome:int=""):
+ """
+ Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+ index calculation or thermal expansion measurement. The command will update home
+ if home was trained. It will only move to its trained chuck/scope position
+ before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+ "MoveToTrainedZPosition" is true.
+ API Status: published
+ Args:
+ SetValue:int = 0
+ SkipSettingHome:int = 0
+ Command Timeout: 300000
+ Example:AutoAlign 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active:int=""):
+ """
+ Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+ SPS300/SUMMIT200 stations.) The camera quiet mode deactivates the chuck,
+ platen and contact view camera and triggers a digital output which
+ connects/disconnects these cameras firewire connection to the PC.
+ API Status: published
+ Args:
+ Active:int = 0
+ Command Timeout: 30000
+ Example:SetCameraQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol:int="", RefDieRow:int="", RefDieDistToCentreX:Decimal="", RefDieDistToCentreY:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is based on the SetMapOrientation command. It allows shifting the
+ center of the reference die to the center of the wafer.
+ API Status: internal
+ Args:
+ RefDieCol:int = 0
+ RefDieRow:int = 0
+ RefDieDistToCentreX:Decimal = 0
+ RefDieDistToCentreY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition:int=""):
+ """
+ Performs a two-point alignment and moves chuck to the trained align position. XY
+ correction is made afterwards to calculate the new home position.
+ API Status: published
+ Args:
+ TrackPosition:int = 0
+ Returns:
+ ThetaOffset:Decimal
+ Command Timeout: 120000
+ Example:AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+ return Decimal(rsp[0])
+
+def AlignChip():
+ """
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). The
+ current chip is assumed to be in the region of interest when the command is
+ called.
+ API Status: published
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChip
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChip")
+ global AlignChip_Response
+ if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount:int="", Range:Decimal=""):
+ """
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search.
+ API Status: published
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocus 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+ global FindFocus_Response
+ if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+ return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID:int=""):
+ """
+ Performs an automated aux site alignment in XYZ. Tool can correct reference
+ position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAux 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model:int="", ReturnDistanceFromModelOrigin:int="", UseSingleImageAcquisition:int=""):
+ """
+ Search user-defined models. Up to 40 different models can be trained. After
+ training, these models can be searched on screen either by direct user
+ interaction or from external applications with a remote command. The remote
+ command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+ each instance of the controller found in the region of interest.
+ API Status: published
+ Args:
+ Model:int = 1
+ ReturnDistanceFromModelOrigin:int = 0
+ UseSingleImageAcquisition:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 10000
+ Example:FindFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+ during Project loading. Does save configuration data but does not save project
+ data.
+ API Status: internal
+ Command Timeout: 6000
+ Example:CloseSpectrum
+ """
+ MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+ """
+ Saves the currently displayed image to the specified file. The image is stored
+ in the requested file format (bmp, jpg or png). By default. it will save the raw
+ camera image and an image with the overlays that are currently visible on the
+ camera view. Using a parameter, one can decide to only save either raw image,
+ overlay image or both. By Specifying 'ALL' as the mount position, the captured
+ screenshot will consist of the currently selected camera layout without
+ providing the raw image. If MountPos and FullPath are empty then the current
+ camera view with overlays is copied to the clipboard.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ FullPath:str = "Image.bmp"
+ SnapShotMode:int = 2
+ Command Timeout: 60000
+ Example:SnapImage Scope C:/Temp/Image.bmp
+ """
+ MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name:str="", Zoom:int="", LiveVideo:int="", WindowState:int=""):
+ """
+ Switches the desired video window of Spectrum as foreground and active view. The
+ camera view can be determined over a tool name or the camera mount position. The
+ second parameter defines the displays zoom factor to be used. Third parameter is
+ used to toogle the live video. Last parameter can be used to maximize a window.
+ API Status: published
+ Args:
+ Name:str = ""
+ Zoom:int = 0
+ LiveVideo:int = 2
+ WindowState:int = 1
+ Command Timeout: 6000
+ Example:SetCameraView AlignWafer 0 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name:str="", State:int="", Shutter:Decimal="", Gain:Decimal="", Brightness:int="", Contrast:int="", Sharpness:int="", Illumination:int=""):
+ """
+ Switches the light of the choosen camera on or off. Light values of -1 will
+ cause that the parameter is not affected.
+ API Status: published
+ Args:
+ Name:str = ""
+ State:int = 0
+ Shutter:Decimal = -1
+ Gain:Decimal = -1
+ Brightness:int = -1
+ Contrast:int = -1
+ Sharpness:int = -1
+ Illumination:int = -1
+ Command Timeout: 6000
+ Example:SetCameraLight AlignWafer 1 20 5
+ """
+ MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName:str="", MountPosition:str="", AskExecute:int=""):
+ """
+ Starts the wizard of a given tool on the display defined in the tool settings.
+ Additionally it can start a wizard for training single models with the syntax
+ e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+ MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+ e.g. ShowWizard Calibrate Platen
+ API Status: published
+ Args:
+ ToolName:str = ""
+ MountPosition:str = ""
+ AskExecute:int = 0
+ Returns:
+ Cancelled:int
+ Command Timeout: 10000000
+ Example:ShowWizard AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+ return int(rsp[0])
+
+def ProbeToPadAlign(Position:str=""):
+ """
+ Sets a new Home position. The command is used during ReAlign to search the
+ trained home reference controller and to calculate the new xy home position.
+ API Status: published
+ Args:
+ Position:str = "H"
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ Command Timeout: 120000
+ Example:ProbeToPadAlign H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+ global ProbeToPadAlign_Response
+ if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+ return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+ """
+ Reads the wafer ID string from the wafer's surface. Returns the read ID as
+ string. Requires IDTools license.
+ API Status: published
+ Returns:
+ OcrString:str
+ Command Timeout: 60000
+ Example:ReadOcrString
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+ """
+ Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+ API Status: published
+ Returns:
+ BarCodeString:str
+ Command Timeout: 60000
+ Example:ReadBarCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+ """
+ Reads the wafers matrix code and decodes it to a string. Requires IDTools
+ license.
+ API Status: published
+ Returns:
+ MatrixCodeString:str
+ Command Timeout: 60000
+ Example:Read2DMatrixCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the Spectrum remote mode. In this mode all user interface elements are
+ hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+ API Status: internal
+ Args:
+ Activate:int = 1
+ Command Timeout: 10000
+ Example:SetSpectrumRemote 1
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name:str=""):
+ """
+ Returns light properties of choosen camera.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ State:int
+ Shutter:Decimal
+ Gain:Decimal
+ Brightness:int
+ Contrast:int
+ Sharpness:int
+ Illumination:int
+ Command Timeout: 6000
+ Example:GetCameraLight Scope
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+ global GetCameraLight_Response
+ if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+ return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name:str=""):
+ """
+ Returns the present camera view state of a desired tool or active view.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ Zoom:int
+ LiveVideo:int
+ WindowState:int
+ Command Timeout: 6000
+ Example:GetCameraView AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+ global GetCameraView_Response
+ if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+ return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName:str="", ModelName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+ be stored in the same folder as the project file. The command was originally
+ required by ReAlignWizard and is currently no longer in use.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ ModelName:str = ""
+ Returns:
+ BitmapPath:str
+ Command Timeout: 30000
+ Example:GetPattern AlignWafer Model1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition:str="", DistPositionX:Decimal="", DistPositionY:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the ChuckCenter under a given camera. When no camera mount position is
+ given, Spectrum uses active view. If there is an Offset different from zero,
+ this position will be moved under the camera.
+ API Status: internal
+ Args:
+ MountPosition:str = ""
+ DistPositionX:Decimal = 0
+ DistPositionY:Decimal = 0
+ Command Timeout: 60000
+ Example:ShowPosition Scope
+ """
+ MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the home die coordinates when the home die is under the alignment camera
+ (for instance, the top camera). Command was used during TrainReAlign to get
+ the start position for Z-Profiling. Command is no longer used.
+ API Status: internal
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 6000
+ Example:GetCameraHomePosition
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+ global GetCameraHomePosition_Response
+ if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+ return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos:str="", SynchronizeXY:int="", SynchronizeZ:int=""):
+ """
+ Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+ the chuck camera. The chuck must be moved to get the mark in view of the
+ specified camera.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ SynchronizeXY:int = 0
+ SynchronizeZ:int = 0
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 120000
+ Example:SynchronizeCamera S 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+ global SynchronizeCamera_Response
+ if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+ return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ:int="", MeasureBothGroups:int=""):
+ """
+ Determines the chuck XYZ axis position where the needles of the probe card are
+ in focus. The output parameter is the Z axis value in microns from zero of the
+ new focus height.
+ API Status: published
+ Args:
+ UpdateZ:int = 1
+ MeasureBothGroups:int = 1
+ Returns:
+ ZPosition:Decimal
+ Command Timeout: 360000
+ Example:ProbeCardOCS 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+ return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition:Decimal="", YPosition:Decimal="", XSubsiteOffset:Decimal="", YSubsiteOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+ move. Automation must be activated/trained before command can be used. Response
+ is X, Y relative distance of adjustment from requested position.
+ API Status: internal
+ Args:
+ XPosition:Decimal = 0
+ YPosition:Decimal = 0
+ XSubsiteOffset:Decimal = 0
+ YSubsiteOffset:Decimal = 0
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:MoveChuckAutoXY 5000 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+ global MoveChuckAutoXY_Response
+ if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+ return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign:int=""):
+ """
+ Alignment for the next wafer when using VueTrack.
+ API Status: published
+ Args:
+ FullVueTrackAlign:int = 1
+ Command Timeout: 6000000
+ Example:VueTrackAlign
+ """
+ MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow:Decimal="", DistAbove:Decimal="", XOffsetCenter:int="", YOffsetCenter:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is only used internally for software testing and for providing backwards
+ compatibility with SCPI legacy commands. It executes a focus search using the
+ eVue focus drive.
+ API Status: internal
+ Args:
+ DistBelow:Decimal = 0
+ DistAbove:Decimal = 0
+ XOffsetCenter:int = 0
+ YOffsetCenter:int = 0
+ Returns:
+ FocusScore:Decimal
+ ZPosition:Decimal
+ Command Timeout: 30000
+ Example:AutoFocusEVue 200 200 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+ global AutoFocusEVue_Response
+ if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+ return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+ with optional index calculation or thermal expansion measurement. AutoAlign is
+ performed using the Platen camera. Only supported for systems with off-axis
+ camera.
+ API Status: internal
+ Args:
+ SetValue:int = 0
+ Command Timeout: 300000
+ Example:AutoAlignOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount:int="", Range:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Focus search is performed using the Platen camera. Only supported for
+ systems with off-axis camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusOffAxis 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+ global FindFocusOffAxis_Response
+ if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+ return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID:int=""):
+ """
+ Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+ can correct reference position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAuxOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount:int="", Range:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Uses the FindFocus tool settings but always the Platen camera -
+ independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+ that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+ have an upward looking camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusPlaten 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+ global FindFocusPlaten_Response
+ if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+ return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). This
+ command is using the off axis platen camera with functionality of ReAlign.
+ API Status: internal
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChipOffAxis
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+ global AlignChipOffAxis_Response
+ if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens:int=""):
+ """
+ Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:SelectAZoomLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+ """
+ Returns 1 of 4 symbolic lenses, coarse ranges.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:GetAZoomLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+ return int(rsp[0])
+
+def AZoomSetupDialog():
+ """
+ Opens the operator panel. In this window you can change the settings for all
+ defined lenses.
+ API Status: published
+ Command Timeout: 5000
+ Example:AZoomSetupDialog
+ """
+ MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus:int="", Ref:str=""):
+ """
+ Changes the focus magnitude.
+ API Status: published
+ Args:
+ Focus:int = 100
+ Ref:str = "R"
+ Returns:
+ RetFocus:int
+ Command Timeout: 10000
+ Example:MoveAZoomFocus 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+ return int(rsp[0])
+
+def ReadAZoomFocus():
+ """
+ Returns the focus magnitude.
+ API Status: published
+ Returns:
+ Focus:int
+ Command Timeout: 5000
+ Example:ReadAZoomFocus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+ return int(rsp[0])
+
+def MoveAZoomVelocity(Direction:str="", Velocity:int=""):
+ """
+ Moves the A-Zoom using the set focus speed.
+ API Status: published
+ Args:
+ Direction:str = ""
+ Velocity:int = 100
+ Returns:
+ RetVelocity:Decimal
+ Command Timeout: 240000
+ Example:MoveAZoomVelocity + 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+ return Decimal(rsp[0])
+
+def StopAZoom():
+ """
+ Stops the A-Zoom movements.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAZoom
+ """
+ MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light:int=""):
+ """
+ Switches all lights ON or OFF. ON means the values defined by the current lens.
+ 1 switches the light on, 0 switches the light off. Without parameter toggles
+ between on an off.
+ API Status: published
+ Args:
+ Light:int = 0
+ Command Timeout: 5000
+ Example:SetAZoomLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the OpticalControl application. Used during Project File handling.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseAZoom
+ """
+ MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value:int="", Channel:int="", Segment:int=""):
+ """
+ Set the brightness of given channel and segment to the given value.
+ API Status: published
+ Args:
+ Value:int = 0
+ Channel:int = 1
+ Segment:int = 1
+ Command Timeout: 5000
+ Example:OCLightVal 128 1 4
+ """
+ MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On:int="", Channel:int=""):
+ """
+ Switch the light (if it has segments then all) in a given channel ON or OFF.
+ Switch ON - that means: light to the before adjusted brightness.
+ API Status: published
+ Args:
+ On:int = 0
+ Channel:int = 1
+ Command Timeout: 5000
+ Example:OCLightOn 1 1
+ """
+ MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom:int="", Motor:int=""):
+ """
+ Set logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Zoom:int = 0
+ Motor:int = 1
+ Command Timeout: 5000
+ Example:OCSetZoomLevel 50 1
+ """
+ MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor:int=""):
+ """
+ Get logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Motor:int = 1
+ Returns:
+ Zoom:int
+ Command Timeout: 5000
+ Example:OCGetZoomLevel 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+ return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int=""):
+ """
+ Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+ wafer during ramping to the new target temperature. Command returns immediately.
+ The status of temperature ramping must be checked using the
+ GetReAlignTemperatureStatus command.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ Command Timeout: 5000
+ Example:StartReAlignTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+ """
+ Stops temperature ramping using ReAlign.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopReAlignTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using ReAlign process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetReAlignTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+ global GetReAlignTemperatureStatus_Response
+ if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+ """
+ Performs an automatic realignment of the wafer. This includes measuring the
+ needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+ drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+ ProbeToDie Alignment to correct the needle position for the current die. Command
+ returns once ReAlign is finished or aborted because of an error.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ ZOffsetWafer:Decimal
+ XOffsetCard:Decimal
+ YOffsetCard:Decimal
+ ZOffsetCard:Decimal
+ Command Timeout: 1000000
+ Example:ReAlign 2 H 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+ global ReAlign_Response
+ if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+ return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+ """
+ Starts the NextWafer routine.
+ API Status: published
+ Returns:
+ Canceled:int
+ Command Timeout: 60000000
+ Example:NextWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("NextWafer")
+ return int(rsp[0])
+
+def StartReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+ """
+ Starts an automatic realignment of the wafer. This includes measuring the needle
+ drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+ XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+ Alignment to correct the needle position for the current die. Command returns
+ immediately. The status of the asynchronous ReAlign execution must be checked
+ using the GetReAlignStatus command.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Command Timeout: 60000
+ Example:StartReAlign 2 H 0 0
+ """
+ MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+ """
+ Stops the ReAlign procedure.
+ API Status: published
+ Command Timeout: 120000
+ Example:StopReAlign
+ """
+ MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+ """
+ Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+ is running.
+ API Status: published
+ Returns:
+ Running:int
+ Command Timeout: 60000
+ Example:GetReAlignStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+ return int(rsp[0])
+
+def EnableOverlay(Overlay:int=""):
+ """
+ Allows activating the overlay of the needles for the top camera.
+ API Status: published
+ Args:
+ Overlay:int = 0
+ Command Timeout: 6000
+ Example:EnableOverlay 0
+ """
+ MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Switches the offset compensation. Applicable for MicroAlign stations only.
+ API Status: internal
+ Args:
+ Offset:int = 0
+ Command Timeout: 60000
+ Example:SwitchOffset 1
+ """
+ MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command was only implemented for supporting a SCPI legacy command. Does not make
+ sense in Velox, as there is no default training rectangle on the screen as in
+ Nucleus.
+ API Status: internal
+ Args:
+ Model:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 30000
+ Example:TrainFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Returns:
+ Exposure:Decimal
+ Command Timeout: 10000
+ Example:GetEvueExposureLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+ return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Args:
+ Exposure:Decimal = 0
+ Command Timeout: 10000
+ Example:SetEvueExposureLevel
+ """
+ MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ:Decimal="", EvueVelocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the eVue focus stage to a specified position. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ EvueZ:Decimal = 0
+ EvueVelocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveEvueFocusStage 1000
+ """
+ MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the eVue focus stage. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Returns:
+ EvueZ:Decimal
+ Command Timeout: 5000
+ Example:GetEvueFocusStagePos
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+ return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command runs the AutoExpose function for the eVue. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ UseCB:int = 1
+ Command Timeout: 20000
+ Example:RunEvueAutoExpose 1
+ """
+ MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope that is connected to Velox. On eVue
+ systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+ and 0.5 to 20.0 for a 40x system.
+ API Status: internal
+ Returns:
+ Zoom:Decimal
+ Command Timeout: 5000
+ Example:GetEvueZoomLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+ return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+ Velox. On eVue systems, this command sets the proper CCD zoom level to the
+ appropriate optical path.
+ API Status: internal
+ Args:
+ Zoom:Decimal = 0
+ Command Timeout: 5000
+ Example:SetEvueZoomLevel 2.0
+ """
+ MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int="", AlignOnFinish:int=""):
+ """
+ Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+ will re-adjust the probes and wafer during ramping to the new target
+ temperature.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ AlignOnFinish:int = 1
+ Command Timeout: 5000
+ Example:StartAutomationTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+ """
+ Stops temperature ramping using Automation.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopAutomationTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetAutomationTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+ global GetAutomationTemperatureStatus_Response
+ if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+ """
+ Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+ active. Command is used by WaferMap to read if it must send MoveChuckAutoXY
+ instead of MoveChuck
+ API Status: published
+ Returns:
+ Active:int
+ Command Timeout: 1000
+ Example:GetAutomationActive
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+ return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex:int="", MoveScope:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ VueTrack vision search of the given needle index.
+ API Status: internal
+ Args:
+ NeedleIndex:int = 1
+ MoveScope:int = 1
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ ZMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationNeedleSearch 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+ global AutomationNeedleSearch_Response
+ if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+ return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ AutomationReferenceSearch exposes the functionality of searching the Automation
+ reference target via remote command
+ API Status: internal
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationReferenceSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+ global AutomationReferenceSearch_Response
+ if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+ return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the configured motorized positioners to a safe position
+ API Status: internal
+ Command Timeout: 60000
+ Example:MovePositionersSafe
+ """
+ MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn:int="", ForceLastCorrection:int=""):
+ """
+ Starts Constant Contact mode using Automation. The Automation will re-adjust the
+ wafer during ramping to the new target temperature.
+ API Status: published
+ Args:
+ IsOn:int = 0
+ ForceLastCorrection:int = 0
+ Command Timeout: 5000
+ Example:SetConstantContactMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+ """
+ Returns the status of the current ConstantContact automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 5000
+ Example:GetConstantContactModeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+ global GetConstantContactModeStatus_Response
+ if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+ return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate:int=""):
+ """
+ Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+ be used to e.g. deactivate automation programmatically in case it is no
+ longer used. When activating automation, the command will return an error in
+ case it is not possible (e.g. not trained)
+ API Status: published
+ Args:
+ Activate:int = 0
+ Command Timeout: 1000
+ Example:SetAutomationActive 1
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+ """
+ Performs an Automation search and position correction using the current chuck
+ position. Response is X, Y relative distance of adjustment.
+ API Status: published
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:AutomationSearchCurrentDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+ global AutomationSearchCurrentDie_Response
+ if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+ return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+ """
+ PreMapWafer finds actual singulated die locations and updates positions used by
+ WaferMap.
+ API Status: published
+ Returns:
+ NumberOfDies:int
+ Command Timeout: 14400000
+ Example:PreMapWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+ return int(rsp[0])
+
+def ISSProbeAlign():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs an probe to pad operation on the ISS with two RF positioners.
+ API Status: internal
+ Command Timeout: 6000000
+ Example:ISSProbeAlign
+ """
+ MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery:int=""):
+ """
+ FindWaferCenter finds the center of the wafer using edge detection.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:FindWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+ global FindWaferCenter_Response
+ if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+ return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery:int=""):
+ """
+ LocateHomeDie finds the center of the wafer using edge detection and sets the
+ home position.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:LocateHomeDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+ global LocateHomeDie_Response
+ if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+ return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName:str="", ProbeID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stores the provided X or Y offset for the given probe for the specified layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Command Timeout: 10000
+ Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+ If optional ProbeID parmameter is set, it removes just that probe from the
+ layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 10000
+ Example:DeleteAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+ just that probe from the layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 30000
+ Example:CaptureAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move to the probes to specfied layout which are offsets from the trained
+ positions.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ Command Timeout: 300000
+ Example:MoveToAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+ """
+ Reset automation data back to trained values.
+ API Status: published
+ Command Timeout: 10000
+ Example:ResetAutomation
+ """
+ MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+ """
+ GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+ returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+ API Status: published
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 10000
+ Example:GetWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+ global GetWaferCenter_Response
+ if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+ return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the eVue focus stage by finding the limit switches
+ API Status: internal
+ Command Timeout: 30000
+ Example:InitEvueFocusStage
+ """
+ MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Args:
+ NumTraceEntriesPreTrigger:int = 0
+ Command Timeout: 30000
+ Example:EvueSetNumTraceEntriesPreTrigger 14
+ """
+ MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Returns:
+ NumTraceEntriesPreTrigger:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntriesPreTrigger
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+ return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts capturing events in the eVue motion capture log. Capture continues until
+ the log is full. However, log entries will overwrite the oldest entry until the
+ trigger event is encountered. Then, {X} events are preserved prior to the
+ trigger event and the oldest events are only overwritten if they are not part of
+ that preserved set.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EvueStartCaptureServoTrace
+ """
+ MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+ 16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+ trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+ stopped on requested server state entry bit4 - stopped by immediate command
+ bit5..31 - reserved
+ API Status: internal
+ Returns:
+ TraceMachineStatus:int
+ Command Timeout: 30000
+ Example:EvueGetTraceMachineStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+ return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+ bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+ lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+ stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+ an index but the 4-bit state that, if seen, is the trigger for trace capture)
+ bit8..31 - reserved
+ API Status: internal
+ Args:
+ TraceCaptureStopBits:int = 0
+ Command Timeout: 30000
+ Example:EvueSetTraceCaptureStopBits
+ """
+ MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current status of the trace machine.
+ API Status: internal
+ Returns:
+ TraceEntries:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntries
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+ return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the N'th trace entry in the log.
+ API Status: internal
+ Args:
+ EntryIdx:int = 0
+ Returns:
+ CommandedPositionMotorCounts:int
+ CommandedPositionMicrons:Decimal
+ MeasuredPositionMotorCounts:int
+ MeasuredPositionMicrons:Decimal
+ TimestampMicroseconds:int
+ ServoStatus:int
+ PwmVal:int
+ Command Timeout: 30000
+ Example:EvueGetTraceEntry 32
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+ global EvueGetTraceEntry_Response
+ if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+ return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the distance in X,Y between the center tips of the RF probes.
+ API Status: internal
+ Args:
+ ImageFilename:str = ""
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ Example:AutomationRFProbeSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+ global AutomationRFProbeSearch_Response
+ if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+ return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the AutoRF calibration sequence.
+ API Status: internal
+ Command Timeout: 3000
+ Example:StartAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the currently running AutoRF calibraiton.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the status of the AutoRF calibration sequence.
+ API Status: internal
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 1000
+ Example:GetAutoRFCalibrationStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+ global GetAutoRFCalibrationStatus_Response
+ if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+ return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the diagnostic state information for the provided index.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ DiagnosticInfo:str
+ Command Timeout: 5000
+ Example:GetAutomationLastStepDiagnostics
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the WLEM Nano Chamber State.
+ API Status: internal
+ Args:
+ State:str = "Free"
+ Command Timeout: 5000
+ Example:SetWLEMNanoChamberState Free
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the WLEM Nano Chamber State.
+ API Status: internal
+ Returns:
+ State:str
+ Command Timeout: 5000
+ Example:GetWLEMNanoChamberState
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMState NCSeal 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMState NCSeal
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+ return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the value of a WLEM Sensor.
+ API Status: internal
+ Args:
+ Sensor:str = "O2Concentration"
+ Returns:
+ Value:Decimal
+ Command Timeout: 5000
+ Example:GetWLEMSensorValue O2Concentration
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+ return Decimal(rsp[0])
+
+def SetWLEMOption(Option:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMOption MinimizeToTray 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMOption MinimizeToTray
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+ return int(rsp[0])
+
+def NewTesterProject(LotID:str="", TileID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a new Lot/Tile is to be tested. The tester
+ responds with the correct project name for the test. This is needed because the
+ prober needs to verify that the correct project is loaded. In case no valid
+ project is available, the command is returned with an error.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ TileID:str = ""
+ Returns:
+ ProjectName:str
+ Command Timeout: 30000
+ Example:NewTesterProject Lot01 Tile01
+ """
+ rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn:int="", DieRow:int="", ActiveDies:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester to begin measuring (Needles are in correct
+ position and in contact). The command is responded when the measurement has
+ finished. The response string holds the binning information separated by comma.
+ For deactivated dies, a bin value of '0' should be responded.
+ API Status: internal
+ Args:
+ DieColumn:int = 0
+ DieRow:int = 0
+ ActiveDies:str = ""
+ Returns:
+ BinNumbers:str
+ Command Timeout: 100000
+ Example:StartMeasurement 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current substrate has
+ finished. It enables the tester application to save measurement data and/or
+ prepare for the next substrate.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfWafer
+ """
+ MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current lot has finished. It
+ enables the tester application to save measurement data and/or prepare for the
+ next lot.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfLot
+ """
+ MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProductID that is to be tested. The
+ tester can respond with an error in case the ProductID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ ProductID:str = ""
+ Command Timeout: 30000
+ Example:VerifyProductID Product123
+ """
+ MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the LotID that is to be tested. The tester
+ can respond with an error in case the LotID is not allowed for testing.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyLotID Lot123
+ """
+ MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the SubstrateID that is to be tested. The
+ tester can respond with an error in case the SubstrateID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ Command Timeout: 30000
+ Example:VerifySubstrateID Substrate123
+ """
+ MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard:str="", Touchdowns:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProbecardID and touchdowns that is
+ used for testing. The tester can respond with an error in case the Probecard is
+ not allowed for testing.
+ API Status: internal
+ Args:
+ ProbeCard:str = ""
+ Touchdowns:int = 0
+ Command Timeout: 30000
+ Example:VerifyProbecard Probecard123 10596
+ """
+ MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the User ID. The tester can respond with
+ an error in case the User ID is not allowed for testing.
+ API Status: internal
+ Args:
+ User:str = ""
+ Command Timeout: 30000
+ Example:VerifyUserID User123
+ """
+ MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the job was aborted and no more test will
+ happen.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbort
+ """
+ MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a wafer is ready for testing which will
+ immediately start. This command is sent in the recipe sequence "Verify
+ SOTReady".
+ API Status: internal
+ Command Timeout: 30000
+ Example:VerifySOTReady
+ """
+ MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID:str="", CassettePlace:str="", LotID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+ informs the tester about the current wafer on the chuck.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ CassettePlace:str = ""
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyWaferStart Wafer01 1 Lot01
+ """
+ MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command will be sent after the user selected which wafers are to be tested.
+ It contains a string which represents the state of each wafer: 0 = empty, 1 =
+ full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+ deselected
+ API Status: internal
+ Args:
+ CassetteCmd:str = ""
+ Returns:
+ CassetteRsp:str
+ Command Timeout: 30000
+ Example:TesterCassetteInfo 0000001110000000010010111
+ """
+ rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent after selecting a project file in the VeloxPro product
+ setup page. The command sends the name of the project to tester for
+ verification.
+ API Status: internal
+ Args:
+ ProjectName:str = ""
+ Command Timeout: 30000
+ Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+ """
+ MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the test for the current wafer was aborted
+ and no more tests will happen with the current wafer. The job will continue
+ though.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbortWafer
+ """
+ MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts execution of one test. It returns a bin number or multple bin numbers
+ when clusters are enabled in the WaferMap (one number for each die in a
+ cluster). The command starts execution of one test. It returns a bin number or
+ multple bin numbers when clusters are enabled in the WaferMap (one number for
+ each die in a cluster).
+ API Status: internal
+ Returns:
+ BitNumber:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+ return int(rsp[0])
+
+def StartTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the test of a wafer. Depending on the cluster definitions queried from
+ the WaferMap, all clusters or all dies will be tested. The command starts the
+ test of a wafer. Depending on the cluster definitions queried from the WaferMap
+ all clusters or all dies will be tested.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the wafer test.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line:int="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the selected line of PA port.
+ API Status: internal
+ Args:
+ Line:int = 0
+ Value:int = 0
+ Command Timeout: 10000
+ Example:SetTTLLine 2 0
+ """
+ MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the I/O lines as bit array.
+ API Status: internal
+ Returns:
+ LineA:int
+ LineB:int
+ LineC:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+ global GetTTLLines_Response
+ if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+ return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns returns the error 914 if the test is in progress.
+ API Status: internal
+ Returns:
+ ErrCode:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+ return int(rsp[0])
+
+def StartScript(ScriptName:str=""):
+ """
+ Starts the script and returns the response immediately.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000
+ Example:StartScript myscript
+ """
+ MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName:str=""):
+ """
+ Command returns information about Communicator status.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Returns:
+ Running:int
+ LastError:int
+ Title:str
+ Command Timeout: 5000
+ Example:GetRunStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+ global GetRunStatus_Response
+ if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+ return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+ """
+ Command closes the program. Used during ProjectFile handling.
+ API Status: published
+ Command Timeout: 10000
+ Example:CloseCommunicator
+ """
+ MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName:str=""):
+ """
+ Executes the script and returns the response afterwards.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000000
+ Example:DoScript myscript
+ """
+ MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads Kernel Data to KernelSetup (Left Program pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReadKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves Kernel Data (Left Program pane) to File. An existing File will be
+ overwritten. If the Folder does not exist, it will be created
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads File Data to KernelSetup (Right Program pane).
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces Kernel Data (Left pane) by File Data (Right pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceKernelDataByFileData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces File Tree (Right pane) by Kernel Data (Left pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceFileTreeByKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+ the Folder does not exist, it will be created.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature:Decimal="", Unit:str="", ReduceContact:int=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the chuck. An
+ answer to the command will be returned after reaching the given temperature and
+ waiting the soak time or an unexpected interrupt of the process. Given back is
+ the already reached temperature.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ ReduceContact:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 36000000
+ Example:HeatChuck 61.3 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+ global HeatChuck_Response
+ if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+ return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature:Decimal="", Unit:str="", UseContactSafety:int=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the
+ temperature chuck. The new target temperature is returned immediately as the
+ command does not wait until heating is complete.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ UseContactSafety:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:SetHeaterTemp 55.5 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+ global SetHeaterTemp_Response
+ if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+ return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit:str="", ExternalHeaterID:int=""):
+ """
+ Reads the current temperature of the chuck and determines the status of the
+ thermal system.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ ExternalHeaterID:int = 0
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Status:str
+ Command Timeout: 60000
+ Example:GetHeaterTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+ global GetHeaterTemp_Response
+ if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+ return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode:int=""):
+ """
+ Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+ chuck is heated with a constant current to avoid noise from the temperature
+ control. The hold mode can be enabled only in HoldReady state.
+ API Status: published
+ Args:
+ HoldMode:int = 1
+ Returns:
+ RespHoldMode:int
+ Command Timeout: 60000
+ Example:EnableHeaterHoldMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+ return int(rsp[0])
+
+def StopHeatChuck():
+ """
+ Stops a pending heating or cooling process. If the device is not at temperature,
+ the actual temperature is set as target temperature.
+ API Status: published
+ Command Timeout: 60000
+ Example:StopHeatChuck
+ """
+ MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit:str=""):
+ """
+ Returns the current dew point temperature, if a dew point sensor is connected.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetDewPointTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+ global GetDewPointTemp_Response
+ if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+ return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the currently set temperature chuck options.
+ API Status: internal
+ Returns:
+ UseSoakTime:int
+ SyncTemp:int
+ CurrConnection:int
+ MinTemperature:Decimal
+ MaxTemperature:Decimal
+ UsePurge:int
+ UseDynamicSoakTime:int
+ UseFixedDieSoakTime:int
+ UseDynamicDieSoakTime:int
+ UseEcoMode:int
+ PurgeOnChamberDoor:int
+ ForceBypassPurge:int
+ DoorClosedTime:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+ global GetTemperatureChuckOptions_Response
+ if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+ return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak:int="", SyncTemp:int="", CurrConnection:int="", UsePurge:int="", UseDynamicWaferSoak:int="", UseFixedDieSoakTime:int="", UseDynamicDieSoakTime:int="", UseEcoMode:int="", PurgeOnChamberDoor:int="", ForceBypassPurge:int="", DoorClosedTime:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is used to change the currently set temperature chuck options.
+ API Status: internal
+ Args:
+ UseFixedWaferSoak:int = -1
+ SyncTemp:int = -1
+ CurrConnection:int = -1
+ UsePurge:int = -1
+ UseDynamicWaferSoak:int = -1
+ UseFixedDieSoakTime:int = -1
+ UseDynamicDieSoakTime:int = -1
+ UseEcoMode:int = -1
+ PurgeOnChamberDoor:int = -1
+ ForceBypassPurge:int = -1
+ DoorClosedTime:int = -1
+ Returns:
+ UseFixedWaferSoakRsp:int
+ SyncTempRsp:int
+ CurrConnectionRsp:int
+ UsePurgeRsp:int
+ UseDynamicWaferSoakRsp:int
+ UseFixedDieSoakTimeRsp:int
+ UseDynamicDieSoakTimeRsp:int
+ UseEcoModeRsp:int
+ PurgeOnChamberDoorRsp:int
+ ForceBypassPurgeRsp:int
+ DoorClosedTimeRsp:int
+ Command Timeout: 300000
+ Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+ global SetTemperatureChuckOptions_Response
+ if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+ return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+ """
+ Returns the current soak time values in seconds and the soaking status.
+ API Status: published
+ Returns:
+ FixedWaferSoakTime:int
+ FixedWaferSoakStatus:int
+ DynamicWaferSoakTime:Decimal
+ DynamicWaferSoakStatus:int
+ FixedDieSoakTime:Decimal
+ DynamicDieSoakTime:Decimal
+ FixedDieSoakStatus:int
+ DynamicDieSoakStatus:int
+ Command Timeout: 60000
+ Example:GetHeaterSoak
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+ global GetHeaterSoak_Response
+ if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+ return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime:int="", DynamicWaferSoakTime:Decimal="", FixedDieSoakTime:Decimal="", DynamicDieSoakTime:Decimal=""):
+ """
+ Sets the new soak time values. The unit of the values is seconds. If soak time
+ is actually running, it may be affected by the change.
+ API Status: published
+ Args:
+ FixedWaferSoakTime:int = 60
+ DynamicWaferSoakTime:Decimal = -1
+ FixedDieSoakTime:Decimal = -1
+ DynamicDieSoakTime:Decimal = -1
+ Command Timeout: 60000
+ Example:SetHeaterSoak 60
+ """
+ MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby:int=""):
+ """
+ Switches the power save (standby) mode of the device on or off. If the device is
+ in power save mode, setting and reading temperatures switches off the power save
+ mode automatically.
+ API Status: published
+ Args:
+ Standby:int = 1
+ Returns:
+ RespStandby:int
+ Command Timeout: 60000
+ Example:EnableHeaterStandby 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+ return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+ """
+ Returns values of the temperature chuck status. The status byte gives
+ information about the current controller's action. The dew point sensor status
+ encapsulates information, if such a sensor is connected, and if the actual dew
+ point difference temperature is readable (active). It can be used for purge
+ control. Soak time left (in seconds) is used when soak time is actually running.
+ API Status: published
+ Returns:
+ Status:str
+ DPSensor:int
+ SoakTimeLeft:int
+ HasEcoMode:int
+ Command Timeout: 60000
+ Example:ReadTemperatureChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+ global ReadTemperatureChuckStatus_Response
+ if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+ return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit:str=""):
+ """
+ Reads the target temperature of the chuck.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetTargetTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+ global GetTargetTemp_Response
+ if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+ return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command sets the window for the target temperture which is the window in which a
+ station is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Args:
+ Window:Decimal = 1
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:SetThermoWindow 2.0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+ return Decimal(rsp[0])
+
+def GetThermoWindow():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command returns the current thermo window which is the window in which a station
+ is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:GetThermoWindow
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+ return Decimal(rsp[0])
+
+def SendThermoCommand(Command:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends a command string to the thermal chuck using the thermal chuck protocol and
+ returns the thermal chucks response as command response. This command can be
+ used to access thermal chuck features that are not exposed as standalone SCI
+ commands. Command is currently implemented for ERS and ATT chucks.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:SendThermoCommand RH
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID:int=""):
+ """
+ Returns the status of a single AUX site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ FlagsMode:int
+ Comp:str
+ PresetHeight:str
+ AuxSiteType:str
+ Command Timeout: 10000
+ Example:ReadAuxStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+ global ReadAuxStatus_Response
+ if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+ return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID:int="", Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+ position is read for the chuck stage. If no AUX ID is given, it tries to read
+ the position from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ AuxIDEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxPosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+ global ReadAuxPosition_Response
+ if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+ return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID:int="", Unit:str=""):
+ """
+ Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+ all response values are read from chuck stage. If no AUX ID is given, it tries
+ to read the heights from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+ global ReadAuxHeights_Response
+ if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID:int="", Overtravel:int=""):
+ """
+ Modes manage the way a stage behaves when it is in contact height. AUX site mode
+ holds only a single flag. Flags can be turned on by using the value 1 or turned
+ off by using the value 0. If you do not want to change the flag - use the value
+ of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+ move an additional overtravel on every contact move.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Overtravel:int = 2
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxMode 1 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+ return int(rsp[0])
+
+def SetAuxHome(AuxID:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+ sites coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetAuxIndex(AuxID:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+ chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetAuxHeight(AuxID:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Sets the AUX sites contact height and corresponding gaps for overtravel,
+ alignment and separation height. A contact height search gap for contact search
+ with edge sensor can also be set. This search gap is always identical for all
+ AUX sites. Without any optional parameters the command sets contact height to
+ the current position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadAuxIndex(AuxID:int="", Unit:str=""):
+ """
+ Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+ is read from chuck stage. If no AUX ID is given, it tries to read the index from
+ the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+ global ReadAuxIndex_Response
+ if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+ return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID:int="", Mode:str="", Unit:str="", Position:Decimal=""):
+ """
+ Sets the AUX sites theta home position. It defines the origin of the AUX sites
+ theta coordinate system for later movements. If AUX ID is set to 0, theta home
+ position is set for chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Position:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxThetaHome 1 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+ return int(rsp[0])
+
+def EnableOffset(Stage:str="", Enable:int="", Move:int=""):
+ """
+ Enables or disables the Offset XY compensation for the selected stage. If the
+ compensation holds an offset different from zero, the chuck is automatically
+ moved the distance of the offset. The chuck also moves automatically to a safe
+ height. The move can be disabled by the third parameter. This may put the stage
+ outside the software fence.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Enable:int = 1
+ Move:int = 1
+ Command Timeout: 60000
+ Example:EnableOffset C 1
+ """
+ MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+ """
+ Sets the offset values for the Offset XY compensation for the selected stage.
+ The changes take effect immediately. Note that the Offset XY compensation must
+ be enabled for the values to take effect. The compensation is enabled or
+ disabled using EnableOffset command.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetOffset C 100000.0 0.0
+ """
+ MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage:str=""):
+ """
+ Gets information about the Offset XY compensation of the selected stage,
+ including the stored offset values and whether the compensation is enabled or
+ disabled.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Enable:int
+ OffsetX:Decimal
+ OffsetY:Decimal
+ Command Timeout: 5000
+ Example:GetOffsetInfo C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+ global GetOffsetInfo_Response
+ if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+ return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage:str="", AuxSite:int="", X:Decimal="", Y:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the switch position of a stage. This is the position to move to if an aux
+ site gets active. This is only supported for the chuck and it's aux sites. Aux
+ index 0 means wafer site, 1 means aux site 1 and so on.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxSite:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 5000
+ Example:SetSwitchPosition C 0 5000 5000
+ """
+ MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID:int=""):
+ """
+ Moves the chuck to the position of a given AUX site. A safe height is used for
+ the move. If AUX ID is set to 0, the target of the move is the wafer site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 60000
+ Example:MoveAuxSite 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount:int=""):
+ """
+ Sets the number of available AUX sites. For preparing for example two cal
+ chucks, the count must be set to 2. For the changes to take effect the system
+ needs to be restarted.
+ API Status: published
+ Args:
+ AuxSiteCount:int = 0
+ Command Timeout: 10000
+ Example:SetAuxSiteCount 2
+ """
+ MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+ """
+ Reads the number of available AUX sites and the ID of the actual active AUX
+ site. If this is 0, the chuck stage is currently active.
+ API Status: published
+ Returns:
+ AuxSiteCount:int
+ ActualAuxSite:int
+ Command Timeout: 10000
+ Example:GetAuxSiteCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+ global GetAuxSiteCount_Response
+ if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+ return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID:int="", AuxSiteName:str=""):
+ """
+ Sets the description of an AUX site. With AUX ID zero, the description of the
+ wafer site can be set.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteName:str = ""
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteName 1 Aux site 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+ return int(rsp[0])
+
+def GetAuxSiteName(AuxID:int=""):
+ """
+ This command reads the description of an AUX site. If AUX ID is set to 0, the
+ description of the chuck stage is given back. If no AUX ID is given, it tries to
+ read from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ Example:GetAuxSiteName 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+ global GetAuxSiteName_Response
+ if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+ return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID:str=""):
+ """
+ Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+ dependent from the type of the AUX site and from the duration and the cleaning
+ count that is set in configuration. The cleaning algorithm includes both a move
+ to the pad site and a move back to the source site.
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 300000
+ Example:CleanProbeTip 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteType(AuxID:int="", AuxSiteType:str=""):
+ """
+ Sets the type for a given AUX site. It depends on the type of the AUX site, if
+ there is a cleaning algorithm available. It is not possible to set the type of
+ the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteType:str = "AuxUnknown"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteType 1 G
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+ return int(rsp[0])
+
+def SetCleaningParams(AuxID:int="", Count:int="", Time:int=""):
+ """
+ Sets the cleaning parameters for a given AUX site. It is not possible to set the
+ cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+ tries to set the parameters of the active site. The cleaning count defines,
+ how much times the cleaning is performed repeatedly. The cleaning time defines,
+ how much milliseconds the needles wait in cleaning position during each
+ cleaning cycle.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Count:int = 1
+ Time:int = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetCleaningParams 1 5 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+ return int(rsp[0])
+
+def GetCleaningParams(AuxID:int=""):
+ """
+ Reads the cleaning parameters of a given AUX site. It is not possible to read
+ cleaning parameters of the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Count:int
+ Time:int
+ Remaining:int
+ Command Timeout: 30000
+ Example:GetCleaningParams
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+ global GetCleaningParams_Response
+ if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+ return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Rotate the switch, home, and fence positions to match the current chuck theta
+ angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+ that don't move theta.
+ API Status: internal
+ Args:
+ AuxID:int = -1
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 5000
+ Example:UpdateAuxSitePositions 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+ return int(rsp[0])
+
+def ResetCleaningPosition(AuxID:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+ """
+ Resets the cleaning position to the beginning of the cleaning aux site (home).
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:ResetCleaningPosition 5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+ return int(rsp[0])
+
+def BnR_EchoData(ControllerID:int="", TestCmd:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Test Command for the Kernel Communication. It is like a ping command. The given
+ text string is returned unchanged.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:BnR_EchoData 1 Hello World
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID:int="", Module:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual version information of the controller software.
+ The 'Version' value contains version number and revision level of the actual
+ implementation. The text string contains a
+ code description, version number and the revision date.
+ The 'Module' byte is optional (default is K).
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:BnR_ReportKernelVersion 1 K
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+ global BnR_ReportKernelVersion_Response
+ if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+ return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns information about the connected station.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StationType:str
+ Type:str
+ Command Timeout: 5000
+ Example:BnR_GetStationType 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+ global BnR_GetStationType_Response
+ if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+ return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID:int="", Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the BnR controller.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:str = "X"
+ Command Timeout: 10000
+ Example:BnR_ResetController 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID:int="", Channel:str="", State:int="", CycleTime:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ State:int = 0
+ CycleTime:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetOutput 1 1000 1 2000
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an output channel. By using the string identifier DO_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ Returns:
+ State:int
+ AllOutputs:str
+ Command Timeout: 5000
+ Example:BnR_GetOutput 1 DO_WaferVacuum
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+ global BnR_GetOutput_Response
+ if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+ return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an input channel. By using the string identifier DI_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DI_MotorPower"
+ Returns:
+ State:int
+ AllInputs:str
+ Command Timeout: 5000
+ Example:BnR_GetInput 1 DI_MotorPower
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+ global BnR_GetInput_Response
+ if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+ return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID:int="", Channel:str="", OutputPercent:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an analog output channel to a given value.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ OutputPercent:Decimal = 50
+ Command Timeout: 5000
+ Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current value of an analog output or input.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ Returns:
+ Value:Decimal
+ UnderOverflow:int
+ Command Timeout: 5000
+ Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+ global BnR_GetAnalogIO_Response
+ if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+ return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the startup status of the BnR controller to determine if the controller
+ is properly booted or still starting.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StartupStatus:str
+ AdditionalStatusInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetStartupStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+ global BnR_GetStartupStatus_Response
+ if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+ return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Creates a Sdm System Dump file on the B&R flash
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 60000
+ Example:BnR_CreateSdmSystemDump
+ """
+ MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets controller data from the B&R controller. Currently used for init
+ information.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 10000
+ Example:BnR_GetControllerData 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID:int="", MessageType:str="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to write a (native) message to Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Message:str = ""
+ Command Timeout: 5000
+ Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID:int="", MessageType:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to read a (native) message from Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Returns:
+ Message:str
+ Command Timeout: 5000
+ Example:BnR_ReadMessage 1 mtCryoLoader
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID:int="", ShowAll:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters
+ and requires the BnR_GetNextDatum command.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 5000
+ Example:BnR_GetDataIterator 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+ global BnR_GetDataIterator_Response
+ if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID:int="", IdentityToken:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:BnR_GetNextDatum 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+ global BnR_GetNextDatum_Response
+ if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+ return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID:int="", PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID:int="", PathName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathName:str = ""
+ Returns:
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+ global BnR_GetDatum_Response
+ if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+ return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID:int="", Task:str="", PCmdInt1:int="", PCmdInt2:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes an internal BnR Task
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Task:str = ""
+ PCmdInt1:int = 0
+ PCmdInt2:int = 0
+ Returns:
+ RspInt:int
+ RspString:str
+ Command Timeout: 10000
+ Example:BnR_DoInternalTask 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+ global BnR_DoInternalTask_Response
+ if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+ return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage:str="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+ as well as the commanded positions.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Unit:str = "Microns"
+ Returns:
+ XorT:Decimal
+ Y:Decimal
+ Z:Decimal
+ CommandedXorT:Decimal
+ CommandedY:Decimal
+ CommandedZ:Decimal
+ Command Timeout: 5000
+ Example:BnR_GetPosition 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+ global BnR_GetPosition_Response
+ if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+ return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage:str="", XValue:Decimal="", YValue:Decimal="", VelX:Decimal="", VelY:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a XY movement for a specified stage. This can be either a
+ blocking or non blocking move.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ VelX:Decimal = 0
+ VelY:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 60000
+ Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+ global BnR_Move_Response
+ if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+ return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage:str="", ZValue:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the stage Z axis to a new position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZValue:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ Z:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZ 1 C 12000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID:int="", Stage:str="", ZDistance:Decimal="", TriggerEveryNthCycle:int="", Vel:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a scan movement of the Z axis that sets a digital output
+ every couple microns to trigger e.g. a camera. After the move is finished, the
+ command returns a list of Z heights at which the digital output was set.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Stage:str = "Chuck"
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 2
+ Vel:Decimal = 10
+ Command Timeout: 300000
+ Example:BnR_ScanMoveZ 1 C 1000 6 10
+ """
+ MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue:Decimal="", Vel:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes a movement of the theta axis, either blocking or non blocking
+ API Status: internal
+ Args:
+ TValue:Decimal = 0
+ Vel:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ T:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveT 1 1.003 10 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage:str="", FlagsStop:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops 1... all axes of a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:BnR_StopAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage:str="", FlagsInit:int="", FlagsDirection:int="", FlagsInitInPlace:int="", LowLimitX:Decimal="", LowLimitY:Decimal="", LowLimitZ:Decimal="", LowLimitTh:Decimal="", InitInPlaceMoveRangeX:Decimal="", InitInPlaceMoveRangeY:Decimal="", InitInPlaceMoveRangeZ:Decimal="", InitInPlaceMoveRangeTh:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Machine Coordinate System: X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+ _FlagsInitInPlace_: X, Y, Z, Theta All flags can be accessed by indirect
+ members. Initializes the stage and resets current coordinate system. Should be
+ used only in cases when the reported coordinates do not correspond to real
+ position of mechanics. Init in Place performs the initialization without any
+ movements.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsInitInPlace:int = 0
+ LowLimitX:Decimal = 0
+ LowLimitY:Decimal = 0
+ LowLimitZ:Decimal = 0
+ LowLimitTh:Decimal = 0
+ InitInPlaceMoveRangeX:Decimal = 0
+ InitInPlaceMoveRangeY:Decimal = 0
+ InitInPlaceMoveRangeZ:Decimal = 0
+ InitInPlaceMoveRangeTh:Decimal = 0
+ Command Timeout: 300000
+ Example:BnR_InitAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+ g/homing/continuousmotion/discretemotion/synchronizedmotion)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ State:str
+ AdditionalStateInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetAxisState 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+ global BnR_GetAxisState_Response
+ if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+ return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns some axis status information
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ Initialized:int
+ PositiveEndlimit:int
+ NegativeEndlimit:int
+ Command Timeout: 5000
+ Example:BnR_GetAxisStatus 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+ global BnR_GetAxisStatus_Response
+ if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+ return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage:str="", QuietMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to enable the quiet mode for a stage (quiet turns motors powerless)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ QuietMode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetQuietMode 1 C 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to query the quiet mode for a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ QuietMode:int
+ Command Timeout: 5000
+ Example:BnR_GetQuietMode 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+ return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage:str="", Axis:str="", InfoType:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns various axis information, dependent on the InfoType
+ parameter
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ InfoType:str = "StallInfo"
+ Returns:
+ RspString:str
+ Command Timeout: 5000
+ Example:BnR_GetInternalAxisInfo 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to get various information required for the BnR wiring tester tool.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ STIn_ModuleOK:int
+ STIn_LifeCnt:int
+ STIn_DrvOK:int
+ STIn_OvertemperatureError:int
+ STIn_CurrentError:int
+ STIn_OvercurrentError:int
+ STIn_RefPulsePos:int
+ STIn_RefPulseCnt:int
+ STIn_ModulePowerSupplyError:int
+ STOut_SetTime:int
+ STOut_MotorStep0:int
+ STOut_DriveEnable:int
+ STOut_BoostCurrent:int
+ STOut_StandStillCurrent:int
+ STOut_ClearError:int
+ CMIn_ModuleOK:int
+ CMIn_SDCLifeCount:int
+ CMIn_Encoder:int
+ CMIn_EncoderTimeValid:int
+ CMIn_DigitalInput1:int
+ CMIn_DigitalInput2:int
+ CMIn_BWChannelA:int
+ CMIn_BWChannelB:int
+ CMIn_PowerSupply2:int
+ CMOut_QuitChannelA:int
+ CMOut_QuitChannelB:int
+ SWAxisErrorID:int
+ SWAxisErrorDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetWiringTesterData 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+ global BnR_GetWiringTesterData_Response
+ if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+ return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage:str="", Axis:str="", Value:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows moving a single axis to and e.g. in case of X does not
+ trigger a Y movement
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Value:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ PositionAfterMove:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveAxis 1 C X 20000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ:Decimal="", WaitFinished:int="", ForcedAbsVelocity:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+ API Status: internal
+ Args:
+ ChuckTargetZ:Decimal = 0
+ WaitFinished:int = 1
+ ForcedAbsVelocity:int = 0
+ Returns:
+ ChuckZ:Decimal
+ ScopeX:Decimal
+ ScopeY:Decimal
+ ScopeZ:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZCombined 1 17592.5 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+ global BnR_MoveZCombined_Response
+ if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+ return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage:str="", ZDown:Decimal="", XValue:Decimal="", YValue:Decimal="", ZUp:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command does a combined Z-XY-Z- move completely on the BnR-controller
+ without WinKernel interaction. This is a part of an ongoing optimization.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZDown:Decimal = 0
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZUp:Decimal = 0
+ Command Timeout: 60000
+ Example:BnR_StepMove 1 C 250 1000 1000 250
+ """
+ MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos:Decimal="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a search move until the search end position is reached or the edge
+ sensor triggers. If the edge sensor triggers during the move, the trigger
+ position is returned.Otherwise, an edge sensor not found error is returned.
+ API Status: internal
+ Args:
+ SearchEndPos:Decimal = 0
+ Velocity:Decimal = 0
+ Returns:
+ EdgeSensorTriggerPos:Decimal
+ Command Timeout: 300000
+ Example:BnR_SearchEdgeSensor 3000 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+ return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a collection of trace data
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 5000
+ Example:BnR_GetTraceData 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID:int="", Mode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Commands sets the trace mode
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetTraceMode 1 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to change a module register value without controller restart
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Value:int = 0
+ Command Timeout: 5000
+ Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to get any desired module register value
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+ return int(rsp[0])
+
+def ProcessStationGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+ Initialized) and error code with error message when error.
+ API Status: internal
+ Returns:
+ Status:str
+ SubstratePresent:int
+ LastError:int
+ UseLoaderModule:int
+ WaferSizes:str
+ StatusMessage:str
+ IsLoaderJobRunning:int
+ Command Timeout: 25000
+ Example:ProcessStationGetStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+ global ProcessStationGetStatus_Response
+ if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+ return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initialize process station machine. This is not the prober init it is a fast
+ program initialization. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 2400000
+ Example:ProcessStationInit
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Finishes a process station process. This resets some internal test information
+ for the probe station. Some data is only reset in case this command is sent
+ after the last wafer in the job was tested. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 7500000
+ Example:ProcessStationFinish
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command moves the chuck of the probe station to the secondary load position and
+ if available also checks the table level sensor. Only applies to fully auto
+ systems.
+ API Status: internal
+ Command Timeout: 120000
+ Example:ProcessStationPrepareForLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck out of the load position and checks if a wafer is placed. Only
+ applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should do whatever is necessary to prepare the current wafer for
+ unload. Typically this includes things such as moving lift pins and opening
+ doors.
+ API Status: internal
+ Command Timeout: 1000000
+ Example:ProcessStationPrepareForUnLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should so whatever is necessary after a wafer is unloaded. This may
+ for example include closing doors.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationUnLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject:int="", ProjectFileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The recipe is a zipped archive that includes all project data. This command
+ tells the device to load the recipe.
+ API Status: internal
+ Args:
+ ForceReOpenProject:int = 0
+ ProjectFileName:str = ""
+ Command Timeout: 60000
+ Example:ProcessStationLoadRecipe 1 SampleProject.spp
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Requests that the device verify that the recipe given can be executed on the
+ device. It should check that the recipe is correctly formed and conforms to the
+ hardware of the device. It should not check for transient things such as whether
+ there is sufficient media or facilities available. those kinds of checks should
+ be done in PrepareForProcess
+ API Status: internal
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 60000
+ Example:ProcessStationVerifyRecipe SampleProject.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+ global ProcessStationVerifyRecipe_Response
+ if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+ return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob:int="", TotalWafersInJob:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells VeloxPro to start the current recipe. The station will switch to error if
+ an error occurs. If VeloxPro recipe execution is currently paused, this command
+ tells the system to continue execution.
+ API Status: internal
+ Args:
+ CurrentWaferInJob:int = -1
+ TotalWafersInJob:int = -1
+ Command Timeout: 25000
+ Example:ProcessStationStartRecipe 1
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the device to stop the current recipe. The station will switch to error if
+ an error occurs.
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationStopRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the module to do whatever is necessary to recover from an error condition.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationRecoverError
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get substrate information from process station controller application.
+ API Status: internal
+ Returns:
+ Result:str
+ PercentDone:Decimal
+ AllowSkipWafer:int
+ TestInformation:str
+ Command Timeout: 25000
+ Example:ProcessStationGetWaferResult
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+ global ProcessStationGetWaferResult_Response
+ if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+ return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+ """
+ Returns information about the wafer that is currently on the probe station. It
+ will return an error when there is no wafer currently on the chuck.
+ API Status: published
+ Returns:
+ Size:int
+ Angle:Decimal
+ ID:str
+ LotID:str
+ ProductID:str
+ Command Timeout: 25000
+ Example:QueryWaferInfo
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+ global QueryWaferInfo_Response
+ if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+ return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the process station to PAUSE mode
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationPauseRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+ """
+ Retrieves the current status of the prober. If probing status is AtFirstDie the
+ tester can take control.
+ API Status: published
+ Returns:
+ Status:str
+ Command Timeout: 25000
+ Example:GetProbingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+ """
+ Tells the prober to proceed the recipe when current status is AtFirstDie.
+ API Status: published
+ Command Timeout: 25000
+ Example:ProceedProbing
+ """
+ MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette:int=""):
+ """
+ Provides all available wafer information. It returns a set of data for each
+ wafer in either cassette. The data contains the cassette and the slot number
+ where the wafer is located, the status of the wafer, and identification
+ information.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 25000
+ Example:GetCassetteStatus 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module:str="", Slot:int=""):
+ """
+ Queries the wafer ID of a given module and slot.
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryWaferID Cassette1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module:str="", Slot:int="", ID:str=""):
+ """
+ Overrides the wafer ID of the given module and slot. If the wafer id is empty
+ and the module is a Loadport, the id will be read by the idreader if possible.
+ This process behaves as follows: - the current wafer id is reset - if the read-
+ wafer-process would be delayed (e.g. there is already a wafer on the idreader)
+ the process will be aborted and an error will be returned - if the id-
+ reading fails, the process behaves like a normal inventory triggered by the UI:
+ skip (returns success), abort (returns error) or "ask user". It is
+ recomended to use either skip or abort for remote id reading. If the
+ module is a Loadport and the slot is set to -1, a regular inventory will be
+ triggered. This behaves similar to an inventory triggered by the UI: The ID
+ won't be reset and already scanned wafers won't be reset. Setting an ID
+ explicitly with slot -1 is an error: - Okay, read id of wafer in slot 3 even if
+ it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+ to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+ UpdateWaferID Cassette1 -1 - Error: UpdateWaferID Cassette1 -1 XYZ123
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ ID:str = ""
+ Command Timeout: 1500000
+ Example:UpdateWaferID Cassette1 1 Wafer01
+ """
+ MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName:str=""):
+ """
+ Queries whether the given project/flow name is a valid project/flow at the probe
+ station. Using file and folder names without white spaces is recommended. For
+ folders and files whith white spaces use quotation marks for the path. Example
+ for using white spaces: ConfirmRecipe
+ "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+ API Status: published
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 25000
+ Example:ConfirmRecipe C:/Temp/Test.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+ global ConfirmRecipe_Response
+ if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+ return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName:str="", WaferIDs:str=""):
+ """
+ Creates and starts a new job by specifying the flow/spp file and the wafers to
+ be included in the job.
+ API Status: published
+ Args:
+ RecipeName:str = ""
+ WaferIDs:str = ""
+ Returns:
+ JobID:str
+ Command Timeout: 25000
+ Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID:str=""):
+ """
+ Get job information for a specific job ID including the flow file and the list
+ of wafers.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ RecipeName:str
+ WaferIDs:str
+ Command Timeout: 25000
+ Example:GetJobParams 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+ global GetJobParams_Response
+ if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+ return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID:str=""):
+ """
+ Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+ an error string is returned.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ Status:str
+ JobStatusInfo:str
+ Command Timeout: 25000
+ Example:JobStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+ global JobStatus_Response
+ if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+ return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID:str="", Unload:int=""):
+ """
+ Aborts the job given by the job ID. The status of the job will be set to
+ "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+ or not.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Unload:int = 0
+ Command Timeout: 25000
+ Example:AbortJob 2 1
+ """
+ MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the VeloxPro application.
+ API Status: internal
+ Args:
+ NoUserPrompt:int = 0
+ Command Timeout: 25000
+ Example:ProcessStationCloseApplication
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+ """
+ Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+ free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+ API Status: published
+ Command Timeout: 600000
+ Example:UnloadWafer
+ """
+ MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType:str=""):
+ """
+ Returns a string for the relevant JobIDs.
+ API Status: published
+ Args:
+ JobType:str = "Probing"
+ Returns:
+ GetJobList:str
+ Command Timeout: 25000
+ Example:GetJobList
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob:str=""):
+ """
+ Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+ determines how the job continues.
+ API Status: published
+ Args:
+ ProceedJob:str = "AbortJob"
+ Command Timeout: 25000
+ Example:ProceedJob AbortJob
+ """
+ MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette:int=""):
+ """
+ Returns the ID of a cassette that is placed on the load port. The loadport and
+ the cassette must support RFID reading (additional hardware needed).
+ API Status: published
+ Args:
+ Cassette:int = 1
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryCassetteID 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId:int="", DockUndock:int=""):
+ """
+ Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+ return an error if no cassette is placed: the LoadPort is not ready/available or
+ the docking failed. The command will do the docking/undocking and return when
+ this is done.
+ API Status: published
+ Args:
+ LoadPortId:int = 0
+ DockUndock:int = 0
+ Command Timeout: 60000
+ Example:DockCassette 1 1
+ """
+ MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID:int="", SlotID:int="", AlignmentAngle:Decimal=""):
+ """
+ Load a wafer from a given loadport onto the prober. If no slot id is defined,
+ the first available wafer with the lowest slot id will be loaded. If no loadport
+ is defined, it will try to use the first loadport. If there is no suitable
+ wafer, it will try the second. Returns an error if the loading process fails or
+ no suitable wafer is found. To define an alignment angle and still use the
+ "autoselect" behaviour, use -1 for loadport and slot.
+ API Status: published
+ Args:
+ LoadportID:int = -1
+ SlotID:int = -1
+ AlignmentAngle:Decimal = 0
+ Command Timeout: 600000
+ Example:LoadWafer 1 1
+ """
+ MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette:int=""):
+ """
+ Updates the cassette status with a simple scan.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 1200000
+ Example:UpdateCassetteStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation:str="", SourceSlot:int="", DestinationLocation:str="", DestinationSlot:int=""):
+ """
+ Transport a wafer from one location to another. This command behaves like the
+ wafer-transport inside the LoaderModule. The Slot must always be set.
+ API Status: published
+ Args:
+ SourceLocation:str = "Cassette1"
+ SourceSlot:int = 1
+ DestinationLocation:str = "Cassette1"
+ DestinationSlot:int = 1
+ Command Timeout: 600000
+ Example:TransportWafer Cassette1 1 PreAligner 1
+ """
+ MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module:str="", ProcessParam:str=""):
+ """
+ "Process" a wafer on a given location. What is done depends on the current
+ station: - IDReader: read ID - PreAligner: align wafer (alignment angle
+ mandatory) - Prober: Perform current recipe
+ API Status: published
+ Args:
+ Module:str = "Cassette1"
+ ProcessParam:str = ""
+ Command Timeout: 100000
+ Example:ProcessWafer PreAligner 90.0
+ """
+ MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the IDReader
+ API Status: internal
+ Returns:
+ IDReaderPos:str
+ Command Timeout: 2000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the current position of the IDReader
+ API Status: internal
+ Args:
+ IDReaderPos:str = "Bottom"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process:str=""):
+ """
+ CryoCommand controls automatic cooling and warm up.
+ API Status: published
+ Args:
+ Process:str = "CD"
+ Command Timeout: 60000
+ Example:CryoCommand CD
+ """
+ MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage:str=""):
+ """
+ Reads the current temperature from sensor chuck or shield.
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Returns:
+ Temp:Decimal
+ Command Timeout: 10000
+ Example:CryoReadTemperature C
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+ return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage:str="", Temp:Decimal=""):
+ """
+ Sets temperature value for TIC chuck or shield. (Only available in process state
+ 'Idle' or 'Cold'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Temp:Decimal = 320
+ Command Timeout: 10000
+ Example:CryoSetTemperature C 70.5
+ """
+ MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage:str=""):
+ """
+ Enables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStartRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage:str=""):
+ """
+ Disables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStopRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+ """
+ Reads current state.
+ API Status: published
+ Returns:
+ State:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+ """
+ Moves the black body to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition:int=""):
+ """
+ Moves the black body to working position.
+ API Status: published
+ Args:
+ NbrPosition:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveBBWork 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position:str="", Shutter:int=""):
+ """
+ Moves one of the two shutters.
+ API Status: published
+ Args:
+ Position:str = "C"
+ Shutter:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveShutter F 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+ """
+ Moves the microscope to working position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+ """
+ Moves the microscope to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+ """
+ Reads the current pressure of the vacuum chamber.
+ API Status: published
+ Returns:
+ Pressure:Decimal
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+ return Decimal(rsp[0])
+
+def MoveZCombined(Height:Decimal="", Percent:Decimal="", Async:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move both Chuck and Scope to a new absolute z-Height. The position must be
+ within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+ maximum velocity for now
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ Percent:Decimal = 0
+ Async:int = 0
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+ """
+ Get the state of the software stop.
+ API Status: published
+ Returns:
+ StopState:int
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+ return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status:str="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Used to set the system either in off, on, error or locked state. For lock, a
+ key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+ SetStatus without message means enable/ recover from error, with message it
+ means unlock. If the system wasn't enabled or in error state before an unlock,
+ it will remain in this state after the unlock.
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+ """
+ Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+ should be the same as the currently active ScopeSilo
+ API Status: published
+ Returns:
+ ScopeWorkingStage:int
+ Command Timeout: 5000
+ Example:GetScopeWorkingStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+ return int(rsp[0])
+
+def SetPerformanceMode(Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the performance mode in use by remote command. If this feature is not
+ supported and the mode is anything but Standard, an error is returned.
+ API Status: internal
+ Args:
+ Mode:str = "Standard"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage:int=""):
+ """
+ Move to the target working stage
+ API Status: published
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 30000
+ Example:SetScopeWorkingStage 1
+ """
+ MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured performance mode. If this feature is not supported
+ on a station, Standard will be returned
+ API Status: internal
+ Returns:
+ Mode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the current status of the combined-z-move-system
+ API Status: internal
+ Returns:
+ Status:str
+ PlatenSafe:int
+ Height:Decimal
+ HeightMax:Decimal
+ HeightRelative:Decimal
+ SafeHeight:Decimal
+ Message:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+ global MoveZCombinedGetStatus_Response
+ if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+ return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable:int="", Path:str=""):
+ """
+ Load a previously saved Scope-Fence-configuration or remove the current
+ configuration
+ API Status: published
+ Args:
+ Enable:int = 0
+ Path:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState:int=""):
+ """
+ Set the state of the software stop.
+ API Status: published
+ Args:
+ StopState:int = 0
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
+def trace(frame, event, arg):
+ print("%s, %s:%d" % (event, frame.f_code.co_filename, frame.f_lineno))
+ return trace
+
+
+class MessageServerInterface(object):
+ # For storing things
+ current_die = 1
+ current_die_coords = [0, 0]
+
+ chuck_home = [0, 0]
+ current_chuck_position = {'x': 0, 'y': 0, 'z': 0}
+ map_home = [0, 0]
+
+ contact_height = -10
+ # constants
+ dies = {
+ "1": [-6,4],
+ "2": [-5,4],
+ "3": [-4,4],
+ "4": [-3,4],
+ "5": [-2,4],
+ "6": [-8,3],
+ "7": [-7,3],
+ "8": [-6,3],
+ "9": [-5,3],
+ "10": [-4,3],
+ "11": [-3,3],
+ "12": [-2,3],
+ "13": [-1,3],
+ "14": [-9,2],
+ "15": [-8,2],
+ "16": [-7,2],
+ "17": [-6,2],
+ "18": [-5,2],
+ "19": [-4,2],
+ "20": [-3,2],
+ "21": [-2,2],
+ "22": [-1,2],
+ "23": [0,2],
+ "24": [-9,1],
+ "25": [-8,1],
+ "26": [-7,1],
+ "27": [-6,1],
+ "28": [-5,1],
+ "29": [-2,1],
+ "30": [-3,1],
+ "31": [-2,1],
+ "32": [-1,1],
+ "33": [0,1],
+ "34": [-9,0],
+ "35": [-8,0],
+ "36": [-7,0],
+ "37": [-6,0],
+ "38": [-5,0],
+ "39": [-4,0],
+ "40": [-3,0],
+ "41": [-2,0],
+ "42": [-1,0],
+ "43": [0,0],
+ "44": [-9,-1],
+ "45": [-8,-1],
+ "46": [-7,-1],
+ "47": [-6,-1],
+ "48": [-5,-1]
+ }
+
+ def __init__(self):
+ print ("MessageServerInterface: initializing")
+
+ def __enter__(self):
+ #-uc-# print ("MessageServerInterface: entering")
+ return self
+
+ def __exit__(self, *args, **kwargs):
+ print ("MessageServerInterface: closed %s %s %s" % (args, kwargs, self))
+
+ @staticmethod
+ def generate_powermeter_values(weights=[10, 10, 20, 10, 35]):
+
+ power = [0, 0]
+ for i in [0, 1]:# generate a random values between -75 and -22 dBm
+ power_75_70 = round(random.randint(-75, -70) + random.random(), 4)
+ power_70_65 = round(random.randint(-70, -65) + random.random(), 4)
+ power_65_55 = round(random.randint(-65, -60) + random.random(), 4)
+ power_30_25 = round(random.randint(-30, -25) + random.random(), 4)
+ power_25_20 = round(random.randint(-25, -20) + random.random(), 4)
+ # Choose randomly between the values, but weighted
+ data_list = [power_75_70] * weights[0] + [power_70_65] * weights[1] + [power_65_55] * weights[2] + [power_30_25] * weights[3] + [power_25_20] * weights[4]
+ power[i] = random.choice(data_list)
+
+ return power[0], power[1]
+
+ @staticmethod
+ def sendSciCommand(*args, **kwargs):
+
+ try:
+ #-uc-# print (">> [SENDING SCI COMMAND static] args: %s, kwargs: %s" % (args, kwargs))
+ if len(kwargs) > 0:
+ args_split = str(kwargs['rparams']).split()
+ func = getattr(MessageServerInterface, args[0])
+ return func(*args_split)
+ else:
+ func = getattr(MessageServerInterface, args[0])
+ return func(*args[1:])
+ except Exception as e:
+ print(">> [SENDING SCI COMMAND static] Exception: %s" % e)
+ return None
+
+ @staticmethod
+ def MoveOpticalProbe(probe, x, y, PosRef = "C"):
+ ''' Move selected probe motor in XY.
+ Input Parameter
+ probe 0=Input, 1=Output (I)
+ x motor command [um] (D)
+ y motor command [um] (D)
+ PosRef R=Relative, H=Home, Z=Zero (C)
+ Output Parameter
+ x motor position [um] (D)
+ y motor position [um] (D)
+ z motor position [um] (D)
+ '''
+ #-uc-# print (" |-> [MoveOpticalProbe] probe: %s x: %s y: %s PosRef: %s: " % (probe, x, y, PosRef))
+ z = 500
+ return x, y, z
+
+ @staticmethod
+ def SetOpticalProbeHome(probe):
+ z = 500
+ return 0, 0, 0, 1, 1, 1
+
+
+ @staticmethod
+ def ReadOpticalProbePowerMeter(channel):
+ '''Read computed power level from probe control.
+
+ API Status:
+ dummy testing
+ Parameters:
+ channel: (Optional) analog input channel (I)
+ Returns:
+ power: calibrated power meter value [dBm] (D)
+ '''
+ #-uc-# print (" |-> [ReadOpticalProbePowerMeter] channel: %s" % (channel))
+ # return a value between -75 and -22 dBm
+
+ # generate a random values between -75 and -22 dBm
+ power, _ = MessageServerInterface.generate_powermeter_values()
+ return power
+
+ @staticmethod
+ def FindOpticalProbeHeight(probe, height, tracking_on=False):
+ '''Find motor and PZT positions to set desired fiber height above wafer.
+
+ Parameters:
+ probe: 0=Input, 1=Output (I)
+ height: Fiber height [um] (D)
+ tracking on: (Optional) Enable fly height control (B)
+ Returns:
+ height: fiber height [um] (D)
+ Z sensor: Z sensor value (D)
+ motorZ: motor Z position [um] (D)
+ PZTZ: PZT Z position [um] (D)
+ '''
+ #-uc-# print (" |-> [FindOpticalProbeHeight] channel: probe %s, height %s, tracking_on %s" % (probe, height, tracking_on))
+ # Add a small delay, to simulate a real measurement up to 1 sec
+ time.sleep(random.random())
+ return height, 0, 0, 0
+
+ @staticmethod
+ def RecenterOpticalProbe(probe):
+ '''Recenter XYZ motor position by the distance PZT is off center and recenter PZT
+
+ Parameters:
+ probe: 0=Input, 1=Output (I)
+ '''
+ #-uc-# print (" |-> [RecenterOpticalProbe] probe: %s +" % (probe))
+ # Add a small delay, to simulate a real measurement up to 0,25 sec
+ time.sleep(random.random()*0.25)
+
+ @staticmethod
+ def AreaScan(input, output, filename = None):
+ '''Perform Area ScanPerform.
+ Parameters:
+ Input: Input scan enabled (B)
+ Output: Output scan enabled (B)
+ Filename: (Optional) Data file name (S)
+ Returns:
+ x: x Input PZT position [um] (D)
+ y: y Input PZT position [um] (D)
+ x: x Output PZT position [um] (D)
+ y: y Output PZT position [um] (D)
+ InputPower: Input scan power [dBm] (D)
+ OutputPower: Output scan power [dBm] (D)
+ '''
+ #-uc-# print (" |-> [AreaScan] input %s, output %s, filename %s" % (input, output, filename))
+ # Add a small delay, to simulate a real measurement up to 4 sec
+ #time.sleep(3)
+ #time.sleep(random.random())
+ power_in, power_out = MessageServerInterface.generate_powermeter_values(weights=[30, 0, 0, 20, 50])
+ #power_in, power_out = MessageServerInterface.generate_powermeter_values(weights=[0, 0, 0, 0, 100])
+
+ return 0, 0, 0, 0, power_in, power_out
+
+ @staticmethod
+ def ReadOpticalProbePos(probe, posRef = "C"):
+ '''Read optical probe position.
+
+ Parameters:
+ probe: 0=Input, 1=Output (I)
+ PosRef: H=Home, Z=Zero (C)
+ Returns:
+ x: x motor position [um] (D)
+ y: y motor position [um] (D)
+ z: z motor position [um] (D)
+ x: x PZT position [um] (D)
+ y: y PZT position [um] (D)
+ z: z PZT position [um] (D)
+ '''
+ #-uc-# print (" |-> [ReadOpticalProbePos] probe: %s %s" % (probe, posRef))
+ # Add a small delay, to simulate a real measurement up to 1 sec
+ time.sleep(random.random())
+ return 0, 0, 0, 0, 0, 0
+
+ @staticmethod
+ def EchoData(string):
+ '''
+ Args:
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp: str
+ '''
+ #-uc-# print (" |-> [EchoData] string: %s" % (string))
+ return string
+
+ @staticmethod
+ def ReportKernelVersion(module):
+ #-uc-# print (" |-> [ReportKernelVersion] module: %s" % (module))
+ return "1.0 Velox Simulator "
+
+ @staticmethod
+ def TrackOpticalProbeHeight(probe, enable):
+ '''Track current fiber height.
+ Parameters:
+ probe: 0=Input, 1=Output (I)
+ enable: enable fly height control (B)
+ '''
+ #-uc-# print (" |-> [TrackOpticalProbeHeight] probe: %s enable: %s" % (probe, enable))
+ # Add a small delay, to simulate a real measurement up to 1 sec
+ time.sleep(random.random())
+
+ @staticmethod
+ def StepToDie(die_number:int="", site:int=""):
+ """
+ Steps the chuck to the die location specified by the die number of the wafer
+ map. If no command data is passed, the chuck automatically steps to the next
+ logical wafer map die location. Returns the row and column number of the actual
+ die location after the move is completed. In addition, the SubDie location, and
+ total number of SubDies is also returned.
+ API Status: published
+ Args:
+ die_number:int = -1
+ site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+
+
+ #-uc-# print (" |-> [StepToDie] die_number: %s, site:%s" % (die_number, site))
+ # Step to this die
+ MessageServerInterface.current_die = die_number
+ # Set the coordinates accordingly
+ MessageServerInterface.current_die_coords = [MessageServerInterface.dies[str(die_number)][0], MessageServerInterface.dies[str(die_number)][1]]
+ # Add a small delay, to simulate a real measurement up to 1 sec
+ time.sleep(random.random())
+ return MessageServerInterface.current_die_coords[0], MessageServerInterface.current_die_coords[1], 0, 0
+
+ @staticmethod
+ def GetDieDataAsColRow(c_die_x="", c_die_y=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Column and Row are absent it uses the
+ current die on the wafer.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ #-uc-# print (" |-> [GetDieDataAsColRow] c_die_x: %s, c_die_y:%s" % (c_die_x, c_die_y))
+ if c_die_x == "" and c_die_y == "":
+ return MessageServerInterface.current_die, MessageServerInterface.current_die_coords[0], MessageServerInterface.current_die_coords[1], 0, "OK"
+
+ for die in MessageServerInterface.dies:
+ if MessageServerInterface.dies[die][0] == c_die_x and MessageServerInterface.dies[die][1] == c_die_y:
+ return int(die), MessageServerInterface.dies[die][0], MessageServerInterface.dies[die][1], 0, "OK"
+
+ @staticmethod
+ def SetChuckHome(mode="0", unit="Microns", x_value="0", y_value="0"):
+ """
+ Sets wafer and die home position, which can be used later as coordinate system
+ for movements.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHome 0 Y
+ """
+ #-uc-# print (" |-> [SetChuckHome] mode %s, unit %s, x_value %s, y_value %s" % (mode, unit, x_value, y_value))
+ MessageServerInterface.current_cuck_position = {'x': 0, 'y': 0, 'z': -500}
+ if mode == 0:
+ MessageServerInterface.chuck_home = []
+
+ @staticmethod
+ def SetMapHome(die_x = "", die_y = ""):
+ """
+ If the command has no parameters it sets the current position as home position
+ both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+ home position using the given die coordinates.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.map_home = [die_x, die_y]
+ #-uc-# print (" |-> [SetMapHome] die_x %s, die_y %s" % (die_x, die_y))
+
+ def ReadChuckPosition(Unit="Microns", PosRef="Home", Comp="Default"):
+ """
+ Returns the current chuck stage position in X, Y and Z.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckPosition Y Z
+ """
+ #-uc-# print (" |-> [ReadChuckPosition] unit %s, pos_ref %s, comp %s" % (Unit, PosRef, Comp))
+ return (
+ MessageServerInterface.current_chuck_position['x'],
+ MessageServerInterface.current_chuck_position['y'],
+ MessageServerInterface.current_chuck_position['z']
+ )
+
+ @staticmethod
+ def ReadChuckHeights(Unit=""):
+ """
+ Returns the current settings used for the chuck Z movement. `Contact` is the
+ contact-height from zero in default compensation. The other heights are relative
+ to this. If no contact is set, the value will be -1.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ SearchGap:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckHeights Y
+ """
+ print(" |-> [ReadChuckHeights] unit %s" % (Unit))
+ #print(" |-> [ReadChuckHeights] unit")
+ #print(" |<- [ReadChuckHeights] return %" % (res))
+ return -20, 0, 0, 0, 0
+
+ @staticmethod
+ def MoveChuck(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+ height or higher, Interlock and Auto Z flags will be analyzed and stage will
+ behave correspondingly - can move to separation first or return an error:
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MoveChuck 5000. 5000. R Y 100
+ """
+ #-uc-# print (" |-> [MoveChuck] XValue %s, YValue %s, PosRef %s, Unit %s, Velocity %s, Comp %s" % (XValue, YValue, PosRef, Unit, Velocity, Comp))
+ MessageServerInterface.current_chuck_position = {'x': XValue, 'y': YValue, 'z': MessageServerInterface.contact_height}
+
+ @staticmethod
+ def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+ """
+ Saves the currently displayed image to the specified file. The image is stored
+ in the requested file format (bmp, jpg or png). By default. it will save the raw
+ camera image and an image with the overlays that are currently visible on the
+ camera view. Using a parameter, one can decide to only save either raw image,
+ overlay image or both. By Specifying 'ALL' as the mount position, the captured
+ screenshot will consist of the currently selected camera layout without
+ providing the raw image. If MountPos and FullPath are empty then the current
+ camera view with overlays is copied to the clipboard.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ FullPath:str = "Image.bmp"
+ SnapShotMode:int = 2
+ Command Timeout: 60000
+ Example:SnapImage Scope C:/Temp/Image.bmp
+ """
+ #-uc-# print (" |-> [SnapImage] MountPos: %s, FullPath %s, SnapShotMode%s" % (MountPos, FullPath, SnapShotMode))
diff --git a/src/FlexSensor/Prober/velox_api/velox/__init__.py b/src/FlexSensor/Prober/velox_api/velox/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..82d8e1f77fd39d9732964623ec949c196623afbb
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/__init__.py
@@ -0,0 +1,9 @@
+
+"""Determines the version of the sci module to import"""
+from sys import version_info
+from Prober.velox_api.velox.vxmessageserver import *
+
+if (version_info[0] > 2 and version_info[1] >= 5):
+ from Prober.velox_api.velox.sci35 import *
+else:
+ from Prober.velox_api.velox.sci27 import *
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py b/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4eb99eecf0d2ef248dc343843e894763e5d7763
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py
@@ -0,0 +1,10 @@
+# Demonstrate simple synchronous commands
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+ response = velox.IsAppRegistered('Kernel')
+ if response < 0 :
+ print('Could not register application.')
+
+ x,y,z = velox.ReadChuckPosition("Microns")
+ print(x,y,z)
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py b/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py
new file mode 100644
index 0000000000000000000000000000000000000000..674e47292f2f15491642df41f481c57b63ae79ff
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py
@@ -0,0 +1,3 @@
+# Asyncronous commands require the user to implement async Python routines
+# There is no special support for asynchronous commands biult in to the
+# velox Python libraries.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py b/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py
new file mode 100644
index 0000000000000000000000000000000000000000..537df71bfad7233afc12b42c198197b14fb8dc3e
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py
@@ -0,0 +1,4 @@
+# There is no support for SCI Notifications in the velox Python
+# library. If notification handling is required, consider the
+# C, C++, or C# libraires of the Velox Integration Toolkit.
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py b/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py
new file mode 100644
index 0000000000000000000000000000000000000000..0a612fe5229cea34af9e68e1bc67ddb357933357
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py
@@ -0,0 +1,26 @@
+# Demonstrate Custom User Commands
+#
+# Custom commands are commands added to the commands.user.txt file.
+# See the Velox Integration Toolkit documentation for details
+#
+# Because custom user commands are not part of the velox Python library,
+# use the generic sendSciCommand of the MessageServer class to send the command.
+#
+# The code below shows two ways to call sendSciCommand: one using the msgServer
+# object from the 'with' statement on the second line of code, and one using the
+# full path velox.MessageServerInterface.sendSciCommand()
+#
+# The parameters are a string containing the name of the command and a string
+# containing any arguemnts that should be sent to the command.
+#
+# rsp = msgServer.sendSciCommand('commandName', 'arguments separated by spaces')
+#
+# The example blow does not use a custom command, but demonstrates calling the
+# echodata test commmd to demonstrate the use os sendSciCommand
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+ rsp = msgServer.sendSciCommand('EchoData', 'Hello')
+ print(rsp)
+ rsp = velox.MessageServerInterface.sendSciCommand('echodata', 'World')
+ print(rsp)
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py b/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py
new file mode 100644
index 0000000000000000000000000000000000000000..794e07a013322ea6b8d15f72fc33efffb719d8b9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py
@@ -0,0 +1,38 @@
+# Demonstrate Die Stepping in WaferMap
+
+import velox
+
+def perform_measurement(die):
+ if die.CurSite > 0:
+ print(f'Measure at die <{die[0], die[1]}> subdie {die.CurSite} of {die.LastSiteIndex}')
+ else:
+ print(f'Measure at die <{die[0], die[1]}>')
+
+with velox.MessageServerInterface() as msgServer:
+ try:
+ rsp = velox.IsAppRegistered('Kernel')
+ print('IsAppRegistered Kernel: %s' % rsp)
+
+
+ rsp = velox.StepFirstDie()
+ perform_measurement(rsp)
+
+ while(True):
+ rsp = velox.StepNextDie()
+ perform_measurement(rsp)
+
+ x,y,z = velox.ReadChuckPosition('Y','H', 'D')
+ print('The Chuck is at <%s,%s,%s>'% (x, y, z))
+
+ except velox.SciException as e:
+ if (e.code == '703'):
+ print('Die Stepping Completed')
+ elif e.code == '512':
+ print('There was an error. The error code was %s.' % e.code)
+ print('This may mean that the WaferMAp application is not running.')
+ print('Make sure that the WaferMap application is running and try again.')
+ print(e)
+ else:
+ print('We caught an exception with error code %s as:' % e.code)
+ print(e)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py b/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..03448e3546a50092e476414243278b3be17ef625
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py
@@ -0,0 +1,3 @@
+# The velox Python library does not support incomming SCI
+# Commands at this time. To implement incomming command functionality,
+# see the examples for C++ and C# in the Vlox Integration Toolkit.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py b/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c45e935dbe8161e0ba4c068c5eaddf0e05758e4
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py
@@ -0,0 +1 @@
+# There is no specific Python example for Tester Control
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py b/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..537c80d6897058660138fd5f8b0cc38e4837e061
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py
@@ -0,0 +1,3 @@
+# User interface applications in Python often use TKinter
+# or some other GUI framework. Users should see Python UI
+# Dccumentstion for examples.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py b/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..2cfe247894d61359ff5edd41c76e614f95af714c
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py
@@ -0,0 +1,88 @@
+# import velox will choose the correct version of the library
+# based on the version of Python being executed
+import velox
+import inspect
+
+# import sys for this example, but it is not required for VPI
+import sys
+
+
+
+# print the version of Python that is running, just to see that it is working
+print('Using Python Version ' + sys.version)
+
+# Connect to the message server using a 'with' statement.
+# The application name registered with the Velox Message Server
+# will be the name of our script. Keep a reference to
+# the object returned by velox.MessageServerInterface
+# - in this example, we call it msgServer
+
+# the parameters to MessageServerInterface are optional.
+# For a local connection, you can leave them blank. If
+# connecting to a remote machine, add keyword parameters and set the
+# address and socket
+# velox.MessageServerInterface(ipaddr='localhost',targetSocket=1412)
+
+with velox.MessageServerInterface() as msgServer:
+ # as long as the connection was successful, we can send some commands.
+ # if it was not successful, an exception is thrown.
+
+
+ # try some SCI Command Examples
+
+ # The SCI commands in the velox module have docstrings to describe
+ # their function, inputs, and outputs.
+ # You can print them from a Python command to see what the function does.
+
+ # print the docstring for the ReportKernelVersion command
+ # ReportKernelVersion returns 2 values.
+ # here is the description of the command
+
+ print(velox.ReportKernelVersion.__doc__)
+
+ # SCI commands return a namedtuple if multiple values are returned.
+ # ReportKernelVersion returns a version number and a description.
+ # You can acess the return values by name or by indexing the tuple.
+
+ v = velox.ReportKernelVersion()
+ print('The kernel version is', v.Version, 'and', v.Description)
+ print('The kernel version array is', v[0], 'and', v[1])
+
+ # a more convenient example is to unpack the tuple into variables
+ # as part of the function call.
+ # here we get variables named ver and desc and use them directly
+ ver, desc = velox.ReportKernelVersion()
+ print('Got ', ver, 'and', desc)
+
+ # The Echo Data command just returns its own first input.
+ # Echo data only returns the first string in the parameter list.
+ # To get a string with spaces to display, we need to add double quotes.
+ # Try it both ways to see the difference. The first one below does
+ # what we expect. The second only prints the first word.
+ # The third assigns a return value to a variable
+
+ print(velox.EchoData('"Hi World1"'))
+
+ print(velox.EchoData("AreaScan(1,1)"))
+
+ print(velox.EchoData("Hi World2"))
+ evalue = velox.EchoData("Echo_This")
+
+ # ReadChuckPosition returns 3 values. Here we print the entire tuple
+ # to show the tuple name and the names of the 3 return values
+ print(velox.ReadChuckPosition("Microns"))
+
+
+
+ #velox.MoveChuck(-2000,-2000,"Relative")
+
+ # it is possible to send raw command strings with the
+ # sendSciCommand function.
+ # it isn't recommended, but in some cases, it might be necessary.
+ # it is much easier and 'safer' to use the defined SCI functions.
+ # note that this is a function of MessageServerInterface,
+ # not a velox module function
+
+ print(msgServer.sendSciCommand("echodata", rparams='"RawHello Velox"'))
+
+ print(msgServer.sendSciCommand("SearchFirstLight",rparams='1 0'))
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/__init__.py b/src/FlexSensor/Prober/velox_api/velox/samples/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz b/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..3d40814fd761e46f15751cca86ef1edfe1e9ebb7
Binary files /dev/null and b/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz differ
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..a518b179b579b94a68caad65035c0b49092f8bb9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py
@@ -0,0 +1,12 @@
+import velox
+
+with velox.MessageServerInterface() as msgServer:
+
+ # FindFocus will throw an exception because we aren't properly set up yet.
+ # This is to demonstrate exception handling.
+ try:
+ print(velox.FindFocus())
+ except velox.SciException as e:
+ print('We caught an exception as expected:')
+ print(e)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..e7f242892e9e154b7ae8364a6f680d5867b159a4
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py
@@ -0,0 +1,9 @@
+import velox
+
+with velox.MessageServerInterface() as msgServer:
+
+ ver, desc = velox.ReportKernelVersion()
+ print('Got ', ver, 'and', desc)
+ x,y,z = velox.ReadChuckPosition("Inches")
+ print(x,y,z)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0f1bc9227cad4600659da5d8e511846e8698b1e
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py
@@ -0,0 +1,85 @@
+# import velox will choose the correct version of the library
+# based on the version of Python being executed
+import velox
+
+# import sys for this example, but it is not required for VPI
+import sys
+
+# print the version of Python that is running, just to see that it is working
+print('Using Python Version ' + sys.version)
+
+# Connect to the message server using a 'with' statement.
+# The application name registered with the Velox Message Server
+# will be the name of our script. Keep a reference to
+# the object returned by velox.MessageServerInterface
+# - in this example, we call it msgServer
+
+# the parameters to MessageServerInterface are optional.
+# For a local connection, you can leave them blank. If
+# connecting to a remote machine, add keyword parameters and set the
+# address and socket
+# velox.MessageServerInterface(ipaddr='localhost',targetSocket=1412)
+
+with velox.MessageServerInterface() as msgServer:
+ # as long as the connection was successful, we can send some commands.
+ # if it was not successful, an exception is thrown.
+
+
+ # try some SCI Command Examples
+
+ # The SCI commands in the velox module have docstrings to describe
+ # their function, inputs, and outputs.
+ # You can print them from a Python command to see what the function does.
+
+ # print the docstring for the ReportKernelVersion command
+ # ReportKernelVersion returns 2 values.
+ # here is the description of the command
+
+ print(velox.ReportKernelVersion.__doc__)
+
+ # SCI commands return a namedtuple if multiple values are returned.
+ # ReportKernelVersion returns a version number and a description.
+ # You can acess the return values by name or by indexing the tuple.
+
+ v = velox.ReportKernelVersion()
+ print('The kernel version is', v.Version, 'and', v.Description)
+ print('The kernel version array is', v[0], 'and', v[1])
+
+ # a more convenient example is to unpack the tuple into variables
+ # as part of the function call.
+ # here we get variables named ver and desc and use them directly
+ ver, desc = velox.ReportKernelVersion()
+ print('Got ', ver, 'and', desc)
+
+ # The Echo Data command just returns its own first input.
+ # Echo data only returns the first string in the parameter list.
+ # To get a string with spaces to display, we need to add double quotes.
+ # Try it both ways to see the difference. The first one below does
+ # what we expect. The second only prints the first word.
+ # The third assigns a return value to a variable
+
+ print(velox.EchoData('"Hi World1"'))
+
+ print(velox.EchoData("AreaScan(1,1)"))
+
+ print(velox.EchoData("Hi World2"))
+ evalue = velox.EchoData("Echo_This")
+
+ # ReadChuckPosition returns 3 values. Here we print the entire tuple
+ # to show the tuple name and the names of the 3 return values
+ print(velox.ReadChuckPosition("Microns"))
+
+
+
+ velox.MoveChuck(-2000,-2000,"Relative")
+
+ # it is possible to send raw command strings with the
+ # sendSciCommand function.
+ # it isn't recommended, but in some cases, it might be necessary.
+ # it is much easier and 'safer' to use the defined SCI functions.
+ # note that this is a function of MessageServerInterface,
+ # not a velox module function
+
+ print(msgServer.sendSciCommand("echodata", rparams='"RawHello Velox"'))
+
+ print(msgServer.sendSciCommand("SearchFirstLight",rparams='1 0'))
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/velox/sci27.py b/src/FlexSensor/Prober/velox_api/velox/sci27.py
new file mode 100644
index 0000000000000000000000000000000000000000..16dac8e5d5e2643b8a8b4b1e6485bd4c06e97b6d
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/sci27.py
@@ -0,0 +1,11998 @@
+from velox.vxmessageserver import *
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite.
+The module was auto-generated from the commands.info.xml file on 2019-11-09.
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():'
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection.
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+ # Your Code: try some SCI Commands - such as:
+ response = velox.ReportKernelVersion()
+ print ('The kernel version is', response.Version, 'and', response.Description)
+
+"""
+def EchoData(TestCmd=""):
+ """
+ Test Command for the Kernel Communication. Like a ping command, the given text
+ string is returned unchanged.
+ API Status: published
+ Args:
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:EchoData Test
+ """
+ rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module=""):
+ """
+ Returns the version information of the kernel or the control box code. The
+ "Version" value contains version number and revision level of the actual Kernel
+ implementation. The text string contains a code description, version number and
+ the revision date.
+ API Status: published
+ Args:
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:ReportKernelVersion K
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+ global ReportKernelVersion_Response
+ if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+ return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+ """
+ Returns an actual status information of the prober.
+ API Status: published
+ Returns:
+ FlagsBusy:int
+ FlagsContact:int
+ Mode:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProberStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+ global ReadProberStatus_Response
+ if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+ return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn="", Stage=""):
+ """
+ Toggles the motor power for quiet probing. In most applications this feature is
+ not required. However, for special measurements it may be necessary to reduce
+ the noise of the system. Quiet on turns off the motor power for all stages (or
+ the one specified with the optional parameter). Quiet off will turn on the motor
+ power of all stages (or the one specified with the optional parameter) for
+ subsequent movements. A move command will also turn on the motor power of the
+ moved stage automatically. For automatical switching of the quiet mode refer to
+ Auto Quiet functionality. Sending 'EnableMotorQuiet 1' will enable the quiet
+ mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+ mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+ quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+ disable the quiet mode for the scope stage.
+ API Status: published
+ Args:
+ WantQuietModeOn:int = 0
+ Stage:str = "None"
+ Command Timeout: 10000
+ Example:EnableMotorQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn=""):
+ """
+ Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+ stations with wafer vacuum sensors in case no wafer was detected.
+ API Status: published
+ Args:
+ WantChuckVacuumOn:int = 0
+ Command Timeout: 10000
+ Example:SetChuckVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn=""):
+ """
+ Toggles the microscope light channel of the peripheral output board and all
+ cameras. Notifications: 7
+ API Status: published
+ Args:
+ WantIlluminatorOn:int = 2
+ Command Timeout: 5000
+ Example:SetMicroLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode="", PulseWidthRed="", PulseWidthGreen="", PulseWidthYellow="", PulseWidthBlue="", PulseWidthWhite=""):
+ """
+ This command controls the beacon channel of the peripheral output board. All
+ lights can be switched on, off, or blinking. Setting an interval to zero means,
+ that the corresponding light will be statically on or off. The minimum blinking
+ interval is 50ms.
+ API Status: published
+ Args:
+ FlagsMode:int = 0
+ PulseWidthRed:int = 1000
+ PulseWidthGreen:int = 0
+ PulseWidthYellow:int = 0
+ PulseWidthBlue:int = 0
+ PulseWidthWhite:int = 0
+ Command Timeout: 5000
+ Example:SetBeaconStatus 1 1000
+ """
+ MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel="", WantOutputOn="", PulseTime=""):
+ """
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: published
+ Args:
+ Channel:int = 1
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetOutput 4 0
+ """
+ MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+ """
+ Stops all Prober movements immediately. The response status value of any pending
+ movement will signify that the stop command was executed.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAllMovements
+ """
+ MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker="", PulseWidth=""):
+ """
+ Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+ For correct function, the inkers have to be linked to default outputs.
+ API Status: published
+ Args:
+ FlagsInker:int = 0
+ PulseWidth:int = 50
+ Command Timeout: 10000
+ Example:InkDevice 1 40
+ """
+ MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+ """
+ Returns the current positioner configuration. The output pattern is: 1. Type
+ Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+ Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+ 2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+ Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+ 11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+ API Status: published
+ Returns:
+ TypePositioner1:int
+ TypePositioner2:int
+ TypePositioner3:int
+ TypePositioner4:int
+ TypePositioner5:int
+ AxisPositioner1:int
+ AxisPositioner2:int
+ AxisPositioner3:int
+ AxisPositioner4:int
+ AxisPositioner5:int
+ TypePositioner6:int
+ AxisPositioner6:int
+ Command Timeout: 5000
+ Example:ReadProbeSetup
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+ global ReadProbeSetup_Response
+ if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+ return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+ """
+ Returns the system options which are currently enabled at the prober.
+ API Status: published
+ Returns:
+ Name:str
+ System:str
+ ChuckXY:int
+ ChuckZ:int
+ ChuckTheta:int
+ ScopeXY:int
+ ScopeZ:int
+ EdgeSensor:int
+ OperationalMode:str
+ Turret:int
+ TemperatureChuck:int
+ AuxSiteCount:int
+ PlatenXY:int
+ PlatenZ:int
+ LoaderGateState:str
+ NucleusType:str
+ Command Timeout: 10000
+ Example:ReadSystemStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+ global ReadSystemStatus_Response
+ if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+ return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode=""):
+ """
+ If 'R' is sent, it sets the external mode of the kernel. This disables most of
+ the control box functions (except the LOCAL function key). Otherwise, this
+ command re-enables all functions of the control box.
+ API Status: published
+ Args:
+ Mode:str = "L"
+ Command Timeout: 5000
+ Example:SetExternalMode L
+ """
+ MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage="", WantStageLock="", Application=""):
+ """
+ Enables or disables the stage lock functionality. Stages which are locked can't
+ be moved in any way. If the joystick controller is locked, the display and the
+ keys are deactivated. The name of the application can be stored by using the
+ Application Name parameter and is shown in lock-caused error messages.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ WantStageLock:int = 1
+ Application:str = ""
+ Command Timeout: 10000
+ Example:SetStageLock C 0 WaferMap
+ """
+ MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel="", Type=""):
+ """
+ Returns the actual status of the specified input channel, output channel or edge
+ sensor. The signal table is described in the Hardware Manual. Each used IO-board
+ has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+ channel numbers. Beyond this range there are pseudo channels, which are used for
+ special purposes. Pseudo channels:
+ API Status: published
+ Args:
+ Channel:int = 1
+ Type:str = "Input"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadSensor 11 I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+ return int(rsp[0])
+
+def GetStageLock(Stage=""):
+ """
+ Reads whether stages or joystick controller are locked.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ Returns:
+ Locks:int
+ Application:str
+ Command Timeout: 10000
+ Example:GetStageLock C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+ global GetStageLock_Response
+ if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+ return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets bottomside mode. In this mode the Z axis is reverse and the
+ command MoveChuckLoad is not allowed.
+ API Status: internal
+ Args:
+ WantBackSideMode:int = 0
+ Command Timeout: 5000
+ Example:SetBackSideMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+ """
+ Returns the current side mode.
+ API Status: published
+ Returns:
+ IsBackSideModeOn:int
+ Command Timeout: 5000
+ Example:GetBackSideMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+ return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode=""):
+ """
+ Switches off all LEDs on the Control Box, on the positioners, and on the screen
+ of the Control Box and also the light of the cameras.
+ API Status: published
+ Args:
+ WantSetDarkMode:int = 0
+ Command Timeout: 5000
+ Example:SetDarkMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+ """
+ Returns the current mode of the light sources.
+ API Status: published
+ Returns:
+ IsDarkMode:int
+ Command Timeout: 5000
+ Example:GetDarkMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+ return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Connect or disconnect the chuck camera to the chuck stage. The command is only
+ available for the Prober type PA300BEP.
+ API Status: internal
+ Args:
+ ConnectCamera:str = "ParkPos"
+ Velocity:Decimal = 100
+ Command Timeout: 300000
+ Example:DockChuckCamera P 75
+ """
+ MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current selected stage of the joystick controller.
+ API Status: internal
+ Returns:
+ Stage:str
+ Command Timeout: 5000
+ Example:ReadCBoxStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current stage of the joystick controller.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:SetCBoxStage C
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current setting of the joystick controllers position monitor for the
+ secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ PosRef:str
+ Unit:str
+ Command Timeout: 5000
+ Example:ReadCBoxPosMonConf C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+ global ReadCBoxPosMonConf_Response
+ if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+ return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage="", PosRef="", Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Configures the joystick controller position monitor for the secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetCBoxPosMonConf C Z Y
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CBoxSpeed:str
+ Command Timeout: 5000
+ Example:ReadCBoxCurrSpeed C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage="", CBoxSpeed=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CBoxSpeed:str = "Speed4"
+ Command Timeout: 5000
+ Example:SetCBoxCurrSpeed C 3
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck stage to the specified X,Y position without waiting for the move
+ to be finished If chuck Z is in contact height or higher, the chuck will drop to
+ separation.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveChuckAsync 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the scope stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveScopeAsync 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe="", XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the probe stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def ReadChuckStatus():
+ """
+ Returns the current chuck status. Every bit in the bit fields works like a
+ boolean value: One <1> means true/on and zero <0> means false/off.
+ Its counted from LSB to MSB. - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+ HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+ EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+ ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta All parameters
+ are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+ accessed by M_pbIsInitX).
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsVacuumOn:int
+ PresetHeight:str
+ LoadPos:str
+ IsLiftDown:int
+ CameraConnection:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+ global ReadChuckStatus_Response
+ if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+ return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit="", PosRef="", Comp=""):
+ """
+ Returns the current chuck stage position in X, Y and Z.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+ global ReadChuckPosition_Response
+ if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+ return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit=""):
+ """
+ Returns the current settings used for the chuck Z movement. `Contact` is the
+ contact-height from zero in default compensation. The other heights are relative
+ to this. If no contact is set, the value will be -1.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ SearchGap:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+ global ReadChuckHeights_Response
+ if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+ return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+ """
+ Machine Coordinate System: Chuck X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+ X, Y, Z, Theta All flags can be accessed by indirect members. Initializes the
+ chuck stage and resets current coordinate system. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 150000
+ Example:InitChuck 7 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+ height or higher, Interlock and Auto Z flags will be analyzed and stage will
+ behave correspondingly - can move to separation first or return an error:
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MoveChuck 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps="", YSteps="", PosRef="", Velocity=""):
+ """
+ Moves the chuck stage in index steps. This command modifies Die Home Position.
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue="", YValue="", Unit="", Velocity=""):
+ """
+ Moves the chuck stage to the specified X, Y sub-site position. Die home position
+ is defined by destination position of last successful MoveChuck or
+ MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+ you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+ back to die home position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckSubsite 200 200 Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity=""):
+ """
+ Performs a movement of chuck Z axis to preset contact height or will return
+ error if no contact height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckContact 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity=""):
+ """
+ Moves the chuck Z axis to the align height. If no Contact height is set will
+ return an error.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity=""):
+ """
+ Moves the chuck Z axis to the separation height. Returns error if no Contact
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition=""):
+ """
+ Moves the Chuck stage in X, Y, Z and Theta to the load position.
+ API Status: published
+ Args:
+ LoadPosition:str = "First"
+ Command Timeout: 60000
+ Example:MoveChuckLoad 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the chuck Z axis to the specified height. If contact is set, only moves up
+ to contact height will be allowed. If overtravel is enabled - up to overtravel
+ height.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 60000
+ Example:MoveChuckZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the chuck Z axis to the specified height and sets contact. The move stops
+ immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+ been found and an old one was set before the old contact will not get lost, it
+ will be reset.
+ API Status: published
+ Args:
+ Height:Decimal = 100
+ PosRef:str = "Relative"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 60000
+ Example:SearchChuckContact 1000 R Y 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+ return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+ """
+ Moves the chuck stage in velocity mode. The motion continues until the
+ StopChuckMovement command is received, or the end limit is reached.
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveChuckVelocity + + 0 100 30 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop=""):
+ """
+ Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+ API Status: published
+ Args:
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:StopChuckMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel="", AutoZ="", Interlock="", ContactSearch="", EdgeInterlock="", QuietContact=""):
+ """
+ Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+ is made from 6 flags and you can control all of them using this command. Every
+ flag can be turned on by using value 1 or turned off by using value 0. If you do
+ not want to change a flag - use value of 2.
+ API Status: published
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ ContactSearch:int = 2
+ EdgeInterlock:int = 2
+ QuietContact:int = 2
+ Command Timeout: 5000
+ Example:SetChuckMode 2 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode="", Unit="", XValue="", YValue=""):
+ """
+ Sets wafer and die home position, which can be used later as coordinate system
+ for movements.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue="", YValue="", Unit=""):
+ """
+ Sets the wafer index size. Normally the size of one die.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetChuckIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight="", Mode="", Unit="", Value=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation. A predefined contact search gap is able to write. No data
+ in the optional parameters sets contact height at current position. If Mode is
+ '0', contact height can be set at current position. The levels O, A, S and T
+ support no Mode '0'. If Mode is 'V' and no value for height is specified -
+ default 0 will be used, what potentially can be not what you expect. If Mode is
+ 'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+ 'R'.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHeight C V Y 5000.
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit=""):
+ """
+ The command gets the current die size which is stored in the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+ global ReadChuckIndex_Response
+ if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+ return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+ """
+ Moves the Chuck to the Transfer Position. If the movement starts in Load
+ Position (where it's possible to pull out the chuck) the handling of the Add On
+ Platen or the Pin Chuck is integrated.
+ API Status: published
+ Command Timeout: 90000
+ Example:MoveChuckTransfer
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift=""):
+ """
+ Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+ motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveChuckLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX="", ScaleY=""):
+ """
+ Thermo drifts of the wafer will be compensated. The compensation is not
+ persistent, (power off - this compensation is deleted). The algorithm works as
+ an additional one. This is for an iterative usage, so: 1. `ResetProber H` 2.
+ `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5` will result in a
+ scale of 2.25 in both directions. The thermal scale can also be reset using the
+ command 'SetChcukThermoValue 20 C'
+ API Status: published
+ Args:
+ ScaleX:Decimal = 1
+ ScaleY:Decimal = 1
+ Command Timeout: 5000
+ Example:SetChuckThermoScale 1.000005 1.0000045
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+ """
+ Read the linear scaling value of the chuck.
+ API Status: published
+ Returns:
+ ScaleX:Decimal
+ ScaleY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoScale
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+ global ReadChuckThermoScale_Response
+ if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+ return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature="", Unit="", ExpCoeffX="", ExpCoeffY=""):
+ """
+ Set a temperature and optional the expansion coefficient. The temperature for
+ normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+ set the temperature directly the controller calculates the stage difference in
+ the coordinate system. For the calculation use the set coefficient of expansion
+ from the controller. The default coefficient of expansion is based on silicon:
+ 2.33E-06 1/K.
+ API Status: published
+ Args:
+ Temperature:Decimal = 0
+ Unit:str = "Celsius"
+ ExpCoeffX:Decimal = 0
+ ExpCoeffY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckThermoValue 250 C 2.43 2.32
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit=""):
+ """
+ Read the current temperature (either set or calculated) for the thermal scaling.
+ With SetChuckThermoScale in use, the value will be calculated by the current
+ scale and the expansion factor of silicium. The temperature that is read with
+ this command is not identical to the current chuck temperature.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ Temperature:Decimal
+ ExpCoeffX:Decimal
+ ExpCoeffY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoValue C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+ global ReadChuckThermoValue_Response
+ if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+ return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ChuckTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetChuckTableID ChuckTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+ return int(rsp[0])
+
+def MoveChuckTablePoint(TableID="", PointID="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move the chuck to the next stored table site.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckTablePoint 3 10 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID="", PointID="", Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the table site information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadChuckTablePoint 10 250 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+ global ReadChuckTablePoint_Response
+ if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the chuck table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearChuckTablePoint(TableID="", StartPoint="", EndPoint=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of chuck table site points in the in the Kernel. If Start
+ Point is -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearChuckTablePoint 5 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+ global ClearChuckTablePoint_Response
+ if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is moved to slowly attach a wafer that is at ambient temperature while
+ the chuck is hot. The command acts similar to MoveChuckTransfer when moving
+ out of Load 2 but will use a much slower Z velocity. This is only supported
+ for BnR-machines (CM300 and Summit200) at the moment.
+ API Status: internal
+ Args:
+ MoveTimeMs:Decimal = 30000
+ Command Timeout: 300000
+ Example:AttachAmbientWafer
+ """
+ MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+ """
+ Returns the actual status of the chuck Theta axis.
+ API Status: published
+ Returns:
+ IsInit:int
+ FlagsLimit:int
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadThetaStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+ global ReadThetaStatus_Response
+ if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+ return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit="", PosRef=""):
+ """
+ Returns the actual Theta position.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ PosRef:str = "Home"
+ Returns:
+ Position:Decimal
+ Command Timeout: 5000
+ Example:ReadThetaPosition D Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+ return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus="", FlagsMoveRange=""):
+ """
+ Performs an initialization move and resets the coordinate system of the Theta
+ axis.
+ API Status: published
+ Args:
+ FlagsDoPlus:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitTheta 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position="", PosRef="", Unit="", Velocity=""):
+ """
+ Moves the chuck Theta axis to the specified position. The positive direction is
+ counter-clockwise.
+ API Status: published
+ Args:
+ Position:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Degrees"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveTheta 1000. R E
+ """
+ MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity="", Velocity=""):
+ """
+ Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+ clockwise. The motion continues until the StopThetaMovement command is received,
+ or the end limit (error condition) is reached. This command is mostly used for
+ joystick movements that do not have a target destination.
+ API Status: published
+ Args:
+ Polarity:str = "Fixed"
+ Velocity:Decimal = 0
+ Command Timeout: 240000
+ Example:MoveThetaVelocity + 67
+ """
+ MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+ """
+ Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+ treated as a smooth stop rather than an emergency stop.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopThetaMovement
+ """
+ MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode="", Unit="", Position=""):
+ """
+ Sets the chuck Theta position to home. This position is usable as reference
+ position for other commands.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Degrees"
+ Position:Decimal = 0
+ Command Timeout: 5000
+ Example:SetThetaHome 0
+ """
+ MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance="", TriggerEveryNthCycle="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts moving the chuck from the current position with Velocity [%] over
+ ZDistance (sign is important, as a negative sign will move chuck down during
+ scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+ be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+ until the ZDistance has been reached. Command returns number of positions and
+ all compensated Z Positions from Zero, where the trigger was sent.
+ API Status: internal
+ Args:
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 3
+ Velocity:Decimal = 10
+ Returns:
+ NumberOfPositions:int
+ TriggerPositions:str
+ Command Timeout: 60000
+ Example:ScanChuckZ 300 3 1.5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+ global ScanChuckZ_Response
+ if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+ return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+ """
+ Moves the chuck Z axis to a z height considered safe. This is either the lower
+ Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+ API Status: published
+ Command Timeout: 60000
+ Example:MoveChuckZSafe
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel="", AutoZ="", Interlock="", AutoZFollow="", AutoQuiet=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The mode manages the way the platen behaves when it is in contact height. Platen
+ mode is made up from 5 flags and the user can control all of them by using this
+ command. Every flag can be turned on by setting value 1 or turned off by setting
+ value 0. If no change for a flag is wanted, use the value of 2.
+ API Status: internal
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Command Timeout: 5000
+ Example:SetPlatenMode 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen to the high (0) or low = lifted (1) position. This initiates
+ motion; the actual movement may take some seconds.
+ API Status: internal
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MovePlatenLift 1
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height="", PosRef="", Unit="", Velocity="", CompLayer=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Searches contact height using the edge sensor using a z movement of the platen
+ stage
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ CompLayer:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+ return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current platen status.
+ API Status: internal
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ PresetHeight:str
+ IsLiftDown:int
+ Command Timeout: 10000
+ Example:ReadPlatenStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+ global ReadPlatenStatus_Response
+ if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+ return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit="", PosRef="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the platens X, Y and Z axes. The default
+ compensation is the currently selected compensation for the stage.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+ global ReadPlatenPosition_Response
+ if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+ return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual settings for the probe Z movement.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+ global ReadPlatenHeights_Response
+ if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+ return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the platens X, Y and Z axes. Currently the initialization in
+ negative direction and the move range scan are not supported.
+ API Status: internal
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitPlaten 4
+ """
+ MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the specified height. If contact is set, only moves
+ up to contact height will be allowed. If overtravel is enabled - up to
+ overtravel height.
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MovePlatenZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a movement of platen Z axis to preset contact height or returns an
+ error, if no contact height is set.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenContact 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the align height. If no contact height is set, the
+ command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the separation height. If no contact height is set,
+ the command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen stage in velocity mode. The motion continues until the
+ StopPlatenMovement command is received, or the software fence is reached.
+ API Status: internal
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 240000
+ Example:MovePlatenVelocity + + 0 67 50 0
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the movement of a set of platen axes immediately.
+ API Status: internal
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 10000
+ Example:StopPlatenMovement 4
+ """
+ MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight="", Mode="", Unit="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation height. A command without data sets contact height at
+ current position.
+ API Status: internal
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 10000
+ Example:SetPlatenHeight C V Y 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the current status of the manual platen. THis is only supported for
+ Nucleus and Summit200.
+ API Status: internal
+ Returns:
+ IsUp:int
+ IsDown:int
+ IsSafe:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+ global ReadManualPlatenState_Response
+ if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+ return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+ """
+ Returns the current scope status.
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsScopeLiftUp:int
+ PresetHeight:str
+ IsScopeLight:int
+ FlagsMode:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadScopeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+ global ReadScopeStatus_Response
+ if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+ return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit="", PosRef="", Comp=""):
+ """
+ Returns the actual scope stage position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadScopePosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+ global ReadScopePosition_Response
+ if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+ return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit=""):
+ """
+ Returns the actual settings of the focus height, align gap, and separation gap
+ for the scope Z axis.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ FocusHeight:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+ global ReadScopeHeights_Response
+ if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+ return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+ """
+ Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+ the Direction default is XY in minus and Z in plus. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 240000
+ Example:InitScope 3 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 70000
+ Example:MoveScope 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps="", YSteps="", PosRef="", Velocity=""):
+ """
+ Moves the microscope stage in index steps. If no PositionReference byte is
+ passed the scope will step relative to the wafer home position. ('R' means the
+ step relative to current position).
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves the microscope Z axis to the specified height. Default velocity is 100%.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 120000
+ Example:MoveScopeZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode="", FollowMode=""):
+ """
+ Scope mode is made up of two flags which can be controlled using this command.
+ Each flag can be turned on by using value 1 or turned off by using value 0. If
+ you do not want to change a flag, use value of 2.
+ API Status: published
+ Args:
+ QuietMode:int = 2
+ FollowMode:int = 2
+ Command Timeout: 5000
+ Example:SetScopeMode 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+ """
+ Moves the microscope stage in velocity mode. The motion continues until the
+ StopScopeMovement command is received, or the end limit (error condition) is
+ reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+ in minus direction '0' Do not change this axis
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveScopeVelocity + + 0 67 100 0
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop=""):
+ """
+ Stops scope movement for the given axis. A smooth stop is executed, no emergency
+ stop.
+ API Status: published
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 5000
+ Example:StopScopeMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode="", Unit="", XValue="", YValue=""):
+ """
+ Sets the scope Home position in X and Y. It identifies the scope coordinate
+ system for later movements. Usually this position is identical to the die home
+ location.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue="", YValue="", Unit=""):
+ """
+ Sets the microscope index size. Normally set in relation to the wafer index
+ size.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetScopeIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight="", Mode="", Unit="", Value=""):
+ """
+ This command defines scope focus height and the corresponding gaps for alignment
+ or separation. No data sets focus height at current position.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHeight F 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit=""):
+ """
+ Returns the actual scope stage index values in X and Y.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+ global ReadScopeIndex_Response
+ if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+ return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 25000
+ Example:MoveScopeFocus 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity=""):
+ """
+ Moves the Scope Z axis to the alignment height. If no focus height is set an
+ error will bereturned.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 10000
+ Example:MoveScopeAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity=""):
+ """
+ Moves the scope Z axis to the separation height. Returns an error if no focus
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveScopeSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift=""):
+ """
+ Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+ initiates the motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveScopeLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current status of the motorized turret.
+ API Status: internal
+ Returns:
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadTurretStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+ return int(rsp[0])
+
+def SelectLens(Lens=""):
+ """
+ Parfocality and para-centricity are adjusted according to the stored values.
+ This can be used with manual turrets to compensate for XYZ differences between
+ lenses.
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 30000
+ Example:SelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ScopeTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetScopeTable ScopeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+ return int(rsp[0])
+
+def MoveScopeTablePoint(TableID="", PointID="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeTablePoint 10 5 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID="", PointID="", Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the scope table site Information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadScopeTablePoint 2 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+ global ReadScopeTablePoint_Response
+ if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+ """
+ Returns the number of the current microscope lens.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:ReadCurrentLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+ return int(rsp[0])
+
+def SetScopeTablePoint(TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the scope table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearScopeTablePoint(TableID="", StartPoint="", EndPoint=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of scope table site points in the Kernel. If Start Point is
+ -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearScopeTablePoint 2 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+ global ClearScopeTablePoint_Response
+ if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+ """
+ Returns the number of silos in the scope fence. Will be zero if no silos are
+ configured.
+ API Status: published
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadScopeSiloCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+ return int(rsp[0])
+
+def ReadProbeStatus(Probe=""):
+ """
+ Returns the current positioner's status.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Returns:
+ ProbeEcho:int
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ Side:str
+ PresetHeight:str
+ IsLiftUp:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProbeStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+ global ReadProbeStatus_Response
+ if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+ return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe="", Unit="", PosRef="", Comp=""):
+ """
+ Returns the actual positioner's position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadProbePosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+ global ReadProbePosition_Response
+ if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+ return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe="", Unit=""):
+ """
+ Returns the actual settings for the probe Z movement.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+ global ReadProbeHeights_Response
+ if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe="", Side=""):
+ """
+ Defines the orientation of the positioner's coordinate system and turns the
+ Y-axis of the probe coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Side:str = "Left"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:OrientProbe 1 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+ return int(rsp[0])
+
+def InitProbe(Probe="", FlagsInit="", FlagsDirection="", FlagsMoveRange="", FlagsInitInPlace=""):
+ """
+ Performs an initialization move and resets the coordinate system of the given
+ positioner.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ FlagsInitInPlace:int = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 120000
+ Example:InitProbe 1 7 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+ return int(rsp[0])
+
+def MoveProbe(Probe="", XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbe 1 1000. 1000. R Y 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeIndex(Probe="", XSteps="", YSteps="", PosRef="", Velocity=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeIndex 1 1 1 R 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+ return int(rsp[0])
+
+def MoveProbeContact(Probe="", Velocity=""):
+ """
+ Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+ height is set, the kernel will return a 'Contact height not set' error.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeContact 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeAlign(Probe="", Velocity=""):
+ """
+ Moves the given ProbeHeads Z axis to the align height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeAlign 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeSeparation(Probe="", Velocity=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeSeparation 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeZ(Probe="", Height="", PosRef="", Unit="", Velocity="", Comp=""):
+ """
+ Moves a given ProbeHeads Z axis to a defined Z height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeZ 1 1000. R Y 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeLift(Probe="", SetLift=""):
+ """
+ Moves the positioner to the lower (0) or upper = lifted (1) position. The
+ command initiates the motion only, the whole movement may take some seconds.
+ API Status: published
+ Args:
+ Probe:int = 1
+ SetLift:int = 1
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:MoveProbeLift 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+ return int(rsp[0])
+
+def MoveProbeVelocity(Probe="", PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+ """
+ '+' Move this axis into plus direction '-' Move this axis into minus direction
+ '0' Do not change this axis
+ API Status: published
+ Args:
+ Probe:int = 1
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeVelocity 1 + + Z 67 100 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+ return int(rsp[0])
+
+def StopProbeMovement(Probe="", FlagsStop=""):
+ """
+ Stops positioner movement for the given axes immediately. A smooth stop is
+ performed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsStop:int = 7
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:StopProbeMovement 1 7
+ """
+ rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+ return int(rsp[0])
+
+def SetProbeMode(Probe="", Overtravel="", AutoZ="", Interlock="", AutoZFollow="", AutoQuiet=""):
+ """
+ The mode manages the way the chuck behaves when it is in contact height.
+ Positioner mode is made up from 5 flags and the user can control all of them by
+ using this command. Every flag can be turned on by setting value 1, or turned
+ off by setting value 0. Use the value 2 if no change for a flag is needed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeMode 1 2 2 2 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+ return int(rsp[0])
+
+def SetProbeHome(Probe="", Mode="", Unit="", XValue="", YValue=""):
+ """
+ Sets the positioner's Home position in X and Y. This position identifies the
+ probe coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetProbeIndex(Probe="", XValue="", YValue="", Unit=""):
+ """
+ Sets the positioner's index size or the location of the reference die relative
+ to the home die.
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetProbeHeight(Probe="", PresetHeight="", Mode="", Unit="", Value=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align, load and separation height. No data sets contact height at current
+ position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadProbeIndex(Probe="", Unit=""):
+ """
+ Returns the current positioner's wafer index values or the current positioner's
+ index positions for X and Y.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+ global ReadProbeIndex_Response
+ if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+ return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe="", NewLEDState=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the positioner LED On or Off.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ NewLEDState:int = 0
+ Returns:
+ ProbeEcho:int
+ LEDState:int
+ Command Timeout: 5000
+ Example:SetProbeLED 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+ global SetProbeLED_Response
+ if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+ return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe="", TableName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the ID of a stored probe table or creates a new table. The ID is unique
+ for the name and the probe. The table itself has a string name. This name is not
+ case sensitive. The command has to be used before all other table commands can
+ be used. Access to tables is possible only with an ID Number (name dependent).
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableName:str = "ProbeTable"
+ Returns:
+ ProbeEcho:int
+ TableID:int
+ Command Timeout: 5000
+ Example:GetProbeTableID 1 ProbeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+ global GetProbeTableID_Response
+ if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+ return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe="", TableID="", PointID="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 1
+ PointID:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeTablePoint 3 14 10 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+ return int(rsp[0])
+
+def ReadProbeTablePoint(Probe="", TableID="", PointID="", Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the data from a point of a stored table in the Kernel.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadProbeTablePoint 2 4 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+ global ReadProbeTablePoint_Response
+ if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+ return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe="", TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+ point with this index loaded, the Kernel returns an error. Number of positions
+ and number of tables are dependet on the internal memory. All positions are
+ stored persistent, that means after switching power on or off the positions are
+ still available. The table starts with point number 1 and ends with the ID 16.
+ The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ProbeEcho:int
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ global SetProbeTablePoint_Response
+ if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+ return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe="", TableID="", StartPoint="", EndPoint=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+ is a negative value, the whole table will be deleted.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ProbeEcho:int
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearProbeTablePoint 3 4 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+ global ClearProbeTablePoint_Response
+ if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+ return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index=""):
+ """
+ Move the scope to the reference position of the given silo. The reference
+ position should be - if not defined otherwise - 200 um above the safe z-height
+ in the center of the scope.
+ API Status: published
+ Args:
+ Index:int = 1
+ Command Timeout: 70000
+ Example:MoveScopeSilo 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index="", X="", Y="", Z=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the reference position of a silo. The next time the scope moves to this
+ silo, it woll go to this position. The Referenceposition must be inside the silo
+ in xy and above the lower Z-Fence of the silo. Setting the reference position
+ directly on the fence in x, y or z typically leads to errors. Try to keep a
+ safety margin.
+ API Status: internal
+ Args:
+ Index:int = 1
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeSiloReference 1 1000 2000 3000
+ """
+ MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance="", YDistance="", PosRef=""):
+ """
+ This command causes a chuck Theta axis rotation to align the wafer to the chuck
+ X,Y movements. It can be used to perform a two point alignment with
+ P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line. The units of
+ the distances are not important - but both distances should use the same unit.
+ If one or both distances are zero, the command does not return an error and
+ instead ignore this alignment
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignChuckTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance="", YDistance="", PosRef=""):
+ """
+ This command causes a virtual rotation of the scope coordinate system to align
+ the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of X and Y distances:
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignScopeTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe="", XDistance="", YDistance="", PosRef=""):
+ """
+ This command causes a rotation of the coordinate system of given probe to align
+ the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of Y and Y distances:
+ API Status: published
+ Args:
+ Probe:int = 1
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:AlignProbeTheta 1 10000 10 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+ return int(rsp[0])
+
+def AlignCardTheta(Angle="", Unit="", PosRef=""):
+ """
+ This command causes a rotation of the chuck coordinate system to align the chuck
+ X, Y axis to the probecard. The polarity of the data determines a left or a
+ right rotation of the chuck coordinate system.
+ API Status: published
+ Args:
+ Angle:Decimal = 0
+ Unit:str = "Degrees"
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignCardTheta 2.5 D R
+ """
+ MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit=""):
+ """
+ Returns the angle between the chuck-coordinate-system and the probecard-
+ coordinate-system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadCardTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit=""):
+ """
+ Returns the current chuck alignment angle which is identical to the current
+ value of theta rotation.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit=""):
+ """
+ Returns the scope's alignment angle, which is the angle between the chuck
+ coordinate system and the scope coordinate system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe="", Unit=""):
+ """
+ Returns the actual positioner's alignment angle, which is the angle between the
+ chuck coordinate system and the positioner coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Degrees"
+ Returns:
+ ProbeEcho:int
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeTheta 1 D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+ global ReadProbeTheta_Response
+ if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+ return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage="", Axis=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the preset speeds, which are used by the joystick controller for moving a
+ single stage. The speeds can be read for XY, for Z and for Theta axis
+ separately. Jog timing and index timing are the times, the joystick controller
+ waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "X"
+ Returns:
+ JogTime:Decimal
+ Speed2:Decimal
+ Speed3:Decimal
+ Speed4:Decimal
+ IndexTime:Decimal
+ Command Timeout: 5000
+ Example:ReadJoystickSpeeds S Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+ global ReadJoystickSpeeds_Response
+ if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+ return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage="", JogTime="", Speed2="", Speed3="", Speed4="", IndexTime="", Axis=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the preset speeds, which are used by the joystick controller for moving a
+ single stage. After setting, the speeds can be selected by pressing the Speed n
+ buttons at the controller. The speeds must be set separately for XY, for Z and
+ for Theta axis. Jog timing and index timing are the times, the joystick
+ controller waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ JogTime:Decimal = 0
+ Speed2:Decimal = 0
+ Speed3:Decimal = 0
+ Speed4:Decimal = 0
+ IndexTime:Decimal = 0
+ Axis:str = "X"
+ Command Timeout: 5000
+ Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open=""):
+ """
+ Opens or closes the loader gate. Automatic handling systems can load wafers to
+ the chuck through the gate.
+ API Status: published
+ Args:
+ Open:int = 0
+ Command Timeout: 5000
+ Example:SetLoaderGate 0
+ """
+ MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+ """
+ Returns whether the system detected a wafer. This feature can be used if the
+ probe station is equipped with a vacuum sensor and while vacuum is activated.
+ API Status: published
+ Returns:
+ SensedByVac:str
+ Command Timeout: 5000
+ Example:ReadWaferStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage=""):
+ """
+ Returns the number of times this stage moved to contact since the last time the
+ counter was reset.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadContactCount C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+ return int(rsp[0])
+
+def ResetContactCount(Stage=""):
+ """
+ Resets the contact counter for the specified stage to zero. Notifications: 23
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:ResetContactCount C
+ """
+ MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command enables the manual mode on Elite/Summit/S300 systems. This mode
+ will allow to move the chuck using the knobs.
+ API Status: internal
+ Args:
+ Enable:int = 1
+ Command Timeout: 10000
+ Example:SetManualMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of the manual mode on Elite/Summit/S300 stations.
+ API Status: internal
+ Returns:
+ Enable:int
+ Command Timeout: 10000
+ Example:GetManualMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+ return int(rsp[0])
+
+def GetAxisReverse(Stage="", Axis=""):
+ """
+ Allows reading if an axis is reverse.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ IsReverse:int
+ Command Timeout: 5000
+ Example:GetAxisReverse C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+ return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor="", Enable=""):
+ """
+ Enables/disables the use of an edge sensor.
+ API Status: published
+ Args:
+ EdgeSensor:int = 1
+ Enable:int = 1
+ Command Timeout: 5000
+ Example:EnableEdgeSensor 1 1
+ """
+ MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel="", WantOutputOn="", PulseTime=""):
+ """
+ Controls the kernel valve driver signals and can be used to drive the outputs.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetTypedOutput WaferVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel=""):
+ """
+ Returns the status of the specified input channel, output channel, or edge
+ sensor.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadTypedSensor EmoIn I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+ return int(rsp[0])
+
+def MoveCoolDownPosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck to the cool down position that is defined in KernelSetup. The
+ cooldown position is used to move the chuck away in XY while the robot is in the
+ chamber and tries to get a hot wafer.
+ API Status: internal
+ Command Timeout: 30000
+ Example:MoveCoolDownPosition
+ """
+ MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the cycling speeds - these are the speeds that are used by
+ the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CycleJog:int
+ CycleSpeed2:int
+ CycleSpeed3:int
+ CycleSpeed4:int
+ CycleIndex:int
+ Command Timeout: 5000
+ Example:ReadJoystickSpeedsCycle S
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+ global ReadJoystickSpeedsCycle_Response
+ if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+ return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage="", CycleJog="", CycleSpeed2="", CycleSpeed3="", CycleSpeed4="", CycleIndex=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets the cycling speeds - these are the speeds that are used by the
+ USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CycleJog:int = 0
+ CycleSpeed2:int = 0
+ CycleSpeed3:int = 0
+ CycleSpeed4:int = 0
+ CycleIndex:int = 0
+ Command Timeout: 5000
+ Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows sending low level AUCS commands to the ECX box stage. Only
+ applies to Elite/Summit/S300 stations.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 60000
+ Example:SendAUCSCommand "MM 1 0 INIT 0"
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage="", Compensation=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command allows reading if a specific type of compensation is enabled or
+ disabled. Returns an error if this type of compensation is not available for
+ this stage.
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Returns:
+ Enabled:int
+ Active:int
+ Command Timeout: 5000
+ Example:ReadCompensationStatus C A
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+ global ReadCompensationStatus_Response
+ if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+ return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode="", WantNotification=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deprecated. All Kernel notifications are now enabled by default.
+ API Status: internal
+ Args:
+ NotificationCode:int = 0
+ WantNotification:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId="", Value1="", Value2="", Value3=""):
+ """
+ This is not a regular command. Asynchronous notifications will be sent from the
+ Kernel controller to the host system only. All notifications can be switched off
+ and on, except the Prober reset notification (ID01). /warning This is a stub
+ implementation without appropriate handling
+ API Status: published
+ Args:
+ NotificationId:int = 0
+ Value1:Decimal = 0
+ Value2:Decimal = 0
+ Value3:Decimal = 0
+ Command Timeout: 5000
+ Example:AlertNotification 31 195000 160000 0
+ """
+ MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage="", Compensation="", Status=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables a compensation mode for the specified stage
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Status:int = -1
+ Command Timeout: 5000
+ Example:SetCompensationStatus C A 1
+ """
+ MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command gets the value "Value" for the parameter "Parameter". The unit is
+ parameter specific.
+ API Status: internal
+ Args:
+ ControllerInfo:str = "Unknown"
+ Returns:
+ Value:Decimal
+ Command Timeout: 1000
+ Example:GetControllerInfo HasScanChuckZ
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+ return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ In unprotected mode a number of security features like software fence and
+ initialization necessity are deactivated. Unprotected mode is
+ deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+ anytime before resets the timer back to 5 minutes. It is not necessary to
+ deactivate it before. **WARNING**: If unprotected mode is enabled, even the
+ most basic safety- and sanity-checks are skipped. Any movement may cause
+ irreparable damage to the prober or attached hardware.
+ API Status: internal
+ Args:
+ OperationalMode:str = "ProtectedMode"
+ Command Timeout: 5000
+ Example:SetOperationalMode P
+ """
+ MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured Nano-chamber-state.
+ API Status: internal
+ Returns:
+ NanoChamberState:str
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the NanoChamber-state.
+ API Status: internal
+ Args:
+ NanoChamberState:str = "Free"
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows to force activate/deactivate the camera cool output or to let it be set
+ automatically by purge control.
+ API Status: internal
+ Args:
+ State:int = 2
+ Command Timeout: 10000
+ Example:SetCameraCool 0
+ """
+ MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the chuck vacuum and forces it to be on. This command ignores the
+ vacuum sensor and timeout.
+ API Status: internal
+ Command Timeout: 10000
+ Example:ActivateChuckVacuum
+ """
+ MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage="", MatrixIndexX="", MatrixIndexY=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns a point from the matrix compensation table for the
+ specified axis from the kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ Returns:
+ XVal:Decimal
+ YVal:Decimal
+ Command Timeout: 5000
+ Example:ReadMatrixValues C 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+ global ReadMatrixValues_Response
+ if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+ return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage="", MatrixIndexX="", MatrixIndexY="", XVal="", YVal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Downloads a point of the matrix compensation table for a specified stage to the
+ kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ XVal:Decimal = 0
+ YVal:Decimal = 0
+ Command Timeout: 5000
+ Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+ """
+ MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage="", Type=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+ only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Returns:
+ Enable:int
+ Command Timeout: 5000
+ Example:ReadMEAStatus C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+ return int(rsp[0])
+
+def LoadMEAFile(Stage="", Type="", Load=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Load the MEA file for a stage (Nucleus legacy stations only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Load:int = 0
+ Command Timeout: 5000
+ Example:LoadMEAFile C 0 1
+ """
+ MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The command returns the positions of the actual software limits (end of move
+ range) for each axis of the specified stage in microns. If the Theta stage is
+ selected Z1 and Z2 include the values for the Theta limits.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ ZLowValue:Decimal
+ ZHighValue:Decimal
+ X1Value:Decimal
+ Y1Value:Decimal
+ X2Value:Decimal
+ Y2Value:Decimal
+ X3Value:Decimal
+ Y3Value:Decimal
+ X4Value:Decimal
+ Y4Value:Decimal
+ Command Timeout: 5000
+ Example:ReadSoftwareLimits C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+ global ReadSoftwareLimits_Response
+ if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+ return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage="", AuxID="", FenceForm="", XBase="", YBase="", XDist="", YDist=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets types and dimensions of technological software fences. It can
+ also be used for enabling and disabling the software fence.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ FenceForm:str = "None"
+ XBase:Decimal = 0
+ YBase:Decimal = 0
+ XDist:Decimal = 0
+ YDist:Decimal = 0
+ Command Timeout: 10000
+ Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage="", AuxID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the type and the dimensions of an actual set technological
+ software fence. In case of a rectangular software fence, X and Y coordinates of
+ the four edge points of the fence are given back. In case of a circular software
+ fence, X and Y coordinates of the center point and the radius are given back.
+ All other return values are filled with zeros. All position values are in
+ microns from zero.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ Returns:
+ FenceForm:str
+ XValue1:Decimal
+ YValue1:Decimal
+ XValue2:Decimal
+ YValue2:Decimal
+ XValue3:Decimal
+ YValue3:Decimal
+ XValue4:Decimal
+ YValue4:Decimal
+ Command Timeout: 10000
+ Example:GetSoftwareFence C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+ global GetSoftwareFence_Response
+ if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+ return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage="", CompLayer=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands reads if the Z-Fence is activated and the currently set Z-fence
+ values for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CompLayer:str = "Default"
+ Returns:
+ Enabled:int
+ ZLow:Decimal
+ ZHigh:Decimal
+ Command Timeout: 10000
+ Example:GetZFence S
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+ global GetZFence_Response
+ if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+ return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage="", Enabled="", ZLow="", ZHigh="", CompLayer=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands sets Z-Fence and the Z-fence values for the specified stage.
+ Values are stored uncompensated internally and set default compensated as
+ default.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Enabled:int = 0
+ ZLow:Decimal = 0
+ ZHigh:Decimal = 0
+ CompLayer:str = "Default"
+ Command Timeout: 10000
+ Example:SetZFence S 1 5000 10000
+ """
+ MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the Prober and replaces the current configuration with a formerly
+ written recovery file. If no recovery file was written, the configuration is
+ reset to the version of the last Prober restart. For ProberBench electronics,
+ 'H' will restart the Operating system, 'S' will only restart the Kernel
+ application. For Windows Kernel, 'H' and 'S' are identical.
+ API Status: internal
+ Args:
+ Mode:str = "S"
+ Command Timeout: 20000
+ Example:ResetProber S
+ """
+ MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reboots the operation system inside the Joystick Controller and restarts the
+ functionality. The restart will need a time of around 20 seconds.
+ API Status: internal
+ Args:
+ ResetMode:str = "S"
+ Command Timeout: 20000
+ Example:ResetCBox S
+ """
+ MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage="", LocationType="", AuxID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The Home Position on the Chuck or ProbeHead Z axis is also called contact
+ height. The Home Position on the Scope Z axis is also called focus height.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ LocationType:str = "Center"
+ AuxID:int = 0
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadStageLocations C C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+ global ReadStageLocations_Response
+ if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+ return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters.
+ and requires the GetNextDatum command.
+ API Status: internal
+ Args:
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 10000
+ Example:GetDataIterator 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+ global GetDataIterator_Response
+ if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ Attributes:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:GetNextDatum 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+ global GetNextDatum_Response
+ if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+ return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:SetDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ PathName:str = ""
+ Returns:
+ Attributes:int
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:GetDatum Chuck:AlignGap
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+ global GetDatum_Response
+ if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+ return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 5000
+ Example:SetRecoveryDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the motion recording. The recording parameters are set in dynamic
+ kernel setup.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStart C
+ """
+ MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Checks the motion recording status for one stage.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Returns:
+ IsReady:int
+ SizeCh0Raw:int
+ SizeCh0Comp:int
+ SizeCh1Raw:int
+ SizeCh1Comp:int
+ SizeCh2Raw:int
+ SizeCh2Comp:int
+ SizeCh3Raw:int
+ SizeCh3Comp:int
+ Command Timeout: 10000
+ Example:TraceStatus C
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+ global TraceStatus_Response
+ if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+ return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller="", Channel="", PointOne="", IsCompress=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a collection of five data pairs. A pair is the index and the value of a
+ recording point. If the stream is empty or at the end the index is 1 and the
+ value 0. The index is relative to the start of the motion recording. The
+ recording is clocked by the motion controller cycle. The cycle time is contained
+ in the Kernel setup. In the raw stream all recorded trace points are contained.
+ But in the compressed stream only the non-linear depending trace points are
+ contained. To reload the recording points the stream must be reset to the first
+ recording point.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ PointOne:int = 1
+ IsCompress:int = 1
+ Returns:
+ Point1:int
+ Value1:int
+ Point2:int
+ Value2:int
+ Point3:int
+ Value3:int
+ Point4:int
+ Value4:int
+ Point5:int
+ Value5:int
+ Command Timeout: 10000
+ Example:TraceGetData C 0 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+ global TraceGetData_Response
+ if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+ return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller="", Channel="", NewPos="", IsCompress=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the index position in the raw or compressed stream for the next call of the
+ command TraceGetData.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ NewPos:int = 0
+ IsCompress:int = 1
+ Command Timeout: 10000
+ Example:TraceSetDataPosition C 0 1000 1
+ """
+ MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the motion recording.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStop C
+ """
+ MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage="", XValue="", YValue="", ZGap="", PosRef="", Unit="", ZProfileType=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set a point for the Z height profile. If this profile is enabled, the Z height
+ depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+ Positive values are elevated spots, negative values are hollows. The height
+ profile is used to adjust the Z height. The adjusted Z height at a X and Y
+ position is derivated from the nearest profile point. The Z contact level will
+ be calculated from the contact height and the stored Z gap at this point. See
+ GetZProfilePoint for details.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZGap:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ ValueCount:int
+ Command Timeout: 5000
+ Example:SetZProfilePoint C 5000 5000 -3 H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+ return int(rsp[0])
+
+def ReadZProfilePoint(Stage="", Index="", PosRef="", Unit="", ZProfileType=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a single point and the corresponding Z gap of the Z height profile. The
+ different z profiles are: - transient: meant to be used on a per-wafer-basis,
+ default - persistent: configured once, stays in memory - persistent-offset: same
+ as persistent, active when offset is enabled - scratch: not used internaly. Can
+ be used to translate KernelDatums <-> ZProfile-Points
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Index:int = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ XValue:Decimal
+ YValue:Decimal
+ ZGap:Decimal
+ ValueCount:int
+ Command Timeout: 5000
+ Example:ReadZProfilePoint C 1 H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+ global ReadZProfilePoint_Response
+ if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+ return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage="", ZProfileType=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clears all profile points. See GetZProfile for type description.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZProfileType:int = 0
+ Command Timeout: 5000
+ Example:ClearZProfile C
+ """
+ MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index=""):
+ """
+ Returns the definition of a silo. If the type is rectangle, center means
+ _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+ API Status: published
+ Args:
+ Index:int = 1
+ Returns:
+ Type:str
+ CenterX:Decimal
+ CenterY:Decimal
+ Radius:Decimal
+ Pos2X:Decimal
+ Pos2Y:Decimal
+ ZHigh:Decimal
+ RefX:Decimal
+ RefY:Decimal
+ RefZ:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeSilo 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+ global ReadScopeSilo_Response
+ if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+ return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName=""):
+ """
+ Alerts applications if the project file was changed.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName=""):
+ """
+ Alerts applications to save the current project. This notification _MUST_ only
+ be invoked by CommonCommands. Sending this notification directly _WILL_ give
+ erroneous results.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel="", UserName="", VeloxLocked=""):
+ """
+ Alerts applications of new access level.
+ API Status: published
+ Args:
+ AccessLevel:str = "Engineer"
+ UserName:str = ""
+ VeloxLocked:int = 0
+ Command Timeout: 5000
+ Example:NewAccessLevel 1
+ """
+ MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled="", AnnualDaysLeft="", VeloxProEnabled="", VueTrackEnabled="", VueTrack4PEnabled="", ReAlignEnabled="", AutomationEnabled="", IdToolsEnabled="", IVistaEnabled="", IVistaProEnabled="", LaserCutterEnabled="", SiPToolsEnabled="", AutoRfEnabled=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener about the licensed Velox features. Is sent cyclically by
+ CommonCommands.
+ API Status: internal
+ Args:
+ AnnualEnabled:int = 1
+ AnnualDaysLeft:int = 460
+ VeloxProEnabled:int = 0
+ VueTrackEnabled:int = 0
+ VueTrack4PEnabled:int = 0
+ ReAlignEnabled:int = 0
+ AutomationEnabled:int = 0
+ IdToolsEnabled:int = 0
+ IVistaEnabled:int = 0
+ IVistaProEnabled:int = 0
+ LaserCutterEnabled:int = 0
+ SiPToolsEnabled:int = 0
+ AutoRfEnabled:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName="", SecName="", NewRegistered=""):
+ """
+ Alerts applications that an application is registered or unregistered on
+ MsgServer.
+ API Status: published
+ Args:
+ AppName:str = "SharedTest"
+ SecName:str = "SharedTest"
+ NewRegistered:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications of a change of the current alignment mode
+ API Status: internal
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ Example:AlignmentModeChange OnAxis
+ """
+ MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum="", Type="", Result="", Desc=""):
+ """
+ An example of Kernel Connection Status is "Windows Socket Error Number and
+ Error Description."
+ API Status: published
+ Args:
+ ControllerNum:int = 1
+ Type:str = "Socket"
+ Result:str = "Disconnected"
+ Desc:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage="", Compensation="", Enabled="", Active=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Compensation:str = "None"
+ Enabled:int = 0
+ Active:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage="", Comp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation level has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Comp:str = "None"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status="", PlatenSafe="", Height="", HeightMax="", HeightRelative="", SafeHeight="", Message=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the combined-z-move-system
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ PlatenSafe:int = 0
+ Height:Decimal = 0
+ HeightMax:Decimal = 0
+ HeightRelative:Decimal = 0
+ SafeHeight:Decimal = 0
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the machine state
+ API Status: internal
+ Args:
+ MachineState:str = "Off"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if the user requests a chuck vacuum change
+ API Status: internal
+ Args:
+ VacuumState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if software stop was activated or deactivated
+ API Status: internal
+ Args:
+ SoftwareStopState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet="", Stage="", IsStageQuiet=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs if the overall quiet mode changes and about changes of single stages
+ API Status: internal
+ Args:
+ IsQuiet:int = 0
+ Stage:str = "None"
+ IsStageQuiet:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies that a configuration item has changed by some application
+ API Status: internal
+ Args:
+ ParameterChanged:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs that a new working stage is active
+ API Status: internal
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage="", Axis="", State="", AdditionalStateInfo=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the user Interface and Kernel if the state of the axis has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ State:str = "NotExisting"
+ AdditionalStateInfo:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage="", State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the stage status has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel="", State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an input channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel="", State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an output channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage="", Axis="", Initialized="", PositiveLimit="", NegativeLimit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener that an axis status has changed. Currently used to notify
+ the Kernel about the init state of a BnR axis.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Initialized:int = 0
+ PositiveLimit:int = 0
+ NegativeLimit:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+ AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+ when stepping.
+ API Status: internal
+ Args:
+ AutoXYModeOn:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+ handle this so it doesn't have to poll OpticalControl for the current zoom
+ level.
+ API Status: internal
+ Args:
+ ZoomLevel:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO="", ValuePercent="", UnderOverflow="", Error=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state or value of an analog input or output channel
+ has changed.
+ API Status: internal
+ Args:
+ AnalogIO:str = "AO_PurgeDewPoint"
+ ValuePercent:Decimal = 0
+ UnderOverflow:int = 0
+ Error:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum="", ControllerInfo="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies the listener about changed controller info. Currently used to inform
+ Toolbar about the battery state of the BnR controller.
+ API Status: internal
+ Args:
+ ControllerNum:int = 1
+ ControllerInfo:str = "BatteryOK"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage="", XorT="", Y="", Z="", CommandedXorT="", CommandedY="", CommandedZ=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by BnR controller if a axis position has changed. Currently
+ used to notify the Kernel about the new axis position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XorT:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ CommandedXorT:Decimal = 0
+ CommandedY:Decimal = 0
+ CommandedZ:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType="", Info=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Generic Information Notification
+ API Status: internal
+ Args:
+ InfoType:str = ""
+ Info:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX="", DieY="", XFromHome="", YFromHome="", CurSite="", LastSiteIndex=""):
+ """
+ Alerts applications that WaferMap has a new position.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ XFromHome:Decimal = 0
+ YFromHome:Decimal = 0
+ CurSite:int = 1
+ LastSiteIndex:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+ """
+ Alerts applications that a wafer's parameters have been changed.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+ the identifier for the button as defined for the guided workflow.
+ API Status: internal
+ Args:
+ TargetIdent:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State="", Error="", ErrorDescription=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when the cooling or heating process was terminated successfully or
+ incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+ COOL DOWN, WARMUP) and sends the error code and error message.
+ API Status: internal
+ Args:
+ State:str = "IDLE"
+ Error:int = 0
+ ErrorDescription:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent when Spectrum VS project has finished loading.
+ API Status: internal
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access="", FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent when a probe card file is loaded.
+ API Status: internal
+ Args:
+ Access:str = "L"
+ FileName:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+ """
+ Alerts applications that the TTL Test is ready.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State="", SubState="", Message="", Error=""):
+ """
+ Notification sent when VeloxPro changes its running state.
+ API Status: published
+ Args:
+ State:str = "Unknown"
+ SubState:str = "Unknown"
+ Message:str = ""
+ Error:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent during wafer stepping process. It updates the progress
+ information. 'Progress' is the relationship of dies tested to dies to be tested.
+ API Status: internal
+ Args:
+ ProgressPercent:Decimal = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader="", UseAutoWafer="", WaferSizes=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent to notify the listener about usage of Loader, usage of
+ fully/semiautomatic mode and supported wafer sizes of process station.
+ API Status: internal
+ Args:
+ UseLoader:int = 0
+ UseAutoWafer:int = 0
+ WaferSizes:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by loader to display a message on the process station.
+ API Status: internal
+ Args:
+ Message:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename="", Option=""):
+ """
+ Asks if the current project should be saved and then brings up the Open Project
+ window which opens the selected project file if the user clicks ok.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Option:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+ """
+ Brings up the Save Project window which saves the project if the user clicks ok.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer=""):
+ """
+ Brings up the Login window and sends a New Access Level alert if the user enters
+ a valid password.
+ API Status: published
+ Args:
+ LevelToOffer:str = "1"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+ """
+ Returns the current software status. The server holds and maintains the software
+ status. Status can be changed by using any of the following commands:
+ BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+ UnloadWafer, ResumeProbing
+ API Status: published
+ Returns:
+ DummyCommonMode:int
+ RunningMode:str
+ AccessLevel:str
+ ExternalMode:int
+ LicenseDaysLeft:int
+ MKH:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStatus")
+ global GetStatus_Response
+ if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+ return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Licensing window.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current license information.
+ API Status: internal
+ Returns:
+ AnnualEnabled:int
+ AnnualDaysLeft:int
+ VeloxProEnabled:int
+ VueTrackEnabled:int
+ VueTrack4PEnabled:int
+ ReAlignEnabled:int
+ AutomationEnabled:int
+ IdToolsEnabled:int
+ IVistaEnabled:int
+ IVistaProEnabled:int
+ LaserCutterEnabled:int
+ SiPToolsEnabled:int
+ AutoRfEnabled:int
+ SecsGemEnabled:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+ global GetLicenseInfo_Response
+ if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+ return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+ """
+ Returns the current project file.
+ API Status: published
+ Returns:
+ ProjectFilename:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+ """
+ Returns the Velox software version as string.
+ API Status: published
+ Returns:
+ SoftwareVersion:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename=""):
+ """
+ The OpenProject command opens the specified project.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application=""):
+ """
+ Checks the server to see if the application "AppName" is registered with the
+ server.
+ API Status: published
+ Args:
+ Application:str = ""
+ Returns:
+ IsAppRegistered:int
+ Command Timeout: 5000
+ Example:IsAppRegistered WaferMap
+ """
+ rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+ return int(rsp[0])
+
+def SaveProject(ProjectFilename=""):
+ """
+ Saves the current data to the project file.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType=""):
+ """
+ Returns the path for either the applications/data or project files.
+ API Status: published
+ Args:
+ PathType:str = "User"
+ Returns:
+ SoftwarePath:str
+ Command Timeout: 5000
+ Example:GetSoftwarePath User
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command.
+ API Status: internal
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:CCSelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command. Probably no longer used.
+ API Status: internal
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+ return int(rsp[0])
+
+def CCMoveAuxSite(AuxID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calls the Kernel command MoveAuxSite to move the chuck to the
+ position of a given AUX site. For the transfer move a safe height is used. If
+ AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+ Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+ command AlignAux is executed after MoveAuxSite to align the site automatically.
+ The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+ installed. AUX ID in the response is the ID of the new active site.
+ API Status: internal
+ Args:
+ AuxID:int = 1
+ Command Timeout: 200000
+ """
+ MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName="", AllowMediaReuse="", SkipAlignAux="", SkipReturnMove=""):
+ """
+ This command moves to the single cleaning site, executes CleanProbeTip, moves to
+ the contact verify site, and then moves to contact. Returns an error if the
+ clean or verify sites aren't defined.
+ API Status: published
+ Args:
+ SequenceName:str = ""
+ AllowMediaReuse:int = 0
+ SkipAlignAux:int = 0
+ SkipReturnMove:int = 0
+ Command Timeout: 1800000
+ Example:ExecuteCleaningSequence "DeepClean"
+ """
+ MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+ """
+ Get the active alignment mode (either on axis or off axis).
+ API Status: published
+ Returns:
+ AlignmentMode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode=""):
+ """
+ Sets the active alignment mode (either on axis or off axis).
+ API Status: published
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName=""):
+ """
+ Gets the Velox user data: name, full name, group, access level. If the
+ commanded user name is empty, the data of the current user will be responded
+ API Status: published
+ Args:
+ CmdUserName:str = ""
+ Returns:
+ UserName:str
+ LongUserName:str
+ UserGroup:str
+ AccessLevel:str
+ VeloxLocked:int
+ Command Timeout: 5000
+ Example:GetLoginData
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+ global GetLoginData_Response
+ if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+ return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to warn user of chuck initialization for Nucleus stations.
+ Allows user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to allow saving project before shutting down Velox. Allows
+ user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCal command to WinCal.
+ API Status: internal
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCheckAutoRFStability command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Returns:
+ StabilityPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+ return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCloseRFStabilityReport command to WinCal.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+ reference. The ISS index is the IssIdxMap index as returned from
+ WinCalGetIssListForAuxSite.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+ as 1 if stage and positioners at home.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ AllRefAtHome:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+ return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+ information for the given aux site ID.
+ API Status: internal
+ Args:
+ AuxID:int = 0
+ Returns:
+ IssIdx:int
+ IssPN:str
+ IssDescription:str
+ IssEnabled:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+ global WinCalGetIssForAuxSite_Response
+ if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+ return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetNameAndVersion command to WinCal.
+ API Status: internal
+ Returns:
+ ServerName:str
+ Version:str
+ MajorVersion:int
+ MinorVersion:int
+ Revision:int
+ Build:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+ global WinCalGetNameAndVersion_Response
+ if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+ return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+ monitor portion of the current calibration setup.
+ API Status: internal
+ Returns:
+ MonitorPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+ return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing="", ResetTrace="", AllowMove=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+ the currently selected calibration setup. Resets the controller used in WinCal
+ for validataion.
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ ResetTrace:int = 1
+ AllowMove:int = 1
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+ return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMeasureMonitorReference command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumValidationPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumValidationPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+ return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumValidationPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumValidationPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumMonitoringPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+ return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumMonitoringPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumRepeatabilityPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+ return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumRepeatabilityPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidate command to WinCal. Performs the validation step of the
+ currently selected calibration setup in WinCal.
+ API Status: internal
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+ return int(rsp[0])
+
+def WinCalGetValidationSetup(Port=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+ parameters.
+ API Status: internal
+ Args:
+ Port:int = 1
+ Returns:
+ StandardType:str
+ StandardPorts:int
+ StandardCompareType:int
+ StructureType:str
+ PostCorrect:int
+ PostCorrectMatching:int
+ AutoConfigure:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+ global WinCalGetValidationSetup_Response
+ if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+ return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+ without the validation step
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+ windows
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+ index it will return a string with the reference information
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ ReferenceInfo:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+ if WinCal has unapplied changes
+ API Status: internal
+ Args:
+ ShowErrors:int = 0
+ Returns:
+ HasUnappliedChanges:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+ return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+ indicated by the index, reference as being the current location
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Save Project as Template window which saves the project template
+ if the user clicks ok.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the New Project from Template dialog which allows the user to select a
+ template and create a new project.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns Max Ports and Number of probes connected to a port
+ API Status: internal
+ Returns:
+ MaxPorts:int
+ NumPortsConnectedtoProbes:int
+ Command Timeout: 1000
+ Example:WinCalGetNumPortsAndProbes
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+ global WinCalGetNumPortsAndProbes_Response
+ if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+ return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the properties from one probe, based on the passed in index. Pass in a
+ physical VNA port number that is less than or equal to Max Probes from the call
+ to CalGetNumPortsAndProbes
+ API Status: internal
+ Args:
+ VnaPortNum:int = 1
+ Returns:
+ IsSelected:int
+ BaseProbe:str
+ Options:str
+ PhysicalOrient:str
+ IsDual:int
+ IsSymmetric:int
+ SignalConfig:str
+ SelectedPitch:int
+ Command Timeout: 1000
+ Example:WinCalGetProbeInfoForPort 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+ global WinCalGetProbeInfoForPort_Response
+ if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+ return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current state of the machine.
+ API Status: internal
+ Returns:
+ MachineState:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the help about dialog for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid="", TimeoutMs=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ TimeoutMs:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the last four project files that were opened.
+ API Status: internal
+ Returns:
+ ProjectFile1:str
+ ProjectFile2:str
+ ProjectFile3:str
+ ProjectFile4:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+ global GetLastFourProjects_Response
+ if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+ return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command=""):
+ """
+ Sends the WinCalExecuteCommand command to WinCal and returns the response
+ string.
+ API Status: published
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will return an error if its called with any other parameter as 0.
+ API Status: internal
+ Args:
+ TurnOnDemoMode:int = 1
+ Command Timeout: 5000
+ Example:SetDemoMode 0
+ """
+ MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Override a command with a demo response. The command will not reach its
+ destination but the supplied demo response will be returned. An active overide
+ for a command will be removed if the provided timeout is negative. Format: [ID]
+ [Time] [ErrorCode]:[Response] - Id: command id in hex withoud leding 0x - Time:
+ time in ms between command and response, negativ to reset demo mode for this
+ command - Errorcode: 0 for success, everything else indicates an error -
+ Response: response string
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 5000
+ Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+ """
+ MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will always return 0.
+ API Status: internal
+ Returns:
+ DemoModeOn:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+ return int(rsp[0])
+
+def ResetNetworkPort(Param=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+ tries to connect to (IP address and listen port of Kernel socket). Dummy
+ implementation for Kernel to support backwards.
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 10000
+ Example:ResetNetworkPort 192.168.3.1 10000
+ """
+ MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum="", Param=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets status information about the connection NetworkDriver to Kernel. Socket
+ Error is the Windows socket error, Description the Windows socket error
+ description. If Socket Error is 0, the description 'Registered' informs that the
+ Kernel is ready to receive Remote Commands.
+ API Status: internal
+ Args:
+ ClientNum:int = 1
+ Param:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:GetNDriverClientStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID="", TimeoutMilliSec=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows specifying a separate command timeout for a single instance
+ of a command. This is especially useful if the application that receives a
+ command knows how long a command will take. This command had been added for
+ SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+ 5s.
+ API Status: internal
+ Args:
+ CmdID:int = 0
+ TimeoutMilliSec:int = 1000
+ Command Timeout: 5000
+ Example:OverrideCommandTimeout 3234 20000
+ """
+ MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shutdown all Velox applications in an ordered fashion. When this command returns
+ success, all non-mandatory apps are closed and the mandatory ones will follow
+ shortly
+ API Status: internal
+ Args:
+ IgnorePID:int = 0
+ Command Timeout: 120000
+ Example:ShutdownVelox
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Registration of an application can be delayed. To trigger this behavior,
+ RegisterProberApp has to be called with flag 3 set (0x04). From
+ RegisterProberApp to the time this command is sent, the application can send
+ commands but can't receive commands. This is necessary because some application
+ have to communicate with others during initialization and can not handle
+ commands properly during this time. The command group is necessary because of
+ architectural reasons (By design, the command receiver does not now the sender
+ of a command).
+ API Status: internal
+ Args:
+ CommandGroup:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos="", YPos="", NumberOfPoints="", NumberOfEPoints=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+ only) and pauses after it (even in the automatic mode)
+ API Status: internal
+ Args:
+ XPos:Decimal = 0
+ YPos:Decimal = 0
+ NumberOfPoints:int = 0
+ NumberOfEPoints:int = 0
+ Command Timeout: 60000
+ Example:StepFirstZProfilePoint 10000 20000 5 5
+ """
+ MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calculates a delta value for the current point and then moves to
+ the specified point (if it's presented) or to the next one. Note, that in case
+ of the automatic Z detecting a return ZDelta parameter is a value for the
+ current point, but in case of the semiautomatic mode the command returns ZDelta
+ as a value for a previous tested point. If the profiling is finished this
+ command will return #807 error (End of the profile). Point indices are started
+ from 1 (1 is first, 2 is second, and so on).
+ API Status: internal
+ Args:
+ Point:int = 0
+ Returns:
+ XPos:Decimal
+ YPos:Decimal
+ Delta:Decimal
+ CurPoint:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 60000
+ Example:StepNextZProfilePoint 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+ global StepNextZProfilePoint_Response
+ if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+ return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode="", SepSpeed="", ProfileSensor="", Stage="", SearchSpeed="", Gap="", Units="", ClearElectronics="", ClearRefZ="", Inaccuracy=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets some Z Profile Program Options remotely.
+ API Status: internal
+ Args:
+ ProfileMode:str = "S"
+ SepSpeed:Decimal = 25
+ ProfileSensor:str = "E"
+ Stage:str = "C"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ Units:str = "Y"
+ ClearElectronics:int = 1
+ ClearRefZ:int = 1
+ Inaccuracy:Decimal = 0
+ Command Timeout: 10000
+ Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return predefined settings of the Z Profile Program.
+ API Status: internal
+ Returns:
+ ProfileMode:str
+ SepSpeed:Decimal
+ ProfileSensor:str
+ Stage:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ Units:str
+ ClearElectronics:int
+ ClearRefZ:int
+ Inaccuracy:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileOptions
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+ global GetZProfileOptions_Response
+ if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+ return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command opens the file inside of the Z Profiling.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 240000
+ Example:OpenZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+ global OpenZProfileFile_Response
+ if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves the current profile in the specified file.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:SaveZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+ global SaveZProfileFile_Response
+ if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read a profile from the ProberBench Electronics II to the application. Return a
+ number of available points.
+ API Status: internal
+ Args:
+ NewOrigin:str = "Z"
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:ReadZProfile H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+ return int(rsp[0])
+
+def SetZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Uploads the current profile to the ProberBench Electronics II. Returns a number
+ of written points.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:SetZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+ return int(rsp[0])
+
+def CloseZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Z-Profiling application.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseZProfiling
+ """
+ MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X="", Y="", PosRef="", Units=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets new start point for the profile. All points of the profile will be shifted
+ accordingly.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Command Timeout: 10000
+ Example:SetZProfileStartPoint 0 0 H Y
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the profiling process. If this status is true it means the
+ process is started.
+ API Status: internal
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ Example:GetZProfilingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+ return int(rsp[0])
+
+def StopZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the profiling process.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos="", X="", Y="", Z=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an origin for the profile. If the origin position is H the command ignores
+ X and Y parameters. If Z is None the command clears Z value of the origin.
+ Otherwise it tries to extract a double value from the string and set it.
+ API Status: internal
+ Args:
+ Pos:str = "H"
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:str = "None"
+ Command Timeout: 10000
+ Example:SetZProfileOrigin H 0 0 None
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current parameters of the profile origin. If the origin Z has no value
+ the return string for it will be None, otherwise it consists a double value of
+ the profile Z.
+ API Status: internal
+ Returns:
+ Pos:str
+ X:Decimal
+ Y:Decimal
+ Z:str
+ Command Timeout: 10000
+ Example:GetZProfileOrigin
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+ global GetZProfileOrigin_Response
+ if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+ return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Command Timeout: 10000
+ Example:StartZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 36000000
+ Example:ZProfileWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+ global ZProfileWafer_Response
+ if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+ return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef="", Units=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current start point of the profile by using given units and a
+ reference position.
+ API Status: internal
+ Args:
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileStartPoint H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+ global GetZProfileStartPoint_Response
+ if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+ return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X="", Y="", After=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Adds new point to the profile at the end (default) or after the given point.
+ Returns an index of new point and a number of all points in the profile. Point
+ indices are started from 1.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ After:int = 0
+ Returns:
+ Index:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:AddZProfilePoint 50000 50000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+ global AddZProfilePoint_Response
+ if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+ return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deletes the point from the profile. Returns a number of all and enabled points
+ in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:DeleteZProfilePoint 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+ global DeleteZProfilePoint_Response
+ if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+ return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index="", Status=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ Example:SetZProfilePointStatus 11 E
+ """
+ MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ Example:GetZProfilePointStatus 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ All points are covered by triangles, each vertex of the triangle is a point of
+ the profile. The centers of the triangles are new points of the profile. If all
+ three vertexes of the triangle are tested points the new point will be marked as
+ tested also and has Z value equal to average Z of all three vertexes. Otherwise
+ the new point will be marked as untested. The command returns a number of points
+ in the profile after the update.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:PreciseZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+ return int(rsp[0])
+
+def CloseTableView():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the TableView application.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+ If no Site no is specified the chuck will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+ return int(rsp[0])
+
+def StepChuckSubsite(Site=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+ table view. If no Subsite no. is specified the chuck will step automatically to
+ the next logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+ return int(rsp[0])
+
+def StepScopeSite(Site=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the microscope stage to the requested Site no. of the scope table view. If
+ no Site no is specified the scope will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+ return int(rsp[0])
+
+def StepProbeSite(Probe="", Site=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the specified probe to the requested Site no. of the Probe no table view.
+ If no Site no. is specified the Probe no. will step automatically to the next
+ logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Site:int = -1
+ Returns:
+ ProbeRet:int
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+ global StepProbeSite_Response
+ if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+ return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual chuck site position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+ global ReadChuckSitePosition_Response
+ if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+ return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+ global ReadScopeSitePosition_Response
+ if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+ return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Returns:
+ ProbeRet:int
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+ global ReadProbeSitePosition_Response
+ if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+ return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the chuck subsite position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+ global ReadChuckSubsitePosition_Response
+ if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+ return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins="", RecalcRoute=""):
+ """
+ Steps the chuck to the first die of the wafer map. Returns the row and column
+ number of the actual die location after the move is completed. If ClearBins is
+ 1, all binning data will be cleared from dies. If yes the route will be
+ recalculated. All dies marked to skip during the last test (marked to skip with
+ SetDieStatus) will be eliminated from the route.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ DieX:int
+ DieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+ global StepFirstDie_Response
+ if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+ return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX="", CDieY="", Site=""):
+ """
+ Steps the chuck to the specified x,y die location of the wafer map. If no
+ command data is passed, the chuck automatically steps to the next logical wafer
+ map die location. Returns the row and column number of the actual die location
+ after the move is completed. In addition, the SubDie location, and total number
+ of SubDies is also returned. If Site (i.e. SubDie) is -1, the chuck will move
+ to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+ If sent without parameters, it will literally 'step to the next die'. When using
+ this command from shared code, use SendWithoutParameter().
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+ global StepNextDie_Response
+ if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin="", CDieX="", CDieY=""):
+ """
+ Assigns the bin information to the wafer map at the current die, unless a row
+ and column is specified. Inks the device if the real time inking option (of the
+ wafer map) is enabled.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 30000
+ Example:BinMapDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+ global BinMapDie_Response
+ if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+ return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins=""):
+ """
+ Assigns the pass or fail information to the actual bin value. Redundant to
+ SetBinCode.
+ API Status: published
+ Args:
+ Bins:str = ""
+ Command Timeout: 10000
+ Example:AssignMapBins PFFFFFF
+ """
+ MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+ """
+ Steps the chuck back the number of consecutive failed dies (goes back to the
+ last known good die) and returns the number of consecutive failed dies.
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+ return int(rsp[0])
+
+def StepFailedForward():
+ """
+ Steps the chuck forward the number of consecutive failed dies (goes to next
+ untested die).
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+ return int(rsp[0])
+
+def ReadMapPosition(Pos="", FromPos=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+ the first value is 1, not 0. M_pnCurSite returns the currently selected
+ Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+ ReadMapPosition) has been included for legacy support. ReadMapPosition2 is
+ the preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+ global ReadMapPosition_Response
+ if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+ """
+ Returns the actual wafer map yield data information.
+ API Status: published
+ Returns:
+ TotalDies:int
+ TestedDies:int
+ Passed:int
+ Failed:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+ global ReadMapYield_Response
+ if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+ return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin="", CDieX="", CDieY="", Site=""):
+ """
+ Bins the current die and steps the chuck to the next selected die location of
+ the wafer map (default) or steps to the specified Column and Row position, if
+ these values are passed. In contrast to StepNextDie, the BinStepDie command
+ will only step from die to die while staying on the current subdie. It will not
+ step through the subdies so it cannot be used for subdie stepping.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ Example:BinStepDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+ global BinStepDie_Response
+ if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX="", DieY=""):
+ """
+ If the command has no parameters it sets the current position as home position
+ both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+ home position using the given die coordinates.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName="", FileType=""):
+ """
+ Saves current map file with specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ FileType:str = "m"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode=""):
+ """
+ Enables or disables an external mode for the application. In the external mode,
+ all controls are disabled. The application handles all its remote commands in
+ both modes. Special interactive modes can also be turned on.
+ API Status: published
+ Args:
+ Mode:str = ""
+ Returns:
+ ModeType:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType=""):
+ """
+ Returns whether the application is in external mode or not.
+ API Status: published
+ Args:
+ ModeType:str = ""
+ Returns:
+ Mode:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number=""):
+ """
+ Specifies the wafer number.
+ API Status: published
+ Args:
+ Number:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+ """
+ Returns the wafer number for the current wafer.
+ API Status: published
+ Returns:
+ Number:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+ """
+ Returns the wafer ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID=""):
+ """
+ Specifies the product ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+ """
+ Displays the product ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProductID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+ """
+ Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+ number of dies which were inked during the inker run.
+ API Status: published
+ Returns:
+ InkedDies:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+ return int(rsp[0])
+
+def CloseWaferMap():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Wafer Map application.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+ """
+ Gets the number of dies in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedDies:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+ return int(rsp[0])
+
+def GetSelectedDieCoords(Die=""):
+ """
+ Given the index of a selected die in the range [1..NumSelectedDies], returns the
+ column and row indices for the selected die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+ global GetSelectedDieCoords_Response
+ if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+ return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset="", YOffset="", CDieX="", CDieY=""):
+ """
+ Moves to a user-specified offset within a die. The optional col row params can
+ be used to specify the die. If they are omitted, WaferMap moves to the specified
+ offset within the next selected die.
+ API Status: published
+ Args:
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+ global StepNextDieOffset_Response
+ if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+ return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos="", FromPos=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+ the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+ (0-based) or -1 if no Subdie is currently selected. This command is the
+ preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+ global ReadMapPosition2_Response
+ if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site=""):
+ """
+ Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+ not 1. This command is the preferred method for deleting a selected
+ subdie.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+ return int(rsp[0])
+
+def DeleteAllSubDie():
+ """
+ Deletes all subdies for all dies.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX="", DieY=""):
+ """
+ Returns a label from the wafer map at the current die, unless a row and column
+ are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label="", DieX="", DieY=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a row and column are
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site=""):
+ """
+ Steps the chuck to the specified SubDie number relative to the current die
+ origin of the wafer map. Returns the SubDie number of the actual die location
+ after the move is completed and the total number of subdies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+ global StepNextSubDie_Response
+ if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+ return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName=""):
+ """
+ Opens a Wafer Map file.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result="", DieX="", DieY=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX="", DieY=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result="", DieX="", DieY="", Site=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die and the
+ current subdie, unless a subdie, row, and column are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX="", DieY="", Site=""):
+ """
+ Returns a measurement result from the wafer map at the current die and current
+ subdie, unless a row, column, and subdie are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin="", CDieX="", CDieY="", Site=""):
+ """
+ Assigns the bin information for the current subdie in the current die, unless a
+ subdie, row, and column are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+ global BinSubDie_Response
+ if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site="", X="", Y="", Label=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ X:Decimal
+ Y:Decimal
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+ global GetSubDieData_Response
+ if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+ return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the home die location of the WaferMap.
+ API Status: internal
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+ global GetMapHome_Response
+ if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+ return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+ """
+ Returns the parameters for the current wafer.
+ API Status: published
+ Returns:
+ MapType:str
+ XIndex:Decimal
+ YIndex:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+ global GetMapDims_Response
+ if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+ return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter="", DieWidth="", DieHeight="", FlatLength="", FlatAngle="", XOffset="", YOffset="", EdgeArea=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are percentages.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth="", DieHeight="", Columns="", Rows=""):
+ """
+ Creates the rectangle wafer with specified parameters.
+ API Status: published
+ Args:
+ DieWidth:Decimal = 0
+ DieHeight:Decimal = 0
+ Columns:int = 0
+ Rows:int = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber="", Site=""):
+ """
+ Steps the chuck to the die location specified by the die number of the wafer
+ map. If no command data is passed, the chuck automatically steps to the next
+ logical wafer map die location. Returns the row and column number of the actual
+ die location after the move is completed. In addition, the SubDie location, and
+ total number of SubDies is also returned.
+ API Status: published
+ Args:
+ DieNumber:int = -1
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+ global StepToDie_Response
+ if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift=""):
+ """
+ Returns parameters of the map coordinate system.
+ API Status: published
+ Args:
+ UseOrientationCornerForShift:int = 0
+ Returns:
+ Orientation:int
+ OriginShiftX:int
+ OriginShiftY:int
+ UseAlphas:int
+ UseIOs:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+ global GetMapOrientation_Response
+ if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+ return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation="", OriginShiftX="", OriginShiftY="", UseAlphas="", UseIOs="", UseOrientationCornerForShift=""):
+ """
+ Sets up new map origin and new coordinate system after that.
+ API Status: published
+ Args:
+ Orientation:int = 0
+ OriginShiftX:int = 0
+ OriginShiftY:int = 0
+ UseAlphas:int = 0
+ UseIOs:int = 1
+ UseOrientationCornerForShift:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX="", DieY="", Status=""):
+ """
+ Sets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX="", DieY=""):
+ """
+ Gets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site="", Status=""):
+ """
+ Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+ not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site=""):
+ """
+ Returns the SubDie status. The SubDie collection is 0-based, the first value is
+ 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin=""):
+ """
+ Returns the Die size from the current map.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Returns:
+ Chars:str
+ Color:int
+ Status:str
+ Inker1:int
+ Inker2:int
+ Inker3:int
+ Inker4:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+ global GetBinCode_Response
+ if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+ return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin="", Chars="", Color="", Status="", Inker1="", Inker2="", Inker3="", Inker4=""):
+ """
+ Appends the Bin information to a bin code.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Chars:str = ""
+ Color:int = 0
+ Status:str = ""
+ Inker1:int = 0
+ Inker2:int = 0
+ Inker3:int = 0
+ Inker4:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Number is absent it uses the current die
+ on the wafer.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+ global GetDieDataAsNum_Response
+ if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+ return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex="", Bin="", Result=""):
+ """
+ Sets the Die Information. If the Die Number is invalid it returns an error.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex="", Site=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+ global GetSubDieDataAsNum_Response
+ if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+ return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex="", Site="", Bin="", Result=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX="", CDieY=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Column and Row are absent it uses the
+ current die on the wafer.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+ global GetDieDataAsColRow_Response
+ if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+ return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX="", DieY="", Bin="", Result=""):
+ """
+ Sets the Data in the Row Column format. If the Die is invalid it returns an
+ error.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX="", CDieY="", Site=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+ global GetSubDieDataAsColRow_Response
+ if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+ return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX="", DieY="", Site="", Bin="", Result=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll="", DoEdgeDies=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables all dies.
+ API Status: internal
+ Args:
+ DoSelectAll:int = 0
+ DoEdgeDies:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current WaferMap Filename.
+ API Status: internal
+ Returns:
+ Name:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapName")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+ """
+ Returns the Lot ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLotID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins="", RecalcRoute=""):
+ """
+ Steps the chuck to the first die cluster of the cluster map. If clusters are not
+ defined, the first Die is used. Returns the row and column information of the
+ actual cluster and die location after the move is completed. Switches to remote
+ control if the "Disable Velox" flag is set in the external options window.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+ global StepFirstCluster_Response
+ if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX="", CClusterY=""):
+ """
+ Steps the chuck to the specified x,y cluster die location of the cluster map. If
+ no command data is passed, the chuck automatically steps to the next logical
+ cluster map location. If clusters are not defined, the Die information is used.
+ Returns the row and column number of the actual die location after the move is
+ completed.
+ API Status: published
+ Args:
+ CClusterX:int = 0
+ CClusterY:int = 0
+ Returns:
+ RClusterX:int
+ RClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+ global StepNextCluster_Response
+ if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode="", StartColumn="", StartRow="", MoveParam=""):
+ """
+ Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+ is done for the shortest move way for the station.
+ API Status: published
+ Args:
+ MoveMode:str = "B"
+ StartColumn:str = "L"
+ StartRow:str = "T"
+ MoveParam:str = "H"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+ """
+ Returns the specified move path for the probe station inside the Wafer Map.
+ API Status: published
+ Returns:
+ MoveMode:str
+ StartColumn:str
+ StartRow:str
+ MoveParam:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+ global GetMapRoute_Response
+ if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+ return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters="", ClusterWidth="", ClusterHeight="", TestIncomplete=""):
+ """
+ Specifies the clusters parameters.
+ API Status: published
+ Args:
+ UseClusters:int = 0
+ ClusterWidth:int = 1
+ ClusterHeight:int = 1
+ TestIncomplete:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+ """
+ Returns current clusters parameters.
+ API Status: published
+ Returns:
+ UseClusters:int
+ ClusterWidth:int
+ ClusterHeight:int
+ TestIncomplete:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+ global GetClusterParams_Response
+ if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+ return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+ """
+ Deletes current wafer map, sub dies and binning information; then creates new
+ wafer map with defaults parameters.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X="", Y="", Label=""):
+ """
+ Adds new subdie at the end of the table.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+ return int(rsp[0])
+
+def DeleteSubDie(Site=""):
+ """
+ Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+ not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+ for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+ support. DeleteSubDie2 is the preferred method for deleting a selected
+ subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+ dies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+ return int(rsp[0])
+
+def GetNumSelectedClusters():
+ """
+ Gets the number of clusters in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedClusters:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+ return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex=""):
+ """
+ Given the index of a selected cluster in the range [1..NumSelectedClusters],
+ returns the column and row indices for the selected cluster.
+ API Status: published
+ Args:
+ ClusterIndex:int = 0
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+ global GetSelectedClusterCoords_Response
+ if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+ return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX="", ClusterY="", DieX="", DieY=""):
+ """
+ Gets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX="", ClusterY="", DieX="", DieY="", Status=""):
+ """
+ Sets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName=""):
+ """
+ Opens a Bin Code Table file (.bct) with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName=""):
+ """
+ Saves bin code table to a file with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize=""):
+ """
+ Sets size of the bin code table. This is the size of bins used in statistics and
+ binning.
+ API Status: published
+ Args:
+ BinsSize:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+ """
+ Gets size of the bin code table.
+ API Status: published
+ Returns:
+ BinsSize:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+ return int(rsp[0])
+
+def StepFailedClusterBack():
+ """
+ Steps the chuck the consecutive failed clusters back (goes back to the last
+ known good cluster) and returns the number of consecutive failed clusters.
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+ return int(rsp[0])
+
+def StepFailedClusterForward():
+ """
+ Steps the chuck the consecutive failed clusters forward and returns the number
+ of consecutive failed clusters (goes to next untested cluster).
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+ return int(rsp[0])
+
+def GoToWaferHome():
+ """
+ Moves the chuck to the wafer home position.
+ API Status: published
+ Command Timeout: 6000000
+ """
+ MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+ """
+ Returns a number of all units marked to test. Note that TestSites is a number of
+ all sites for all dies.
+ API Status: published
+ Returns:
+ ClustersCount:int
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+ global GetWaferInfo_Response
+ if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+ return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster=""):
+ """
+ Returns a number of all dies and sites marked to test in the given cluster.
+ API Status: published
+ Args:
+ Cluster:int = 0
+ Returns:
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+ global GetClusterInfo_Response
+ if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+ return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die=""):
+ """
+ Returns a number of sites marked to test in the given die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+ return int(rsp[0])
+
+def ConvertToAlphas(Start="", Finish=""):
+ """
+ Returns a string of the alpha column coordinates for the given range divided by
+ spaces.
+ API Status: published
+ Args:
+ Start:int = 0
+ Finish:int = 0
+ Returns:
+ Alphas:str
+ Command Timeout: 240000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer=""):
+ """
+ Sets new active layer.
+ API Status: published
+ Args:
+ Layer:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+ """
+ Returns current active layer.
+ API Status: published
+ Returns:
+ Layer:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX="", RefY=""):
+ """
+ Sets a new reference point for the die. This point is NOT used for die stepping,
+ nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+ GUI setting, the Die Reference Point can be set to be more representative of the
+ actual reference location within the die. A setting of (0.0, 0.0) is defined as
+ the upper left corner of the die. All subdie coordinates are relative to upper
+ left corner of the die.
+ API Status: published
+ Args:
+ RefX:Decimal = 0
+ RefY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+ """
+ Returns current reference point for the die. For details see SetDieRefPoint
+ command.
+ API Status: published
+ Returns:
+ RefX:Decimal
+ RefY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+ global GetDieRefPoint_Response
+ if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+ return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+ """
+ Clears all binning data in the wafer map.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State="", Window=""):
+ """
+ Has sense in the application only (not for ActiveX controls). It shows or hides
+ a window. All parameters are case-insensitive.
+ API Status: published
+ Args:
+ State:str = "s"
+ Window:str = "setup"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin="", ButtonStatus=""):
+ """
+ Sets the current bin for the application. Second parameter allows to enable or
+ disable "Mark with Bin" mode in the application.
+ API Status: published
+ Args:
+ Bin:int = 0
+ ButtonStatus:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+ """
+ Returns the current bin in the application.
+ API Status: published
+ Returns:
+ Bin:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+ return int(rsp[0])
+
+def ReadClusterPosition(Pos="", FromPos=""):
+ """
+ Returns the actual wafer map cluster position. If the cluster probing is
+ disabled, the command will assume a cluster of size 1x1.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ ClusterWidth:int
+ ClusterHeight:int
+ EnabledDies:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+ global ReadClusterPosition_Response
+ if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+ return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are percentages.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+ global GetWaferMapParams_Response
+ if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+ """
+ Creates a rectangular wafermap with specified parameters.
+ API Status: published
+ Returns:
+ DieWidth:Decimal
+ DieHeight:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+ global GetRectMapParams_Response
+ if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+ return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X="", Y=""):
+ """
+ Tries to find an appropriate position in the wafer for the current chuck
+ position. X and Y describe the chuck position of the wafer center relatively to
+ the chuck zero position. If the wafer position is found the command sets it as
+ the wafer map home position and sets the current chuck position as the chuck
+ home position. If there is no corresponding wafer position the command returns
+ error 701. Command is used by AutoAlign for the BuildMap feature.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor="", SearchSpeed="", Gap="", SuccessRatio="", ProfDistX="", ProfDistY=""):
+ """
+ Sets some WaferMap profiling options remotely.
+ API Status: published
+ Args:
+ ProfileSensor:str = "e"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ SuccessRatio:Decimal = 75
+ ProfDistX:Decimal = 0
+ ProfDistY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+ """
+ Returns predefined settings of the WaferMap profiling options.
+ API Status: published
+ Returns:
+ ProfileSensor:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ SuccessRatio:Decimal
+ ProfDistX:Decimal
+ ProfDistY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+ global GetWaferProfileOptions_Response
+ if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+ return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue=""):
+ """
+ Starts the profiling process. To determine the current profiling state, use
+ GetWaferProfilingStatus command.
+ API Status: published
+ Args:
+ DoContinue:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+ """
+ Returns status of the profiling process. If this status is true, the process is
+ started.
+ API Status: published
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+ return int(rsp[0])
+
+def StopWaferProfiling():
+ """
+ Stops the profiling process.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+ """
+ Profiles the wafer and returns a status of the profiling as an error code.
+ API Status: published
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Profiles the wafer and returns a status of the profiling as an error code.
+ Executes profiling using the off axis camera
+ API Status: internal
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX="", DieY="", Site=""):
+ """
+ Returns a label from the wafer map at the current die and current subdie, unless
+ a row, column, and subdie are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label="", DieX="", DieY="", Site=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, row, and column are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex="", Site=""):
+ """
+ Returns a label from the wafer map the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label="", CDieIndex="", Site=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex=""):
+ """
+ Returns a label from the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label="", CDieIndex=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the XY offset from the reference position of the Home Die to wafer
+ center in chuck coordinates.
+ API Status: internal
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+ global GetHomeDieOffset_Response
+ if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+ return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter="", DieWidth="", DieHeight="", FlatLength="", FlatAngle="", XOffset="", YOffset="", EdgeArea=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are microns.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are microns.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+ global GetWaferMapParams2_Response
+ if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle=""):
+ """
+ This command sets the Wafer Test Angle. This is different from the notch angle
+ and allows rotating the WaferMap.
+ API Status: published
+ Args:
+ Angle:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+ """
+ This returns the Wafer Test Angle. This is different from the notch angle and
+ allows rotating the WaferMap.
+ API Status: published
+ Returns:
+ Angle:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+ return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName="", ClearMap=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads the Pre-Mapped Dies Table file with specified name.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ ClearMap:int = 1
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX="", DieY=""):
+ """
+ This command is valid when a PreMapped Dies Table has been loaded. Returns
+ values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+ specified. Returns actual (as measured during the Pre-Mapping) x, y, z, and
+ theta die positions. Also returns whether or not Z and Theta are being used.
+ This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+ PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+ returned.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ UseZ:int
+ UseTheta:int
+ ActualX:Decimal
+ ActualY:Decimal
+ ActualZ:Decimal
+ Theta:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+ global GetPreMappedDieInfo_Response
+ if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+ return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result="", CDieIndex=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex="", Site=""):
+ """
+ Returns a measurement result from the wafer map the current die and the current
+ subdie, unless a subdie, and die number are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result="", CDieIndex="", Site=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die at the
+ current subdie, unless a subdie, and die number are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables edge dies for test
+ API Status: internal
+ Args:
+ Enable:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows access to read any data item in Spectrum explorer. GetSpectrumData
+ AlignWafer/ProjectData/Mark1/ChuckPosition/X GetSpectrumData Chuck
+ Camera/Camera Settings/Shutter
+ API Status: internal
+ Args:
+ DataPath:str = ""
+ Returns:
+ Value:str
+ Command Timeout: 6000
+ Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows changing any data item in Spectrum explorer. Works independent of access
+ level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+ SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+ API Status: internal
+ Args:
+ PathAndValue:str = ""
+ Command Timeout: 6000
+ Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName="", XY="", Z="", Model=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the current chuck and microscope position and sets them as
+ new controller or chuck and microscope positions. The command was originally used
+ by ReAlignWizard but may be removed in the future because of direct access to
+ tooldata within Spectrum.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XY:int = 1
+ Z:int = 0
+ Model:int = -1
+ Command Timeout: 60000
+ Example:ReadVMPosition AlignWafer 1 0 0
+ """
+ MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName="", XYChuck="", ZChuck="", XYScope="", ZScope="", Model=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command moves to trained stages positions of a requested tool. Command is
+ used by ReAlignWizard to move to the trained positions for AutoAlign and
+ DetectWaferHeight.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XYChuck:int = 1
+ ZChuck:int = 1
+ XYScope:int = 0
+ ZScope:int = 0
+ Model:int = -1
+ Command Timeout: 120000
+ Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+ """
+ MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome="", AutoEdgeFind="", FileName=""):
+ """
+ ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+ to determine the contour of it. The data will be memorized as xy coordinates of
+ contour points referenced to the home position. These Points are written to a
+ file after tracking the shape.
+ API Status: published
+ Args:
+ SetHome:int = 1
+ AutoEdgeFind:int = 0
+ FileName:str = ""
+ Command Timeout: 600000
+ Example:ShapeTracker 1
+ """
+ MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition="", Synchronize="", ChuckX="", ChuckY=""):
+ """
+ Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+ focused on the trained chuck position or the manual adjusted reference position.
+ This tool uses the FindFocus tool with its own Range.
+ API Status: published
+ Args:
+ SetStartPosition:int = 0
+ Synchronize:int = 0
+ ChuckX:Decimal = -1
+ ChuckY:Decimal = -1
+ Returns:
+ PositionX:Decimal
+ PositionY:Decimal
+ WaferHeight:Decimal
+ SynchGap:Decimal
+ ZOffset:Decimal
+ Stage:str
+ Command Timeout: 300000
+ Example:DetectWaferHeight 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+ global DetectWaferHeight_Response
+ if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+ return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command checks if a plugin is trained and returns a string of error/warning
+ messages including information about what is not trained, setup for the tool to
+ run.
+ API Status: internal
+ Args:
+ Plugin:str = ""
+ Returns:
+ PluginAvailable:int
+ Message:str
+ Command Timeout: 1000
+ Example:CheckSpectrumPlugin AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+ global CheckSpectrumPlugin_Response
+ if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+ return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue="", SkipSettingHome=""):
+ """
+ Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+ index calculation or thermal expansion measurement. The command will update home
+ if home was trained. It will only move to its trained chuck/scope position
+ before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+ "MoveToTrainedZPosition" is true.
+ API Status: published
+ Args:
+ SetValue:int = 0
+ SkipSettingHome:int = 0
+ Command Timeout: 300000
+ Example:AutoAlign 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active=""):
+ """
+ Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+ SPS300/SUMMIT200 stations.) The camera quiet mode deactivates the chuck,
+ platen and contact view camera and triggers a digital output which
+ connects/disconnects these cameras firewire connection to the PC.
+ API Status: published
+ Args:
+ Active:int = 0
+ Command Timeout: 30000
+ Example:SetCameraQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol="", RefDieRow="", RefDieDistToCentreX="", RefDieDistToCentreY=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is based on the SetMapOrientation command. It allows shifting the
+ center of the reference die to the center of the wafer.
+ API Status: internal
+ Args:
+ RefDieCol:int = 0
+ RefDieRow:int = 0
+ RefDieDistToCentreX:Decimal = 0
+ RefDieDistToCentreY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition=""):
+ """
+ Performs a two-point alignment and moves chuck to the trained align position. XY
+ correction is made afterwards to calculate the new home position.
+ API Status: published
+ Args:
+ TrackPosition:int = 0
+ Returns:
+ ThetaOffset:Decimal
+ Command Timeout: 120000
+ Example:AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+ return Decimal(rsp[0])
+
+def AlignChip():
+ """
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). The
+ current chip is assumed to be in the region of interest when the command is
+ called.
+ API Status: published
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChip
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChip")
+ global AlignChip_Response
+ if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount="", Range=""):
+ """
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search.
+ API Status: published
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocus 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+ global FindFocus_Response
+ if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+ return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID=""):
+ """
+ Performs an automated aux site alignment in XYZ. Tool can correct reference
+ position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAux 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model="", ReturnDistanceFromModelOrigin="", UseSingleImageAcquisition=""):
+ """
+ Search user-defined models. Up to 40 different models can be trained. After
+ training, these models can be searched on screen either by direct user
+ interaction or from external applications with a remote command. The remote
+ command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+ each instance of the controller found in the region of interest.
+ API Status: published
+ Args:
+ Model:int = 1
+ ReturnDistanceFromModelOrigin:int = 0
+ UseSingleImageAcquisition:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 10000
+ Example:FindFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+ during Project loading. Does save configuration data but does not save project
+ data.
+ API Status: internal
+ Command Timeout: 6000
+ Example:CloseSpectrum
+ """
+ MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos="", FullPath="", SnapShotMode=""):
+ """
+ Saves the currently displayed image to the specified file. The image is stored
+ in the requested file format (bmp, jpg or png). By default. it will save the raw
+ camera image and an image with the overlays that are currently visible on the
+ camera view. Using a parameter, one can decide to only save either raw image,
+ overlay image or both. By Specifying 'ALL' as the mount position, the captured
+ screenshot will consist of the currently selected camera layout without
+ providing the raw image. If MountPos and FullPath are empty then the current
+ camera view with overlays is copied to the clipboard.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ FullPath:str = "Image.bmp"
+ SnapShotMode:int = 2
+ Command Timeout: 60000
+ Example:SnapImage Scope C:/Temp/Image.bmp
+ """
+ MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name="", Zoom="", LiveVideo="", WindowState=""):
+ """
+ Switches the desired video window of Spectrum as foreground and active view. The
+ camera view can be determined over a tool name or the camera mount position. The
+ second parameter defines the displays zoom factor to be used. Third parameter is
+ used to toogle the live video. Last parameter can be used to maximize a window.
+ API Status: published
+ Args:
+ Name:str = ""
+ Zoom:int = 0
+ LiveVideo:int = 2
+ WindowState:int = 1
+ Command Timeout: 6000
+ Example:SetCameraView AlignWafer 0 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name="", State="", Shutter="", Gain="", Brightness="", Contrast="", Sharpness="", Illumination=""):
+ """
+ Switches the light of the choosen camera on or off. Light values of -1 will
+ cause that the parameter is not affected.
+ API Status: published
+ Args:
+ Name:str = ""
+ State:int = 0
+ Shutter:Decimal = -1
+ Gain:Decimal = -1
+ Brightness:int = -1
+ Contrast:int = -1
+ Sharpness:int = -1
+ Illumination:int = -1
+ Command Timeout: 6000
+ Example:SetCameraLight AlignWafer 1 20 5
+ """
+ MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName="", MountPosition="", AskExecute=""):
+ """
+ Starts the wizard of a given tool on the display defined in the tool settings.
+ Additionally it can start a wizard for training single models with the syntax
+ e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+ MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+ e.g. ShowWizard Calibrate Platen
+ API Status: published
+ Args:
+ ToolName:str = ""
+ MountPosition:str = ""
+ AskExecute:int = 0
+ Returns:
+ Cancelled:int
+ Command Timeout: 10000000
+ Example:ShowWizard AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+ return int(rsp[0])
+
+def ProbeToPadAlign(Position=""):
+ """
+ Sets a new Home position. The command is used during ReAlign to search the
+ trained home reference controller and to calculate the new xy home position.
+ API Status: published
+ Args:
+ Position:str = "H"
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ Command Timeout: 120000
+ Example:ProbeToPadAlign H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+ global ProbeToPadAlign_Response
+ if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+ return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+ """
+ Reads the wafer ID string from the wafer's surface. Returns the read ID as
+ string. Requires IDTools license.
+ API Status: published
+ Returns:
+ OcrString:str
+ Command Timeout: 60000
+ Example:ReadOcrString
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+ """
+ Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+ API Status: published
+ Returns:
+ BarCodeString:str
+ Command Timeout: 60000
+ Example:ReadBarCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+ """
+ Reads the wafers matrix code and decodes it to a string. Requires IDTools
+ license.
+ API Status: published
+ Returns:
+ MatrixCodeString:str
+ Command Timeout: 60000
+ Example:Read2DMatrixCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the Spectrum remote mode. In this mode all user interface elements are
+ hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+ API Status: internal
+ Args:
+ Activate:int = 1
+ Command Timeout: 10000
+ Example:SetSpectrumRemote 1
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name=""):
+ """
+ Returns light properties of choosen camera.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ State:int
+ Shutter:Decimal
+ Gain:Decimal
+ Brightness:int
+ Contrast:int
+ Sharpness:int
+ Illumination:int
+ Command Timeout: 6000
+ Example:GetCameraLight Scope
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+ global GetCameraLight_Response
+ if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+ return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name=""):
+ """
+ Returns the present camera view state of a desired tool or active view.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ Zoom:int
+ LiveVideo:int
+ WindowState:int
+ Command Timeout: 6000
+ Example:GetCameraView AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+ global GetCameraView_Response
+ if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+ return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName="", ModelName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+ be stored in the same folder as the project file. The command was originally
+ required by ReAlignWizard and is currently no longer in use.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ ModelName:str = ""
+ Returns:
+ BitmapPath:str
+ Command Timeout: 30000
+ Example:GetPattern AlignWafer Model1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition="", DistPositionX="", DistPositionY=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the ChuckCenter under a given camera. When no camera mount position is
+ given, Spectrum uses active view. If there is an Offset different from zero,
+ this position will be moved under the camera.
+ API Status: internal
+ Args:
+ MountPosition:str = ""
+ DistPositionX:Decimal = 0
+ DistPositionY:Decimal = 0
+ Command Timeout: 60000
+ Example:ShowPosition Scope
+ """
+ MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the home die coordinates when the home die is under the alignment camera
+ (for instance, the top camera). Command was used during TrainReAlign to get
+ the start position for Z-Profiling. Command is no longer used.
+ API Status: internal
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 6000
+ Example:GetCameraHomePosition
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+ global GetCameraHomePosition_Response
+ if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+ return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos="", SynchronizeXY="", SynchronizeZ=""):
+ """
+ Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+ the chuck camera. The chuck must be moved to get the mark in view of the
+ specified camera.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ SynchronizeXY:int = 0
+ SynchronizeZ:int = 0
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 120000
+ Example:SynchronizeCamera S 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+ global SynchronizeCamera_Response
+ if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+ return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ="", MeasureBothGroups=""):
+ """
+ Determines the chuck XYZ axis position where the needles of the probe card are
+ in focus. The output parameter is the Z axis value in microns from zero of the
+ new focus height.
+ API Status: published
+ Args:
+ UpdateZ:int = 1
+ MeasureBothGroups:int = 1
+ Returns:
+ ZPosition:Decimal
+ Command Timeout: 360000
+ Example:ProbeCardOCS 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+ return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition="", YPosition="", XSubsiteOffset="", YSubsiteOffset=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+ move. Automation must be activated/trained before command can be used. Response
+ is X, Y relative distance of adjustment from requested position.
+ API Status: internal
+ Args:
+ XPosition:Decimal = 0
+ YPosition:Decimal = 0
+ XSubsiteOffset:Decimal = 0
+ YSubsiteOffset:Decimal = 0
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:MoveChuckAutoXY 5000 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+ global MoveChuckAutoXY_Response
+ if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+ return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign=""):
+ """
+ Alignment for the next wafer when using VueTrack.
+ API Status: published
+ Args:
+ FullVueTrackAlign:int = 1
+ Command Timeout: 6000000
+ Example:VueTrackAlign
+ """
+ MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow="", DistAbove="", XOffsetCenter="", YOffsetCenter=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is only used internally for software testing and for providing backwards
+ compatibility with SCPI legacy commands. It executes a focus search using the
+ eVue focus drive.
+ API Status: internal
+ Args:
+ DistBelow:Decimal = 0
+ DistAbove:Decimal = 0
+ XOffsetCenter:int = 0
+ YOffsetCenter:int = 0
+ Returns:
+ FocusScore:Decimal
+ ZPosition:Decimal
+ Command Timeout: 30000
+ Example:AutoFocusEVue 200 200 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+ global AutoFocusEVue_Response
+ if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+ return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+ with optional index calculation or thermal expansion measurement. AutoAlign is
+ performed using the Platen camera. Only supported for systems with off-axis
+ camera.
+ API Status: internal
+ Args:
+ SetValue:int = 0
+ Command Timeout: 300000
+ Example:AutoAlignOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount="", Range=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Focus search is performed using the Platen camera. Only supported for
+ systems with off-axis camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusOffAxis 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+ global FindFocusOffAxis_Response
+ if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+ return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID=""):
+ """
+ Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+ can correct reference position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAuxOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount="", Range=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Uses the FindFocus tool settings but always the Platen camera -
+ independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+ that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+ have an upward looking camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusPlaten 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+ global FindFocusPlaten_Response
+ if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+ return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). This
+ command is using the off axis platen camera with functionality of ReAlign.
+ API Status: internal
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChipOffAxis
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+ global AlignChipOffAxis_Response
+ if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens=""):
+ """
+ Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:SelectAZoomLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+ """
+ Returns 1 of 4 symbolic lenses, coarse ranges.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:GetAZoomLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+ return int(rsp[0])
+
+def AZoomSetupDialog():
+ """
+ Opens the operator panel. In this window you can change the settings for all
+ defined lenses.
+ API Status: published
+ Command Timeout: 5000
+ Example:AZoomSetupDialog
+ """
+ MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus="", Ref=""):
+ """
+ Changes the focus magnitude.
+ API Status: published
+ Args:
+ Focus:int = 100
+ Ref:str = "R"
+ Returns:
+ RetFocus:int
+ Command Timeout: 10000
+ Example:MoveAZoomFocus 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+ return int(rsp[0])
+
+def ReadAZoomFocus():
+ """
+ Returns the focus magnitude.
+ API Status: published
+ Returns:
+ Focus:int
+ Command Timeout: 5000
+ Example:ReadAZoomFocus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+ return int(rsp[0])
+
+def MoveAZoomVelocity(Direction="", Velocity=""):
+ """
+ Moves the A-Zoom using the set focus speed.
+ API Status: published
+ Args:
+ Direction:str = ""
+ Velocity:int = 100
+ Returns:
+ RetVelocity:Decimal
+ Command Timeout: 240000
+ Example:MoveAZoomVelocity + 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+ return Decimal(rsp[0])
+
+def StopAZoom():
+ """
+ Stops the A-Zoom movements.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAZoom
+ """
+ MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light=""):
+ """
+ Switches all lights ON or OFF. ON means the values defined by the current lens.
+ 1 switches the light on, 0 switches the light off. Without parameter toggles
+ between on an off.
+ API Status: published
+ Args:
+ Light:int = 0
+ Command Timeout: 5000
+ Example:SetAZoomLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the OpticalControl application. Used during Project File handling.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseAZoom
+ """
+ MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value="", Channel="", Segment=""):
+ """
+ Set the brightness of given channel and segment to the given value.
+ API Status: published
+ Args:
+ Value:int = 0
+ Channel:int = 1
+ Segment:int = 1
+ Command Timeout: 5000
+ Example:OCLightVal 128 1 4
+ """
+ MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On="", Channel=""):
+ """
+ Switch the light (if it has segments then all) in a given channel ON or OFF.
+ Switch ON - that means: light to the before adjusted brightness.
+ API Status: published
+ Args:
+ On:int = 0
+ Channel:int = 1
+ Command Timeout: 5000
+ Example:OCLightOn 1 1
+ """
+ MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom="", Motor=""):
+ """
+ Set logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Zoom:int = 0
+ Motor:int = 1
+ Command Timeout: 5000
+ Example:OCSetZoomLevel 50 1
+ """
+ MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor=""):
+ """
+ Get logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Motor:int = 1
+ Returns:
+ Zoom:int
+ Command Timeout: 5000
+ Example:OCGetZoomLevel 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+ return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature="", ThetaAlignOnFinish="", ContactOnFinish=""):
+ """
+ Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+ wafer during ramping to the new target temperature. Command returns immediately.
+ The status of temperature ramping must be checked using the
+ GetReAlignTemperatureStatus command.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ Command Timeout: 5000
+ Example:StartReAlignTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+ """
+ Stops temperature ramping using ReAlign.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopReAlignTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using ReAlign process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetReAlignTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+ global GetReAlignTemperatureStatus_Response
+ if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats="", Mode="", AlignProbeCard="", CorrectZ=""):
+ """
+ Performs an automatic realignment of the wafer. This includes measuring the
+ needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+ drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+ ProbeToDie Alignment to correct the needle position for the current die. Command
+ returns once ReAlign is finished or aborted because of an error.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ ZOffsetWafer:Decimal
+ XOffsetCard:Decimal
+ YOffsetCard:Decimal
+ ZOffsetCard:Decimal
+ Command Timeout: 1000000
+ Example:ReAlign 2 H 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+ global ReAlign_Response
+ if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+ return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+ """
+ Starts the NextWafer routine.
+ API Status: published
+ Returns:
+ Canceled:int
+ Command Timeout: 60000000
+ Example:NextWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("NextWafer")
+ return int(rsp[0])
+
+def StartReAlign(Repeats="", Mode="", AlignProbeCard="", CorrectZ=""):
+ """
+ Starts an automatic realignment of the wafer. This includes measuring the needle
+ drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+ XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+ Alignment to correct the needle position for the current die. Command returns
+ immediately. The status of the asynchronous ReAlign execution must be checked
+ using the GetReAlignStatus command.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Command Timeout: 60000
+ Example:StartReAlign 2 H 0 0
+ """
+ MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+ """
+ Stops the ReAlign procedure.
+ API Status: published
+ Command Timeout: 120000
+ Example:StopReAlign
+ """
+ MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+ """
+ Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+ is running.
+ API Status: published
+ Returns:
+ Running:int
+ Command Timeout: 60000
+ Example:GetReAlignStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+ return int(rsp[0])
+
+def EnableOverlay(Overlay=""):
+ """
+ Allows activating the overlay of the needles for the top camera.
+ API Status: published
+ Args:
+ Overlay:int = 0
+ Command Timeout: 6000
+ Example:EnableOverlay 0
+ """
+ MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Switches the offset compensation. Applicable for MicroAlign stations only.
+ API Status: internal
+ Args:
+ Offset:int = 0
+ Command Timeout: 60000
+ Example:SwitchOffset 1
+ """
+ MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command was only implemented for supporting a SCPI legacy command. Does not make
+ sense in Velox, as there is no default training rectangle on the screen as in
+ Nucleus.
+ API Status: internal
+ Args:
+ Model:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 30000
+ Example:TrainFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Returns:
+ Exposure:Decimal
+ Command Timeout: 10000
+ Example:GetEvueExposureLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+ return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Args:
+ Exposure:Decimal = 0
+ Command Timeout: 10000
+ Example:SetEvueExposureLevel
+ """
+ MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ="", EvueVelocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the eVue focus stage to a specified position. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ EvueZ:Decimal = 0
+ EvueVelocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveEvueFocusStage 1000
+ """
+ MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the eVue focus stage. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Returns:
+ EvueZ:Decimal
+ Command Timeout: 5000
+ Example:GetEvueFocusStagePos
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+ return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command runs the AutoExpose function for the eVue. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ UseCB:int = 1
+ Command Timeout: 20000
+ Example:RunEvueAutoExpose 1
+ """
+ MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope that is connected to Velox. On eVue
+ systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+ and 0.5 to 20.0 for a 40x system.
+ API Status: internal
+ Returns:
+ Zoom:Decimal
+ Command Timeout: 5000
+ Example:GetEvueZoomLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+ return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+ Velox. On eVue systems, this command sets the proper CCD zoom level to the
+ appropriate optical path.
+ API Status: internal
+ Args:
+ Zoom:Decimal = 0
+ Command Timeout: 5000
+ Example:SetEvueZoomLevel 2.0
+ """
+ MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature="", ThetaAlignOnFinish="", ContactOnFinish="", AlignOnFinish=""):
+ """
+ Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+ will re-adjust the probes and wafer during ramping to the new target
+ temperature.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ AlignOnFinish:int = 1
+ Command Timeout: 5000
+ Example:StartAutomationTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+ """
+ Stops temperature ramping using Automation.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopAutomationTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetAutomationTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+ global GetAutomationTemperatureStatus_Response
+ if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+ """
+ Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+ active. Command is used by WaferMap to read if it must send MoveChuckAutoXY
+ instead of MoveChuck
+ API Status: published
+ Returns:
+ Active:int
+ Command Timeout: 1000
+ Example:GetAutomationActive
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+ return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex="", MoveScope=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ VueTrack vision search of the given needle index.
+ API Status: internal
+ Args:
+ NeedleIndex:int = 1
+ MoveScope:int = 1
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ ZMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationNeedleSearch 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+ global AutomationNeedleSearch_Response
+ if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+ return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ AutomationReferenceSearch exposes the functionality of searching the Automation
+ reference target via remote command
+ API Status: internal
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationReferenceSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+ global AutomationReferenceSearch_Response
+ if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+ return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the configured motorized positioners to a safe position
+ API Status: internal
+ Command Timeout: 60000
+ Example:MovePositionersSafe
+ """
+ MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn="", ForceLastCorrection=""):
+ """
+ Starts Constant Contact mode using Automation. The Automation will re-adjust the
+ wafer during ramping to the new target temperature.
+ API Status: published
+ Args:
+ IsOn:int = 0
+ ForceLastCorrection:int = 0
+ Command Timeout: 5000
+ Example:SetConstantContactMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+ """
+ Returns the status of the current ConstantContact automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 5000
+ Example:GetConstantContactModeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+ global GetConstantContactModeStatus_Response
+ if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+ return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate=""):
+ """
+ Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+ be used to e.g. deactivate automation programmatically in case it is no
+ longer used. When activating automation, the command will return an error in
+ case it is not possible (e.g. not trained)
+ API Status: published
+ Args:
+ Activate:int = 0
+ Command Timeout: 1000
+ Example:SetAutomationActive 1
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+ """
+ Performs an Automation search and position correction using the current chuck
+ position. Response is X, Y relative distance of adjustment.
+ API Status: published
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:AutomationSearchCurrentDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+ global AutomationSearchCurrentDie_Response
+ if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+ return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+ """
+ PreMapWafer finds actual singulated die locations and updates positions used by
+ WaferMap.
+ API Status: published
+ Returns:
+ NumberOfDies:int
+ Command Timeout: 14400000
+ Example:PreMapWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+ return int(rsp[0])
+
+def ISSProbeAlign():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs an probe to pad operation on the ISS with two RF positioners.
+ API Status: internal
+ Command Timeout: 6000000
+ Example:ISSProbeAlign
+ """
+ MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery=""):
+ """
+ FindWaferCenter finds the center of the wafer using edge detection.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:FindWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+ global FindWaferCenter_Response
+ if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+ return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery=""):
+ """
+ LocateHomeDie finds the center of the wafer using edge detection and sets the
+ home position.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:LocateHomeDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+ global LocateHomeDie_Response
+ if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+ return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName="", ProbeID="", XOffset="", YOffset=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stores the provided X or Y offset for the given probe for the specified layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Command Timeout: 10000
+ Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName="", ProbeID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+ If optional ProbeID parmameter is set, it removes just that probe from the
+ layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 10000
+ Example:DeleteAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName="", ProbeID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+ just that probe from the layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 30000
+ Example:CaptureAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move to the probes to specfied layout which are offsets from the trained
+ positions.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ Command Timeout: 300000
+ Example:MoveToAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+ """
+ Reset automation data back to trained values.
+ API Status: published
+ Command Timeout: 10000
+ Example:ResetAutomation
+ """
+ MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+ """
+ GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+ returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+ API Status: published
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 10000
+ Example:GetWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+ global GetWaferCenter_Response
+ if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+ return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the eVue focus stage by finding the limit switches
+ API Status: internal
+ Command Timeout: 30000
+ Example:InitEvueFocusStage
+ """
+ MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Args:
+ NumTraceEntriesPreTrigger:int = 0
+ Command Timeout: 30000
+ Example:EvueSetNumTraceEntriesPreTrigger 14
+ """
+ MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Returns:
+ NumTraceEntriesPreTrigger:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntriesPreTrigger
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+ return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts capturing events in the eVue motion capture log. Capture continues until
+ the log is full. However, log entries will overwrite the oldest entry until the
+ trigger event is encountered. Then, {X} events are preserved prior to the
+ trigger event and the oldest events are only overwritten if they are not part of
+ that preserved set.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EvueStartCaptureServoTrace
+ """
+ MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+ 16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+ trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+ stopped on requested server state entry bit4 - stopped by immediate command
+ bit5..31 - reserved
+ API Status: internal
+ Returns:
+ TraceMachineStatus:int
+ Command Timeout: 30000
+ Example:EvueGetTraceMachineStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+ return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+ bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+ lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+ stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+ an index but the 4-bit state that, if seen, is the trigger for trace capture)
+ bit8..31 - reserved
+ API Status: internal
+ Args:
+ TraceCaptureStopBits:int = 0
+ Command Timeout: 30000
+ Example:EvueSetTraceCaptureStopBits
+ """
+ MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current status of the trace machine.
+ API Status: internal
+ Returns:
+ TraceEntries:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntries
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+ return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the N'th trace entry in the log.
+ API Status: internal
+ Args:
+ EntryIdx:int = 0
+ Returns:
+ CommandedPositionMotorCounts:int
+ CommandedPositionMicrons:Decimal
+ MeasuredPositionMotorCounts:int
+ MeasuredPositionMicrons:Decimal
+ TimestampMicroseconds:int
+ ServoStatus:int
+ PwmVal:int
+ Command Timeout: 30000
+ Example:EvueGetTraceEntry 32
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+ global EvueGetTraceEntry_Response
+ if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+ return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the distance in X,Y between the center tips of the RF probes.
+ API Status: internal
+ Args:
+ ImageFilename:str = ""
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ Example:AutomationRFProbeSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+ global AutomationRFProbeSearch_Response
+ if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+ return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the AutoRF calibration sequence.
+ API Status: internal
+ Command Timeout: 3000
+ Example:StartAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the currently running AutoRF calibraiton.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the status of the AutoRF calibration sequence.
+ API Status: internal
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 1000
+ Example:GetAutoRFCalibrationStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+ global GetAutoRFCalibrationStatus_Response
+ if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+ return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the diagnostic state information for the provided index.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ DiagnosticInfo:str
+ Command Timeout: 5000
+ Example:GetAutomationLastStepDiagnostics
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the WLEM Nano Chamber State.
+ API Status: internal
+ Args:
+ State:str = "Free"
+ Command Timeout: 5000
+ Example:SetWLEMNanoChamberState Free
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the WLEM Nano Chamber State.
+ API Status: internal
+ Returns:
+ State:str
+ Command Timeout: 5000
+ Example:GetWLEMNanoChamberState
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMState NCSeal 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMState NCSeal
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+ return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the value of a WLEM Sensor.
+ API Status: internal
+ Args:
+ Sensor:str = "O2Concentration"
+ Returns:
+ Value:Decimal
+ Command Timeout: 5000
+ Example:GetWLEMSensorValue O2Concentration
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+ return Decimal(rsp[0])
+
+def SetWLEMOption(Option="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMOption MinimizeToTray 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMOption MinimizeToTray
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+ return int(rsp[0])
+
+def NewTesterProject(LotID="", TileID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a new Lot/Tile is to be tested. The tester
+ responds with the correct project name for the test. This is needed because the
+ prober needs to verify that the correct project is loaded. In case no valid
+ project is available, the command is returned with an error.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ TileID:str = ""
+ Returns:
+ ProjectName:str
+ Command Timeout: 30000
+ Example:NewTesterProject Lot01 Tile01
+ """
+ rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn="", DieRow="", ActiveDies=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester to begin measuring (Needles are in correct
+ position and in contact). The command is responded when the measurement has
+ finished. The response string holds the binning information separated by comma.
+ For deactivated dies, a bin value of '0' should be responded.
+ API Status: internal
+ Args:
+ DieColumn:int = 0
+ DieRow:int = 0
+ ActiveDies:str = ""
+ Returns:
+ BinNumbers:str
+ Command Timeout: 100000
+ Example:StartMeasurement 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current substrate has
+ finished. It enables the tester application to save measurement data and/or
+ prepare for the next substrate.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfWafer
+ """
+ MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current lot has finished. It
+ enables the tester application to save measurement data and/or prepare for the
+ next lot.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfLot
+ """
+ MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProductID that is to be tested. The
+ tester can respond with an error in case the ProductID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ ProductID:str = ""
+ Command Timeout: 30000
+ Example:VerifyProductID Product123
+ """
+ MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the LotID that is to be tested. The tester
+ can respond with an error in case the LotID is not allowed for testing.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyLotID Lot123
+ """
+ MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the SubstrateID that is to be tested. The
+ tester can respond with an error in case the SubstrateID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ Command Timeout: 30000
+ Example:VerifySubstrateID Substrate123
+ """
+ MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard="", Touchdowns=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProbecardID and touchdowns that is
+ used for testing. The tester can respond with an error in case the Probecard is
+ not allowed for testing.
+ API Status: internal
+ Args:
+ ProbeCard:str = ""
+ Touchdowns:int = 0
+ Command Timeout: 30000
+ Example:VerifyProbecard Probecard123 10596
+ """
+ MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the User ID. The tester can respond with
+ an error in case the User ID is not allowed for testing.
+ API Status: internal
+ Args:
+ User:str = ""
+ Command Timeout: 30000
+ Example:VerifyUserID User123
+ """
+ MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the job was aborted and no more test will
+ happen.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbort
+ """
+ MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a wafer is ready for testing which will
+ immediately start. This command is sent in the recipe sequence "Verify
+ SOTReady".
+ API Status: internal
+ Command Timeout: 30000
+ Example:VerifySOTReady
+ """
+ MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID="", CassettePlace="", LotID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+ informs the tester about the current wafer on the chuck.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ CassettePlace:str = ""
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyWaferStart Wafer01 1 Lot01
+ """
+ MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command will be sent after the user selected which wafers are to be tested.
+ It contains a string which represents the state of each wafer: 0 = empty, 1 =
+ full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+ deselected
+ API Status: internal
+ Args:
+ CassetteCmd:str = ""
+ Returns:
+ CassetteRsp:str
+ Command Timeout: 30000
+ Example:TesterCassetteInfo 0000001110000000010010111
+ """
+ rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent after selecting a project file in the VeloxPro product
+ setup page. The command sends the name of the project to tester for
+ verification.
+ API Status: internal
+ Args:
+ ProjectName:str = ""
+ Command Timeout: 30000
+ Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+ """
+ MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the test for the current wafer was aborted
+ and no more tests will happen with the current wafer. The job will continue
+ though.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbortWafer
+ """
+ MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts execution of one test. It returns a bin number or multple bin numbers
+ when clusters are enabled in the WaferMap (one number for each die in a
+ cluster). The command starts execution of one test. It returns a bin number or
+ multple bin numbers when clusters are enabled in the WaferMap (one number for
+ each die in a cluster).
+ API Status: internal
+ Returns:
+ BitNumber:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+ return int(rsp[0])
+
+def StartTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the test of a wafer. Depending on the cluster definitions queried from
+ the WaferMap, all clusters or all dies will be tested. The command starts the
+ test of a wafer. Depending on the cluster definitions queried from the WaferMap
+ all clusters or all dies will be tested.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the wafer test.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the selected line of PA port.
+ API Status: internal
+ Args:
+ Line:int = 0
+ Value:int = 0
+ Command Timeout: 10000
+ Example:SetTTLLine 2 0
+ """
+ MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the I/O lines as bit array.
+ API Status: internal
+ Returns:
+ LineA:int
+ LineB:int
+ LineC:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+ global GetTTLLines_Response
+ if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+ return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns returns the error 914 if the test is in progress.
+ API Status: internal
+ Returns:
+ ErrCode:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+ return int(rsp[0])
+
+def StartScript(ScriptName=""):
+ """
+ Starts the script and returns the response immediately.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000
+ Example:StartScript myscript
+ """
+ MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName=""):
+ """
+ Command returns information about Communicator status.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Returns:
+ Running:int
+ LastError:int
+ Title:str
+ Command Timeout: 5000
+ Example:GetRunStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+ global GetRunStatus_Response
+ if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+ return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+ """
+ Command closes the program. Used during ProjectFile handling.
+ API Status: published
+ Command Timeout: 10000
+ Example:CloseCommunicator
+ """
+ MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName=""):
+ """
+ Executes the script and returns the response afterwards.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000000
+ Example:DoScript myscript
+ """
+ MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads Kernel Data to KernelSetup (Left Program pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReadKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves Kernel Data (Left Program pane) to File. An existing File will be
+ overwritten. If the Folder does not exist, it will be created
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads File Data to KernelSetup (Right Program pane).
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces Kernel Data (Left pane) by File Data (Right pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceKernelDataByFileData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces File Tree (Right pane) by Kernel Data (Left pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceFileTreeByKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+ the Folder does not exist, it will be created.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature="", Unit="", ReduceContact=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the chuck. An
+ answer to the command will be returned after reaching the given temperature and
+ waiting the soak time or an unexpected interrupt of the process. Given back is
+ the already reached temperature.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ ReduceContact:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 36000000
+ Example:HeatChuck 61.3 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+ global HeatChuck_Response
+ if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+ return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature="", Unit="", UseContactSafety=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the
+ temperature chuck. The new target temperature is returned immediately as the
+ command does not wait until heating is complete.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ UseContactSafety:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:SetHeaterTemp 55.5 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+ global SetHeaterTemp_Response
+ if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+ return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit="", ExternalHeaterID=""):
+ """
+ Reads the current temperature of the chuck and determines the status of the
+ thermal system.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ ExternalHeaterID:int = 0
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Status:str
+ Command Timeout: 60000
+ Example:GetHeaterTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+ global GetHeaterTemp_Response
+ if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+ return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode=""):
+ """
+ Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+ chuck is heated with a constant current to avoid noise from the temperature
+ control. The hold mode can be enabled only in HoldReady state.
+ API Status: published
+ Args:
+ HoldMode:int = 1
+ Returns:
+ RespHoldMode:int
+ Command Timeout: 60000
+ Example:EnableHeaterHoldMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+ return int(rsp[0])
+
+def StopHeatChuck():
+ """
+ Stops a pending heating or cooling process. If the device is not at temperature,
+ the actual temperature is set as target temperature.
+ API Status: published
+ Command Timeout: 60000
+ Example:StopHeatChuck
+ """
+ MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit=""):
+ """
+ Returns the current dew point temperature, if a dew point sensor is connected.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetDewPointTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+ global GetDewPointTemp_Response
+ if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+ return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the currently set temperature chuck options.
+ API Status: internal
+ Returns:
+ UseSoakTime:int
+ SyncTemp:int
+ CurrConnection:int
+ MinTemperature:Decimal
+ MaxTemperature:Decimal
+ UsePurge:int
+ UseDynamicSoakTime:int
+ UseFixedDieSoakTime:int
+ UseDynamicDieSoakTime:int
+ UseEcoMode:int
+ PurgeOnChamberDoor:int
+ ForceBypassPurge:int
+ DoorClosedTime:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+ global GetTemperatureChuckOptions_Response
+ if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+ return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak="", SyncTemp="", CurrConnection="", UsePurge="", UseDynamicWaferSoak="", UseFixedDieSoakTime="", UseDynamicDieSoakTime="", UseEcoMode="", PurgeOnChamberDoor="", ForceBypassPurge="", DoorClosedTime=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is used to change the currently set temperature chuck options.
+ API Status: internal
+ Args:
+ UseFixedWaferSoak:int = -1
+ SyncTemp:int = -1
+ CurrConnection:int = -1
+ UsePurge:int = -1
+ UseDynamicWaferSoak:int = -1
+ UseFixedDieSoakTime:int = -1
+ UseDynamicDieSoakTime:int = -1
+ UseEcoMode:int = -1
+ PurgeOnChamberDoor:int = -1
+ ForceBypassPurge:int = -1
+ DoorClosedTime:int = -1
+ Returns:
+ UseFixedWaferSoakRsp:int
+ SyncTempRsp:int
+ CurrConnectionRsp:int
+ UsePurgeRsp:int
+ UseDynamicWaferSoakRsp:int
+ UseFixedDieSoakTimeRsp:int
+ UseDynamicDieSoakTimeRsp:int
+ UseEcoModeRsp:int
+ PurgeOnChamberDoorRsp:int
+ ForceBypassPurgeRsp:int
+ DoorClosedTimeRsp:int
+ Command Timeout: 300000
+ Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+ global SetTemperatureChuckOptions_Response
+ if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+ return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+ """
+ Returns the current soak time values in seconds and the soaking status.
+ API Status: published
+ Returns:
+ FixedWaferSoakTime:int
+ FixedWaferSoakStatus:int
+ DynamicWaferSoakTime:Decimal
+ DynamicWaferSoakStatus:int
+ FixedDieSoakTime:Decimal
+ DynamicDieSoakTime:Decimal
+ FixedDieSoakStatus:int
+ DynamicDieSoakStatus:int
+ Command Timeout: 60000
+ Example:GetHeaterSoak
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+ global GetHeaterSoak_Response
+ if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+ return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime="", DynamicWaferSoakTime="", FixedDieSoakTime="", DynamicDieSoakTime=""):
+ """
+ Sets the new soak time values. The unit of the values is seconds. If soak time
+ is actually running, it may be affected by the change.
+ API Status: published
+ Args:
+ FixedWaferSoakTime:int = 60
+ DynamicWaferSoakTime:Decimal = -1
+ FixedDieSoakTime:Decimal = -1
+ DynamicDieSoakTime:Decimal = -1
+ Command Timeout: 60000
+ Example:SetHeaterSoak 60
+ """
+ MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby=""):
+ """
+ Switches the power save (standby) mode of the device on or off. If the device is
+ in power save mode, setting and reading temperatures switches off the power save
+ mode automatically.
+ API Status: published
+ Args:
+ Standby:int = 1
+ Returns:
+ RespStandby:int
+ Command Timeout: 60000
+ Example:EnableHeaterStandby 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+ return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+ """
+ Returns values of the temperature chuck status. The status byte gives
+ information about the current controller's action. The dew point sensor status
+ encapsulates information, if such a sensor is connected, and if the actual dew
+ point difference temperature is readable (active). It can be used for purge
+ control. Soak time left (in seconds) is used when soak time is actually running.
+ API Status: published
+ Returns:
+ Status:str
+ DPSensor:int
+ SoakTimeLeft:int
+ HasEcoMode:int
+ Command Timeout: 60000
+ Example:ReadTemperatureChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+ global ReadTemperatureChuckStatus_Response
+ if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+ return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit=""):
+ """
+ Reads the target temperature of the chuck.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetTargetTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+ global GetTargetTemp_Response
+ if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+ return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command sets the window for the target temperture which is the window in which a
+ station is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Args:
+ Window:Decimal = 1
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:SetThermoWindow 2.0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+ return Decimal(rsp[0])
+
+def GetThermoWindow():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command returns the current thermo window which is the window in which a station
+ is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:GetThermoWindow
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+ return Decimal(rsp[0])
+
+def SendThermoCommand(Command=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends a command string to the thermal chuck using the thermal chuck protocol and
+ returns the thermal chucks response as command response. This command can be
+ used to access thermal chuck features that are not exposed as standalone SCI
+ commands. Command is currently implemented for ERS and ATT chucks.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:SendThermoCommand RH
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID=""):
+ """
+ Returns the status of a single AUX site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ FlagsMode:int
+ Comp:str
+ PresetHeight:str
+ AuxSiteType:str
+ Command Timeout: 10000
+ Example:ReadAuxStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+ global ReadAuxStatus_Response
+ if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+ return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID="", Unit="", PosRef="", Comp=""):
+ """
+ Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+ position is read for the chuck stage. If no AUX ID is given, it tries to read
+ the position from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ AuxIDEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxPosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+ global ReadAuxPosition_Response
+ if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+ return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID="", Unit=""):
+ """
+ Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+ all response values are read from chuck stage. If no AUX ID is given, it tries
+ to read the heights from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+ global ReadAuxHeights_Response
+ if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID="", Overtravel=""):
+ """
+ Modes manage the way a stage behaves when it is in contact height. AUX site mode
+ holds only a single flag. Flags can be turned on by using the value 1 or turned
+ off by using the value 0. If you do not want to change the flag - use the value
+ of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+ move an additional overtravel on every contact move.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Overtravel:int = 2
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxMode 1 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+ return int(rsp[0])
+
+def SetAuxHome(AuxID="", Mode="", Unit="", XValue="", YValue=""):
+ """
+ Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+ sites coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetAuxIndex(AuxID="", XValue="", YValue="", Unit=""):
+ """
+ Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+ chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetAuxHeight(AuxID="", PresetHeight="", Mode="", Unit="", Value=""):
+ """
+ Sets the AUX sites contact height and corresponding gaps for overtravel,
+ alignment and separation height. A contact height search gap for contact search
+ with edge sensor can also be set. This search gap is always identical for all
+ AUX sites. Without any optional parameters the command sets contact height to
+ the current position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadAuxIndex(AuxID="", Unit=""):
+ """
+ Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+ is read from chuck stage. If no AUX ID is given, it tries to read the index from
+ the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+ global ReadAuxIndex_Response
+ if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+ return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID="", Mode="", Unit="", Position=""):
+ """
+ Sets the AUX sites theta home position. It defines the origin of the AUX sites
+ theta coordinate system for later movements. If AUX ID is set to 0, theta home
+ position is set for chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Position:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxThetaHome 1 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+ return int(rsp[0])
+
+def EnableOffset(Stage="", Enable="", Move=""):
+ """
+ Enables or disables the Offset XY compensation for the selected stage. If the
+ compensation holds an offset different from zero, the chuck is automatically
+ moved the distance of the offset. The chuck also moves automatically to a safe
+ height. The move can be disabled by the third parameter. This may put the stage
+ outside the software fence.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Enable:int = 1
+ Move:int = 1
+ Command Timeout: 60000
+ Example:EnableOffset C 1
+ """
+ MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage="", OffsetX="", OffsetY=""):
+ """
+ Sets the offset values for the Offset XY compensation for the selected stage.
+ The changes take effect immediately. Note that the Offset XY compensation must
+ be enabled for the values to take effect. The compensation is enabled or
+ disabled using EnableOffset command.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetOffset C 100000.0 0.0
+ """
+ MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage=""):
+ """
+ Gets information about the Offset XY compensation of the selected stage,
+ including the stored offset values and whether the compensation is enabled or
+ disabled.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Enable:int
+ OffsetX:Decimal
+ OffsetY:Decimal
+ Command Timeout: 5000
+ Example:GetOffsetInfo C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+ global GetOffsetInfo_Response
+ if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+ return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage="", AuxSite="", X="", Y=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the switch position of a stage. This is the position to move to if an aux
+ site gets active. This is only supported for the chuck and it's aux sites. Aux
+ index 0 means wafer site, 1 means aux site 1 and so on.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxSite:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 5000
+ Example:SetSwitchPosition C 0 5000 5000
+ """
+ MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID=""):
+ """
+ Moves the chuck to the position of a given AUX site. A safe height is used for
+ the move. If AUX ID is set to 0, the target of the move is the wafer site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 60000
+ Example:MoveAuxSite 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount=""):
+ """
+ Sets the number of available AUX sites. For preparing for example two cal
+ chucks, the count must be set to 2. For the changes to take effect the system
+ needs to be restarted.
+ API Status: published
+ Args:
+ AuxSiteCount:int = 0
+ Command Timeout: 10000
+ Example:SetAuxSiteCount 2
+ """
+ MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+ """
+ Reads the number of available AUX sites and the ID of the actual active AUX
+ site. If this is 0, the chuck stage is currently active.
+ API Status: published
+ Returns:
+ AuxSiteCount:int
+ ActualAuxSite:int
+ Command Timeout: 10000
+ Example:GetAuxSiteCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+ global GetAuxSiteCount_Response
+ if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+ return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID="", AuxSiteName=""):
+ """
+ Sets the description of an AUX site. With AUX ID zero, the description of the
+ wafer site can be set.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteName:str = ""
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteName 1 Aux site 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+ return int(rsp[0])
+
+def GetAuxSiteName(AuxID=""):
+ """
+ This command reads the description of an AUX site. If AUX ID is set to 0, the
+ description of the chuck stage is given back. If no AUX ID is given, it tries to
+ read from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ Example:GetAuxSiteName 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+ global GetAuxSiteName_Response
+ if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+ return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID=""):
+ """
+ Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+ dependent from the type of the AUX site and from the duration and the cleaning
+ count that is set in configuration. The cleaning algorithm includes both a move
+ to the pad site and a move back to the source site.
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 300000
+ Example:CleanProbeTip 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteType(AuxID="", AuxSiteType=""):
+ """
+ Sets the type for a given AUX site. It depends on the type of the AUX site, if
+ there is a cleaning algorithm available. It is not possible to set the type of
+ the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteType:str = "AuxUnknown"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteType 1 G
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+ return int(rsp[0])
+
+def SetCleaningParams(AuxID="", Count="", Time=""):
+ """
+ Sets the cleaning parameters for a given AUX site. It is not possible to set the
+ cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+ tries to set the parameters of the active site. The cleaning count defines,
+ how much times the cleaning is performed repeatedly. The cleaning time defines,
+ how much milliseconds the needles wait in cleaning position during each
+ cleaning cycle.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Count:int = 1
+ Time:int = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetCleaningParams 1 5 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+ return int(rsp[0])
+
+def GetCleaningParams(AuxID=""):
+ """
+ Reads the cleaning parameters of a given AUX site. It is not possible to read
+ cleaning parameters of the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Count:int
+ Time:int
+ Remaining:int
+ Command Timeout: 30000
+ Example:GetCleaningParams
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+ global GetCleaningParams_Response
+ if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+ return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID="", XOffset="", YOffset=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Rotate the switch, home, and fence positions to match the current chuck theta
+ angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+ that don't move theta.
+ API Status: internal
+ Args:
+ AuxID:int = -1
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 5000
+ Example:UpdateAuxSitePositions 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+ return int(rsp[0])
+
+def ResetCleaningPosition(AuxID="", OffsetX="", OffsetY=""):
+ """
+ Resets the cleaning position to the beginning of the cleaning aux site (home).
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:ResetCleaningPosition 5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+ return int(rsp[0])
+
+def BnR_EchoData(ControllerID="", TestCmd=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Test Command for the Kernel Communication. It is like a ping command. The given
+ text string is returned unchanged.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:BnR_EchoData 1 Hello World
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID="", Module=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual version information of the controller software.
+ The 'Version' value contains version number and revision level of the actual
+ implementation. The text string contains a
+ code description, version number and the revision date.
+ The 'Module' byte is optional (default is K).
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:BnR_ReportKernelVersion 1 K
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+ global BnR_ReportKernelVersion_Response
+ if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+ return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns information about the connected station.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StationType:str
+ Type:str
+ Command Timeout: 5000
+ Example:BnR_GetStationType 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+ global BnR_GetStationType_Response
+ if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+ return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID="", Mode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the BnR controller.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:str = "X"
+ Command Timeout: 10000
+ Example:BnR_ResetController 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID="", Channel="", State="", CycleTime=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ State:int = 0
+ CycleTime:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetOutput 1 1000 1 2000
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID="", Channel=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an output channel. By using the string identifier DO_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ Returns:
+ State:int
+ AllOutputs:str
+ Command Timeout: 5000
+ Example:BnR_GetOutput 1 DO_WaferVacuum
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+ global BnR_GetOutput_Response
+ if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+ return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID="", Channel=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an input channel. By using the string identifier DI_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DI_MotorPower"
+ Returns:
+ State:int
+ AllInputs:str
+ Command Timeout: 5000
+ Example:BnR_GetInput 1 DI_MotorPower
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+ global BnR_GetInput_Response
+ if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+ return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID="", Channel="", OutputPercent=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an analog output channel to a given value.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ OutputPercent:Decimal = 50
+ Command Timeout: 5000
+ Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID="", Channel=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current value of an analog output or input.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ Returns:
+ Value:Decimal
+ UnderOverflow:int
+ Command Timeout: 5000
+ Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+ global BnR_GetAnalogIO_Response
+ if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+ return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the startup status of the BnR controller to determine if the controller
+ is properly booted or still starting.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StartupStatus:str
+ AdditionalStatusInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetStartupStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+ global BnR_GetStartupStatus_Response
+ if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+ return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Creates a Sdm System Dump file on the B&R flash
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 60000
+ Example:BnR_CreateSdmSystemDump
+ """
+ MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets controller data from the B&R controller. Currently used for init
+ information.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 10000
+ Example:BnR_GetControllerData 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID="", MessageType="", Message=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to write a (native) message to Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Message:str = ""
+ Command Timeout: 5000
+ Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID="", MessageType=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to read a (native) message from Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Returns:
+ Message:str
+ Command Timeout: 5000
+ Example:BnR_ReadMessage 1 mtCryoLoader
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID="", ShowAll=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters
+ and requires the BnR_GetNextDatum command.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 5000
+ Example:BnR_GetDataIterator 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+ global BnR_GetDataIterator_Response
+ if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID="", IdentityToken=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:BnR_GetNextDatum 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+ global BnR_GetNextDatum_Response
+ if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+ return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID="", PathNameAndValue=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID="", PathName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathName:str = ""
+ Returns:
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+ global BnR_GetDatum_Response
+ if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+ return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID="", Task="", PCmdInt1="", PCmdInt2=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes an internal BnR Task
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Task:str = ""
+ PCmdInt1:int = 0
+ PCmdInt2:int = 0
+ Returns:
+ RspInt:int
+ RspString:str
+ Command Timeout: 10000
+ Example:BnR_DoInternalTask 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+ global BnR_DoInternalTask_Response
+ if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+ return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage="", Unit=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+ as well as the commanded positions.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Unit:str = "Microns"
+ Returns:
+ XorT:Decimal
+ Y:Decimal
+ Z:Decimal
+ CommandedXorT:Decimal
+ CommandedY:Decimal
+ CommandedZ:Decimal
+ Command Timeout: 5000
+ Example:BnR_GetPosition 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+ global BnR_GetPosition_Response
+ if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+ return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage="", XValue="", YValue="", VelX="", VelY="", WaitFinished=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a XY movement for a specified stage. This can be either a
+ blocking or non blocking move.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ VelX:Decimal = 0
+ VelY:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 60000
+ Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+ global BnR_Move_Response
+ if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+ return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage="", ZValue="", Vel="", Dec="", WaitFinished=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the stage Z axis to a new position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZValue:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ Z:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZ 1 C 12000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID="", Stage="", ZDistance="", TriggerEveryNthCycle="", Vel=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a scan movement of the Z axis that sets a digital output
+ every couple microns to trigger e.g. a camera. After the move is finished, the
+ command returns a list of Z heights at which the digital output was set.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Stage:str = "Chuck"
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 2
+ Vel:Decimal = 10
+ Command Timeout: 300000
+ Example:BnR_ScanMoveZ 1 C 1000 6 10
+ """
+ MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue="", Vel="", WaitFinished=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes a movement of the theta axis, either blocking or non blocking
+ API Status: internal
+ Args:
+ TValue:Decimal = 0
+ Vel:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ T:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveT 1 1.003 10 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage="", FlagsStop=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops 1... all axes of a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:BnR_StopAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage="", FlagsInit="", FlagsDirection="", FlagsInitInPlace="", LowLimitX="", LowLimitY="", LowLimitZ="", LowLimitTh="", InitInPlaceMoveRangeX="", InitInPlaceMoveRangeY="", InitInPlaceMoveRangeZ="", InitInPlaceMoveRangeTh=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Machine Coordinate System: X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+ _FlagsInitInPlace_: X, Y, Z, Theta All flags can be accessed by indirect
+ members. Initializes the stage and resets current coordinate system. Should be
+ used only in cases when the reported coordinates do not correspond to real
+ position of mechanics. Init in Place performs the initialization without any
+ movements.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsInitInPlace:int = 0
+ LowLimitX:Decimal = 0
+ LowLimitY:Decimal = 0
+ LowLimitZ:Decimal = 0
+ LowLimitTh:Decimal = 0
+ InitInPlaceMoveRangeX:Decimal = 0
+ InitInPlaceMoveRangeY:Decimal = 0
+ InitInPlaceMoveRangeZ:Decimal = 0
+ InitInPlaceMoveRangeTh:Decimal = 0
+ Command Timeout: 300000
+ Example:BnR_InitAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage="", Axis=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+ g/homing/continuousmotion/discretemotion/synchronizedmotion)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ State:str
+ AdditionalStateInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetAxisState 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+ global BnR_GetAxisState_Response
+ if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+ return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage="", Axis=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns some axis status information
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ Initialized:int
+ PositiveEndlimit:int
+ NegativeEndlimit:int
+ Command Timeout: 5000
+ Example:BnR_GetAxisStatus 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+ global BnR_GetAxisStatus_Response
+ if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+ return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage="", QuietMode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to enable the quiet mode for a stage (quiet turns motors powerless)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ QuietMode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetQuietMode 1 C 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to query the quiet mode for a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ QuietMode:int
+ Command Timeout: 5000
+ Example:BnR_GetQuietMode 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+ return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage="", Axis="", InfoType=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns various axis information, dependent on the InfoType
+ parameter
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ InfoType:str = "StallInfo"
+ Returns:
+ RspString:str
+ Command Timeout: 5000
+ Example:BnR_GetInternalAxisInfo 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage="", Axis=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to get various information required for the BnR wiring tester tool.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ STIn_ModuleOK:int
+ STIn_LifeCnt:int
+ STIn_DrvOK:int
+ STIn_OvertemperatureError:int
+ STIn_CurrentError:int
+ STIn_OvercurrentError:int
+ STIn_RefPulsePos:int
+ STIn_RefPulseCnt:int
+ STIn_ModulePowerSupplyError:int
+ STOut_SetTime:int
+ STOut_MotorStep0:int
+ STOut_DriveEnable:int
+ STOut_BoostCurrent:int
+ STOut_StandStillCurrent:int
+ STOut_ClearError:int
+ CMIn_ModuleOK:int
+ CMIn_SDCLifeCount:int
+ CMIn_Encoder:int
+ CMIn_EncoderTimeValid:int
+ CMIn_DigitalInput1:int
+ CMIn_DigitalInput2:int
+ CMIn_BWChannelA:int
+ CMIn_BWChannelB:int
+ CMIn_PowerSupply2:int
+ CMOut_QuitChannelA:int
+ CMOut_QuitChannelB:int
+ SWAxisErrorID:int
+ SWAxisErrorDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetWiringTesterData 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+ global BnR_GetWiringTesterData_Response
+ if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+ return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage="", Axis="", Value="", Vel="", Dec="", WaitFinished=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows moving a single axis to and e.g. in case of X does not
+ trigger a Y movement
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Value:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ PositionAfterMove:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveAxis 1 C X 20000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ="", WaitFinished="", ForcedAbsVelocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+ API Status: internal
+ Args:
+ ChuckTargetZ:Decimal = 0
+ WaitFinished:int = 1
+ ForcedAbsVelocity:int = 0
+ Returns:
+ ChuckZ:Decimal
+ ScopeX:Decimal
+ ScopeY:Decimal
+ ScopeZ:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZCombined 1 17592.5 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+ global BnR_MoveZCombined_Response
+ if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+ return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage="", ZDown="", XValue="", YValue="", ZUp=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command does a combined Z-XY-Z- move completely on the BnR-controller
+ without WinKernel interaction. This is a part of an ongoing optimization.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZDown:Decimal = 0
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZUp:Decimal = 0
+ Command Timeout: 60000
+ Example:BnR_StepMove 1 C 250 1000 1000 250
+ """
+ MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos="", Velocity=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a search move until the search end position is reached or the edge
+ sensor triggers. If the edge sensor triggers during the move, the trigger
+ position is returned.Otherwise, an edge sensor not found error is returned.
+ API Status: internal
+ Args:
+ SearchEndPos:Decimal = 0
+ Velocity:Decimal = 0
+ Returns:
+ EdgeSensorTriggerPos:Decimal
+ Command Timeout: 300000
+ Example:BnR_SearchEdgeSensor 3000 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+ return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a collection of trace data
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 5000
+ Example:BnR_GetTraceData 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID="", Mode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Commands sets the trace mode
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetTraceMode 1 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage="", Axis="", MotorModule="", RegisterName="", Value=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to change a module register value without controller restart
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Value:int = 0
+ Command Timeout: 5000
+ Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage="", Axis="", MotorModule="", RegisterName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to get any desired module register value
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+ return int(rsp[0])
+
+def ProcessStationGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+ Initialized) and error code with error message when error.
+ API Status: internal
+ Returns:
+ Status:str
+ SubstratePresent:int
+ LastError:int
+ UseLoaderModule:int
+ WaferSizes:str
+ StatusMessage:str
+ IsLoaderJobRunning:int
+ Command Timeout: 25000
+ Example:ProcessStationGetStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+ global ProcessStationGetStatus_Response
+ if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+ return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initialize process station machine. This is not the prober init it is a fast
+ program initialization. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 2400000
+ Example:ProcessStationInit
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Finishes a process station process. This resets some internal test information
+ for the probe station. Some data is only reset in case this command is sent
+ after the last wafer in the job was tested. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 7500000
+ Example:ProcessStationFinish
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command moves the chuck of the probe station to the secondary load position and
+ if available also checks the table level sensor. Only applies to fully auto
+ systems.
+ API Status: internal
+ Command Timeout: 120000
+ Example:ProcessStationPrepareForLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck out of the load position and checks if a wafer is placed. Only
+ applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should do whatever is necessary to prepare the current wafer for
+ unload. Typically this includes things such as moving lift pins and opening
+ doors.
+ API Status: internal
+ Command Timeout: 1000000
+ Example:ProcessStationPrepareForUnLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should so whatever is necessary after a wafer is unloaded. This may
+ for example include closing doors.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationUnLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject="", ProjectFileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The recipe is a zipped archive that includes all project data. This command
+ tells the device to load the recipe.
+ API Status: internal
+ Args:
+ ForceReOpenProject:int = 0
+ ProjectFileName:str = ""
+ Command Timeout: 60000
+ Example:ProcessStationLoadRecipe 1 SampleProject.spp
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Requests that the device verify that the recipe given can be executed on the
+ device. It should check that the recipe is correctly formed and conforms to the
+ hardware of the device. It should not check for transient things such as whether
+ there is sufficient media or facilities available. those kinds of checks should
+ be done in PrepareForProcess
+ API Status: internal
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 60000
+ Example:ProcessStationVerifyRecipe SampleProject.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+ global ProcessStationVerifyRecipe_Response
+ if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+ return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob="", TotalWafersInJob=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells VeloxPro to start the current recipe. The station will switch to error if
+ an error occurs. If VeloxPro recipe execution is currently paused, this command
+ tells the system to continue execution.
+ API Status: internal
+ Args:
+ CurrentWaferInJob:int = -1
+ TotalWafersInJob:int = -1
+ Command Timeout: 25000
+ Example:ProcessStationStartRecipe 1
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the device to stop the current recipe. The station will switch to error if
+ an error occurs.
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationStopRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the module to do whatever is necessary to recover from an error condition.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationRecoverError
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get substrate information from process station controller application.
+ API Status: internal
+ Returns:
+ Result:str
+ PercentDone:Decimal
+ AllowSkipWafer:int
+ TestInformation:str
+ Command Timeout: 25000
+ Example:ProcessStationGetWaferResult
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+ global ProcessStationGetWaferResult_Response
+ if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+ return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+ """
+ Returns information about the wafer that is currently on the probe station. It
+ will return an error when there is no wafer currently on the chuck.
+ API Status: published
+ Returns:
+ Size:int
+ Angle:Decimal
+ ID:str
+ LotID:str
+ ProductID:str
+ Command Timeout: 25000
+ Example:QueryWaferInfo
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+ global QueryWaferInfo_Response
+ if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+ return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the process station to PAUSE mode
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationPauseRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+ """
+ Retrieves the current status of the prober. If probing status is AtFirstDie the
+ tester can take control.
+ API Status: published
+ Returns:
+ Status:str
+ Command Timeout: 25000
+ Example:GetProbingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+ """
+ Tells the prober to proceed the recipe when current status is AtFirstDie.
+ API Status: published
+ Command Timeout: 25000
+ Example:ProceedProbing
+ """
+ MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette=""):
+ """
+ Provides all available wafer information. It returns a set of data for each
+ wafer in either cassette. The data contains the cassette and the slot number
+ where the wafer is located, the status of the wafer, and identification
+ information.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 25000
+ Example:GetCassetteStatus 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module="", Slot=""):
+ """
+ Queries the wafer ID of a given module and slot.
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryWaferID Cassette1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module="", Slot="", ID=""):
+ """
+ Overrides the wafer ID of the given module and slot. If the wafer id is empty
+ and the module is a Loadport, the id will be read by the idreader if possible.
+ This process behaves as follows: - the current wafer id is reset - if the read-
+ wafer-process would be delayed (e.g. there is already a wafer on the idreader)
+ the process will be aborted and an error will be returned - if the id-
+ reading fails, the process behaves like a normal inventory triggered by the UI:
+ skip (returns success), abort (returns error) or "ask user". It is
+ recomended to use either skip or abort for remote id reading. If the
+ module is a Loadport and the slot is set to -1, a regular inventory will be
+ triggered. This behaves similar to an inventory triggered by the UI: The ID
+ won't be reset and already scanned wafers won't be reset. Setting an ID
+ explicitly with slot -1 is an error: - Okay, read id of wafer in slot 3 even if
+ it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+ to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+ UpdateWaferID Cassette1 -1 - Error: UpdateWaferID Cassette1 -1 XYZ123
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ ID:str = ""
+ Command Timeout: 1500000
+ Example:UpdateWaferID Cassette1 1 Wafer01
+ """
+ MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName=""):
+ """
+ Queries whether the given project/flow name is a valid project/flow at the probe
+ station. Using file and folder names without white spaces is recommended. For
+ folders and files whith white spaces use quotation marks for the path. Example
+ for using white spaces: ConfirmRecipe
+ "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+ API Status: published
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 25000
+ Example:ConfirmRecipe C:/Temp/Test.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+ global ConfirmRecipe_Response
+ if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+ return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName="", WaferIDs=""):
+ """
+ Creates and starts a new job by specifying the flow/spp file and the wafers to
+ be included in the job.
+ API Status: published
+ Args:
+ RecipeName:str = ""
+ WaferIDs:str = ""
+ Returns:
+ JobID:str
+ Command Timeout: 25000
+ Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID=""):
+ """
+ Get job information for a specific job ID including the flow file and the list
+ of wafers.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ RecipeName:str
+ WaferIDs:str
+ Command Timeout: 25000
+ Example:GetJobParams 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+ global GetJobParams_Response
+ if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+ return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID=""):
+ """
+ Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+ an error string is returned.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ Status:str
+ JobStatusInfo:str
+ Command Timeout: 25000
+ Example:JobStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+ global JobStatus_Response
+ if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+ return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID="", Unload=""):
+ """
+ Aborts the job given by the job ID. The status of the job will be set to
+ "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+ or not.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Unload:int = 0
+ Command Timeout: 25000
+ Example:AbortJob 2 1
+ """
+ MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the VeloxPro application.
+ API Status: internal
+ Args:
+ NoUserPrompt:int = 0
+ Command Timeout: 25000
+ Example:ProcessStationCloseApplication
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+ """
+ Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+ free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+ API Status: published
+ Command Timeout: 600000
+ Example:UnloadWafer
+ """
+ MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType=""):
+ """
+ Returns a string for the relevant JobIDs.
+ API Status: published
+ Args:
+ JobType:str = "Probing"
+ Returns:
+ GetJobList:str
+ Command Timeout: 25000
+ Example:GetJobList
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob=""):
+ """
+ Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+ determines how the job continues.
+ API Status: published
+ Args:
+ ProceedJob:str = "AbortJob"
+ Command Timeout: 25000
+ Example:ProceedJob AbortJob
+ """
+ MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette=""):
+ """
+ Returns the ID of a cassette that is placed on the load port. The loadport and
+ the cassette must support RFID reading (additional hardware needed).
+ API Status: published
+ Args:
+ Cassette:int = 1
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryCassetteID 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId="", DockUndock=""):
+ """
+ Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+ return an error if no cassette is placed: the LoadPort is not ready/available or
+ the docking failed. The command will do the docking/undocking and return when
+ this is done.
+ API Status: published
+ Args:
+ LoadPortId:int = 0
+ DockUndock:int = 0
+ Command Timeout: 60000
+ Example:DockCassette 1 1
+ """
+ MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID="", SlotID="", AlignmentAngle=""):
+ """
+ Load a wafer from a given loadport onto the prober. If no slot id is defined,
+ the first available wafer with the lowest slot id will be loaded. If no loadport
+ is defined, it will try to use the first loadport. If there is no suitable
+ wafer, it will try the second. Returns an error if the loading process fails or
+ no suitable wafer is found. To define an alignment angle and still use the
+ "autoselect" behaviour, use -1 for loadport and slot.
+ API Status: published
+ Args:
+ LoadportID:int = -1
+ SlotID:int = -1
+ AlignmentAngle:Decimal = 0
+ Command Timeout: 600000
+ Example:LoadWafer 1 1
+ """
+ MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette=""):
+ """
+ Updates the cassette status with a simple scan.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 1200000
+ Example:UpdateCassetteStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation="", SourceSlot="", DestinationLocation="", DestinationSlot=""):
+ """
+ Transport a wafer from one location to another. This command behaves like the
+ wafer-transport inside the LoaderModule. The Slot must always be set.
+ API Status: published
+ Args:
+ SourceLocation:str = "Cassette1"
+ SourceSlot:int = 1
+ DestinationLocation:str = "Cassette1"
+ DestinationSlot:int = 1
+ Command Timeout: 600000
+ Example:TransportWafer Cassette1 1 PreAligner 1
+ """
+ MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module="", ProcessParam=""):
+ """
+ "Process" a wafer on a given location. What is done depends on the current
+ station: - IDReader: read ID - PreAligner: align wafer (alignment angle
+ mandatory) - Prober: Perform current recipe
+ API Status: published
+ Args:
+ Module:str = "Cassette1"
+ ProcessParam:str = ""
+ Command Timeout: 100000
+ Example:ProcessWafer PreAligner 90.0
+ """
+ MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the IDReader
+ API Status: internal
+ Returns:
+ IDReaderPos:str
+ Command Timeout: 2000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the current position of the IDReader
+ API Status: internal
+ Args:
+ IDReaderPos:str = "Bottom"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process=""):
+ """
+ CryoCommand controls automatic cooling and warm up.
+ API Status: published
+ Args:
+ Process:str = "CD"
+ Command Timeout: 60000
+ Example:CryoCommand CD
+ """
+ MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage=""):
+ """
+ Reads the current temperature from sensor chuck or shield.
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Returns:
+ Temp:Decimal
+ Command Timeout: 10000
+ Example:CryoReadTemperature C
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+ return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage="", Temp=""):
+ """
+ Sets temperature value for TIC chuck or shield. (Only available in process state
+ 'Idle' or 'Cold'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Temp:Decimal = 320
+ Command Timeout: 10000
+ Example:CryoSetTemperature C 70.5
+ """
+ MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage=""):
+ """
+ Enables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStartRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage=""):
+ """
+ Disables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStopRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+ """
+ Reads current state.
+ API Status: published
+ Returns:
+ State:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+ """
+ Moves the black body to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition=""):
+ """
+ Moves the black body to working position.
+ API Status: published
+ Args:
+ NbrPosition:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveBBWork 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position="", Shutter=""):
+ """
+ Moves one of the two shutters.
+ API Status: published
+ Args:
+ Position:str = "C"
+ Shutter:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveShutter F 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+ """
+ Moves the microscope to working position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+ """
+ Moves the microscope to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+ """
+ Reads the current pressure of the vacuum chamber.
+ API Status: published
+ Returns:
+ Pressure:Decimal
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+ return Decimal(rsp[0])
+
+def MoveZCombined(Height="", Percent="", Async=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move both Chuck and Scope to a new absolute z-Height. The position must be
+ within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+ maximum velocity for now
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ Percent:Decimal = 0
+ Async:int = 0
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+ """
+ Get the state of the software stop.
+ API Status: published
+ Returns:
+ StopState:int
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+ return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status="", Message=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Used to set the system either in off, on, error or locked state. For lock, a
+ key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+ SetStatus without message means enable/ recover from error, with message it
+ means unlock. If the system wasn't enabled or in error state before an unlock,
+ it will remain in this state after the unlock.
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+ """
+ Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+ should be the same as the currently active ScopeSilo
+ API Status: published
+ Returns:
+ ScopeWorkingStage:int
+ Command Timeout: 5000
+ Example:GetScopeWorkingStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+ return int(rsp[0])
+
+def SetPerformanceMode(Mode=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the performance mode in use by remote command. If this feature is not
+ supported and the mode is anything but Standard, an error is returned.
+ API Status: internal
+ Args:
+ Mode:str = "Standard"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage=""):
+ """
+ Move to the target working stage
+ API Status: published
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 30000
+ Example:SetScopeWorkingStage 1
+ """
+ MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured performance mode. If this feature is not supported
+ on a station, Standard will be returned
+ API Status: internal
+ Returns:
+ Mode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the current status of the combined-z-move-system
+ API Status: internal
+ Returns:
+ Status:str
+ PlatenSafe:int
+ Height:Decimal
+ HeightMax:Decimal
+ HeightRelative:Decimal
+ SafeHeight:Decimal
+ Message:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+ global MoveZCombinedGetStatus_Response
+ if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+ return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable="", Path=""):
+ """
+ Load a previously saved Scope-Fence-configuration or remove the current
+ configuration
+ API Status: published
+ Args:
+ Enable:int = 0
+ Path:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState=""):
+ """
+ Set the state of the software stop.
+ API Status: published
+ Args:
+ StopState:int = 0
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
diff --git a/src/FlexSensor/Prober/velox_api/velox/sci35.py b/src/FlexSensor/Prober/velox_api/velox/sci35.py
new file mode 100644
index 0000000000000000000000000000000000000000..655db8fb75f1ddee407da4bee0f5d95a0fe8a6aa
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/sci35.py
@@ -0,0 +1,11999 @@
+from Prober.velox_api.velox.vxmessageserver import *
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite.
+The module was auto-generated from the commands.info.xml file on 2019-11-09.
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():'
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection.
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+ # Your Code: try some SCI Commands - such as:
+ response = velox.ReportKernelVersion()
+ print ('The kernel version is', response.Version, 'and', response.Description)
+
+"""
+def EchoData(TestCmd:str=""):
+ """
+ Test Command for the Kernel Communication. Like a ping command, the given text
+ string is returned unchanged.
+ API Status: published
+ Args:
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:EchoData Test
+ """
+ rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module:str=""):
+
+ """
+ Returns the version information of the kernel or the control box code. The
+ "Version" value contains version number and revision level of the actual Kernel
+ implementation. The text string contains a code description, version number and
+ the revision date.
+ API Status: published
+ Args:
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:ReportKernelVersion K
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+ global ReportKernelVersion_Response
+ if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+ return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+ """
+ Returns an actual status information of the prober.
+ API Status: published
+ Returns:
+ FlagsBusy:int
+ FlagsContact:int
+ Mode:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProberStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+ global ReadProberStatus_Response
+ if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+ return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn:int="", Stage:str=""):
+ """
+ Toggles the motor power for quiet probing. In most applications this feature is
+ not required. However, for special measurements it may be necessary to reduce
+ the noise of the system. Quiet on turns off the motor power for all stages (or
+ the one specified with the optional parameter). Quiet off will turn on the motor
+ power of all stages (or the one specified with the optional parameter) for
+ subsequent movements. A move command will also turn on the motor power of the
+ moved stage automatically. For automatical switching of the quiet mode refer to
+ Auto Quiet functionality. Sending 'EnableMotorQuiet 1' will enable the quiet
+ mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+ mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+ quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+ disable the quiet mode for the scope stage.
+ API Status: published
+ Args:
+ WantQuietModeOn:int = 0
+ Stage:str = "None"
+ Command Timeout: 10000
+ Example:EnableMotorQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn:int=""):
+ """
+ Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+ stations with wafer vacuum sensors in case no wafer was detected.
+ API Status: published
+ Args:
+ WantChuckVacuumOn:int = 0
+ Command Timeout: 10000
+ Example:SetChuckVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn:int=""):
+ """
+ Toggles the microscope light channel of the peripheral output board and all
+ cameras. Notifications: 7
+ API Status: published
+ Args:
+ WantIlluminatorOn:int = 2
+ Command Timeout: 5000
+ Example:SetMicroLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode:int="", PulseWidthRed:int="", PulseWidthGreen:int="", PulseWidthYellow:int="", PulseWidthBlue:int="", PulseWidthWhite:int=""):
+ """
+ This command controls the beacon channel of the peripheral output board. All
+ lights can be switched on, off, or blinking. Setting an interval to zero means,
+ that the corresponding light will be statically on or off. The minimum blinking
+ interval is 50ms.
+ API Status: published
+ Args:
+ FlagsMode:int = 0
+ PulseWidthRed:int = 1000
+ PulseWidthGreen:int = 0
+ PulseWidthYellow:int = 0
+ PulseWidthBlue:int = 0
+ PulseWidthWhite:int = 0
+ Command Timeout: 5000
+ Example:SetBeaconStatus 1 1000
+ """
+ MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel:int="", WantOutputOn:int="", PulseTime:int=""):
+ """
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: published
+ Args:
+ Channel:int = 1
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetOutput 4 0
+ """
+ MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+ """
+ Stops all Prober movements immediately. The response status value of any pending
+ movement will signify that the stop command was executed.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAllMovements
+ """
+ MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker:int="", PulseWidth:int=""):
+ """
+ Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+ For correct function, the inkers have to be linked to default outputs.
+ API Status: published
+ Args:
+ FlagsInker:int = 0
+ PulseWidth:int = 50
+ Command Timeout: 10000
+ Example:InkDevice 1 40
+ """
+ MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+ """
+ Returns the current positioner configuration. The output pattern is: 1. Type
+ Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+ Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+ 2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+ Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+ 11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+ API Status: published
+ Returns:
+ TypePositioner1:int
+ TypePositioner2:int
+ TypePositioner3:int
+ TypePositioner4:int
+ TypePositioner5:int
+ AxisPositioner1:int
+ AxisPositioner2:int
+ AxisPositioner3:int
+ AxisPositioner4:int
+ AxisPositioner5:int
+ TypePositioner6:int
+ AxisPositioner6:int
+ Command Timeout: 5000
+ Example:ReadProbeSetup
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+ global ReadProbeSetup_Response
+ if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+ return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+ """
+ Returns the system options which are currently enabled at the prober.
+ API Status: published
+ Returns:
+ Name:str
+ System:str
+ ChuckXY:int
+ ChuckZ:int
+ ChuckTheta:int
+ ScopeXY:int
+ ScopeZ:int
+ EdgeSensor:int
+ OperationalMode:str
+ Turret:int
+ TemperatureChuck:int
+ AuxSiteCount:int
+ PlatenXY:int
+ PlatenZ:int
+ LoaderGateState:str
+ NucleusType:str
+ Command Timeout: 10000
+ Example:ReadSystemStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+ global ReadSystemStatus_Response
+ if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+ return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode:str=""):
+ """
+ If 'R' is sent, it sets the external mode of the kernel. This disables most of
+ the control box functions (except the LOCAL function key). Otherwise, this
+ command re-enables all functions of the control box.
+ API Status: published
+ Args:
+ Mode:str = "L"
+ Command Timeout: 5000
+ Example:SetExternalMode L
+ """
+ MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage:str="", WantStageLock:int="", Application:str=""):
+ """
+ Enables or disables the stage lock functionality. Stages which are locked can't
+ be moved in any way. If the joystick controller is locked, the display and the
+ keys are deactivated. The name of the application can be stored by using the
+ Application Name parameter and is shown in lock-caused error messages.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ WantStageLock:int = 1
+ Application:str = ""
+ Command Timeout: 10000
+ Example:SetStageLock C 0 WaferMap
+ """
+ MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel:int="", Type:str=""):
+ """
+ Returns the actual status of the specified input channel, output channel or edge
+ sensor. The signal table is described in the Hardware Manual. Each used IO-board
+ has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+ channel numbers. Beyond this range there are pseudo channels, which are used for
+ special purposes. Pseudo channels:
+ API Status: published
+ Args:
+ Channel:int = 1
+ Type:str = "Input"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadSensor 11 I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+ return int(rsp[0])
+
+def GetStageLock(Stage:str=""):
+ """
+ Reads whether stages or joystick controller are locked.
+ API Status: published
+ Args:
+ Stage:str = "0"
+ Returns:
+ Locks:int
+ Application:str
+ Command Timeout: 10000
+ Example:GetStageLock C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+ global GetStageLock_Response
+ if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+ return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets bottomside mode. In this mode the Z axis is reverse and the
+ command MoveChuckLoad is not allowed.
+ API Status: internal
+ Args:
+ WantBackSideMode:int = 0
+ Command Timeout: 5000
+ Example:SetBackSideMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+ """
+ Returns the current side mode.
+ API Status: published
+ Returns:
+ IsBackSideModeOn:int
+ Command Timeout: 5000
+ Example:GetBackSideMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+ return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode:int=""):
+ """
+ Switches off all LEDs on the Control Box, on the positioners, and on the screen
+ of the Control Box and also the light of the cameras.
+ API Status: published
+ Args:
+ WantSetDarkMode:int = 0
+ Command Timeout: 5000
+ Example:SetDarkMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+ """
+ Returns the current mode of the light sources.
+ API Status: published
+ Returns:
+ IsDarkMode:int
+ Command Timeout: 5000
+ Example:GetDarkMode
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+ return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera:str="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Connect or disconnect the chuck camera to the chuck stage. The command is only
+ available for the Prober type PA300BEP.
+ API Status: internal
+ Args:
+ ConnectCamera:str = "ParkPos"
+ Velocity:Decimal = 100
+ Command Timeout: 300000
+ Example:DockChuckCamera P 75
+ """
+ MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current selected stage of the joystick controller.
+ API Status: internal
+ Returns:
+ Stage:str
+ Command Timeout: 5000
+ Example:ReadCBoxStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current stage of the joystick controller.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:SetCBoxStage C
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current setting of the joystick controllers position monitor for the
+ secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ PosRef:str
+ Unit:str
+ Command Timeout: 5000
+ Example:ReadCBoxPosMonConf C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+ global ReadCBoxPosMonConf_Response
+ if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+ return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage:str="", PosRef:str="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Configures the joystick controller position monitor for the secified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetCBoxPosMonConf C Z Y
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CBoxSpeed:str
+ Command Timeout: 5000
+ Example:ReadCBoxCurrSpeed C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage:str="", CBoxSpeed:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current speed of the joystick controller for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CBoxSpeed:str = "Speed4"
+ Command Timeout: 5000
+ Example:SetCBoxCurrSpeed C 3
+ """
+ MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck stage to the specified X,Y position without waiting for the move
+ to be finished If chuck Z is in contact height or higher, the chuck will drop to
+ separation.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveChuckAsync 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the scope stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 5000
+ Example:MoveScopeAsync 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the probe stage to the specified X,Y position without waiting for the move
+ to be finished.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def ReadChuckStatus():
+ """
+ Returns the current chuck status. Every bit in the bit fields works like a
+ boolean value: One <1> means true/on and zero <0> means false/off.
+ Its counted from LSB to MSB. - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+ HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+ EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+ ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta All parameters
+ are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+ accessed by M_pbIsInitX).
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsVacuumOn:int
+ PresetHeight:str
+ LoadPos:str
+ IsLiftDown:int
+ CameraConnection:str
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+ global ReadChuckStatus_Response
+ if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+ return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the current chuck stage position in X, Y and Z.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+ global ReadChuckPosition_Response
+ if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+ return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit:str=""):
+ """
+ Returns the current settings used for the chuck Z movement. `Contact` is the
+ contact-height from zero in default compensation. The other heights are relative
+ to this. If no contact is set, the value will be -1.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ SearchGap:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+ global ReadChuckHeights_Response
+ if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+ return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ Machine Coordinate System: Chuck X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+ X, Y, Z, Theta All flags can be accessed by indirect members. Initializes the
+ chuck stage and resets current coordinate system. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 150000
+ Example:InitChuck 7 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+ height or higher, Interlock and Auto Z flags will be analyzed and stage will
+ behave correspondingly - can move to separation first or return an error:
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MoveChuck 5000. 5000. R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck stage in index steps. This command modifies Die Home Position.
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue:Decimal="", YValue:Decimal="", Unit:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck stage to the specified X, Y sub-site position. Die home position
+ is defined by destination position of last successful MoveChuck or
+ MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+ you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+ back to die home position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckSubsite 200 200 Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity:Decimal=""):
+ """
+ Performs a movement of chuck Z axis to preset contact height or will return
+ error if no contact height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckContact 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity:Decimal=""):
+ """
+ Moves the chuck Z axis to the align height. If no Contact height is set will
+ return an error.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity:Decimal=""):
+ """
+ Moves the chuck Z axis to the separation height. Returns error if no Contact
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveChuckSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition:str=""):
+ """
+ Moves the Chuck stage in X, Y, Z and Theta to the load position.
+ API Status: published
+ Args:
+ LoadPosition:str = "First"
+ Command Timeout: 60000
+ Example:MoveChuckLoad 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck Z axis to the specified height. If contact is set, only moves up
+ to contact height will be allowed. If overtravel is enabled - up to overtravel
+ height.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 60000
+ Example:MoveChuckZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the chuck Z axis to the specified height and sets contact. The move stops
+ immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+ been found and an old one was set before the old contact will not get lost, it
+ will be reset.
+ API Status: published
+ Args:
+ Height:Decimal = 100
+ PosRef:str = "Relative"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 60000
+ Example:SearchChuckContact 1000 R Y 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+ return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ Moves the chuck stage in velocity mode. The motion continues until the
+ StopChuckMovement command is received, or the end limit is reached.
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveChuckVelocity + + 0 100 30 0
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop:int=""):
+ """
+ Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+ API Status: published
+ Args:
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:StopChuckMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel:int="", AutoZ:int="", Interlock:int="", ContactSearch:int="", EdgeInterlock:int="", QuietContact:int=""):
+ """
+ Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+ is made from 6 flags and you can control all of them using this command. Every
+ flag can be turned on by using value 1 or turned off by using value 0. If you do
+ not want to change a flag - use value of 2.
+ API Status: published
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ ContactSearch:int = 2
+ EdgeInterlock:int = 2
+ QuietContact:int = 2
+ Command Timeout: 5000
+ Example:SetChuckMode 2 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets wafer and die home position, which can be used later as coordinate system
+ for movements.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the wafer index size. Normally the size of one die.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetChuckIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation. A predefined contact search gap is able to write. No data
+ in the optional parameters sets contact height at current position. If Mode is
+ '0', contact height can be set at current position. The levels O, A, S and T
+ support no Mode '0'. If Mode is 'V' and no value for height is specified -
+ default 0 will be used, what potentially can be not what you expect. If Mode is
+ 'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+ 'R'.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckHeight C V Y 5000.
+ """
+ MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit:str=""):
+ """
+ The command gets the current die size which is stored in the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+ global ReadChuckIndex_Response
+ if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+ return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+ """
+ Moves the Chuck to the Transfer Position. If the movement starts in Load
+ Position (where it's possible to pull out the chuck) the handling of the Add On
+ Platen or the Pin Chuck is integrated.
+ API Status: published
+ Command Timeout: 90000
+ Example:MoveChuckTransfer
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift:int=""):
+ """
+ Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+ motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveChuckLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX:Decimal="", ScaleY:Decimal=""):
+ """
+ Thermo drifts of the wafer will be compensated. The compensation is not
+ persistent, (power off - this compensation is deleted). The algorithm works as
+ an additional one. This is for an iterative usage, so: 1. `ResetProber H` 2.
+ `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5` will result in a
+ scale of 2.25 in both directions. The thermal scale can also be reset using the
+ command 'SetChcukThermoValue 20 C'
+ API Status: published
+ Args:
+ ScaleX:Decimal = 1
+ ScaleY:Decimal = 1
+ Command Timeout: 5000
+ Example:SetChuckThermoScale 1.000005 1.0000045
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+ """
+ Read the linear scaling value of the chuck.
+ API Status: published
+ Returns:
+ ScaleX:Decimal
+ ScaleY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoScale
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+ global ReadChuckThermoScale_Response
+ if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+ return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature:Decimal="", Unit:str="", ExpCoeffX:Decimal="", ExpCoeffY:Decimal=""):
+ """
+ Set a temperature and optional the expansion coefficient. The temperature for
+ normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+ set the temperature directly the controller calculates the stage difference in
+ the coordinate system. For the calculation use the set coefficient of expansion
+ from the controller. The default coefficient of expansion is based on silicon:
+ 2.33E-06 1/K.
+ API Status: published
+ Args:
+ Temperature:Decimal = 0
+ Unit:str = "Celsius"
+ ExpCoeffX:Decimal = 0
+ ExpCoeffY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetChuckThermoValue 250 C 2.43 2.32
+ """
+ MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit:str=""):
+ """
+ Read the current temperature (either set or calculated) for the thermal scaling.
+ With SetChuckThermoScale in use, the value will be calculated by the current
+ scale and the expansion factor of silicium. The temperature that is read with
+ this command is not identical to the current chuck temperature.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ Temperature:Decimal
+ ExpCoeffX:Decimal
+ ExpCoeffY:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckThermoValue C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+ global ReadChuckThermoValue_Response
+ if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+ return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ChuckTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetChuckTableID ChuckTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+ return int(rsp[0])
+
+def MoveChuckTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move the chuck to the next stored table site.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveChuckTablePoint 3 10 67
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the table site information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadChuckTablePoint 10 250 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+ global ReadChuckTablePoint_Response
+ if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the chuck table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearChuckTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of chuck table site points in the in the Kernel. If Start
+ Point is -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearChuckTablePoint 5 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+ global ClearChuckTablePoint_Response
+ if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is moved to slowly attach a wafer that is at ambient temperature while
+ the chuck is hot. The command acts similar to MoveChuckTransfer when moving
+ out of Load 2 but will use a much slower Z velocity. This is only supported
+ for BnR-machines (CM300 and Summit200) at the moment.
+ API Status: internal
+ Args:
+ MoveTimeMs:Decimal = 30000
+ Command Timeout: 300000
+ Example:AttachAmbientWafer
+ """
+ MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+ """
+ Returns the actual status of the chuck Theta axis.
+ API Status: published
+ Returns:
+ IsInit:int
+ FlagsLimit:int
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadThetaStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+ global ReadThetaStatus_Response
+ if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+ return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit:str="", PosRef:str=""):
+ """
+ Returns the actual Theta position.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ PosRef:str = "Home"
+ Returns:
+ Position:Decimal
+ Command Timeout: 5000
+ Example:ReadThetaPosition D Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+ return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus:int="", FlagsMoveRange:int=""):
+ """
+ Performs an initialization move and resets the coordinate system of the Theta
+ axis.
+ API Status: published
+ Args:
+ FlagsDoPlus:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitTheta 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck Theta axis to the specified position. The positive direction is
+ counter-clockwise.
+ API Status: published
+ Args:
+ Position:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Degrees"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveTheta 1000. R E
+ """
+ MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity:str="", Velocity:Decimal=""):
+ """
+ Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+ clockwise. The motion continues until the StopThetaMovement command is received,
+ or the end limit (error condition) is reached. This command is mostly used for
+ joystick movements that do not have a target destination.
+ API Status: published
+ Args:
+ Polarity:str = "Fixed"
+ Velocity:Decimal = 0
+ Command Timeout: 240000
+ Example:MoveThetaVelocity + 67
+ """
+ MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+ """
+ Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+ treated as a smooth stop rather than an emergency stop.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopThetaMovement
+ """
+ MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode:str="", Unit:str="", Position:Decimal=""):
+ """
+ Sets the chuck Theta position to home. This position is usable as reference
+ position for other commands.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Degrees"
+ Position:Decimal = 0
+ Command Timeout: 5000
+ Example:SetThetaHome 0
+ """
+ MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance:Decimal="", TriggerEveryNthCycle:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts moving the chuck from the current position with Velocity [%] over
+ ZDistance (sign is important, as a negative sign will move chuck down during
+ scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+ be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+ until the ZDistance has been reached. Command returns number of positions and
+ all compensated Z Positions from Zero, where the trigger was sent.
+ API Status: internal
+ Args:
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 3
+ Velocity:Decimal = 10
+ Returns:
+ NumberOfPositions:int
+ TriggerPositions:str
+ Command Timeout: 60000
+ Example:ScanChuckZ 300 3 1.5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+ global ScanChuckZ_Response
+ if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+ return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+ """
+ Moves the chuck Z axis to a z height considered safe. This is either the lower
+ Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+ API Status: published
+ Command Timeout: 60000
+ Example:MoveChuckZSafe
+ """
+ MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The mode manages the way the platen behaves when it is in contact height. Platen
+ mode is made up from 5 flags and the user can control all of them by using this
+ command. Every flag can be turned on by setting value 1 or turned off by setting
+ value 0. If no change for a flag is wanted, use the value of 2.
+ API Status: internal
+ Args:
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Command Timeout: 5000
+ Example:SetPlatenMode 2 2 2 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen to the high (0) or low = lifted (1) position. This initiates
+ motion; the actual movement may take some seconds.
+ API Status: internal
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MovePlatenLift 1
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Searches contact height using the edge sensor using a z movement of the platen
+ stage
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ CompLayer:str = "Default"
+ Returns:
+ ContactHeight:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+ return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current platen status.
+ API Status: internal
+ Returns:
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ PresetHeight:str
+ IsLiftDown:int
+ Command Timeout: 10000
+ Example:ReadPlatenStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+ global ReadPlatenStatus_Response
+ if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+ return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the platens X, Y and Z axes. The default
+ compensation is the currently selected compensation for the stage.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenPosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+ global ReadPlatenPosition_Response
+ if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+ return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual settings for the probe Z movement.
+ API Status: internal
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadPlatenHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+ global ReadPlatenHeights_Response
+ if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+ return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the platens X, Y and Z axes. Currently the initialization in
+ negative direction and the move range scan are not supported.
+ API Status: internal
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 120000
+ Example:InitPlaten 4
+ """
+ MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the specified height. If contact is set, only moves
+ up to contact height will be allowed. If overtravel is enabled - up to
+ overtravel height.
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 30000
+ Example:MovePlatenZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a movement of platen Z axis to preset contact height or returns an
+ error, if no contact height is set.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenContact 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the align height. If no contact height is set, the
+ command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen Z axis to the separation height. If no contact height is set,
+ the command will return an error.
+ API Status: internal
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MovePlatenSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the platen stage in velocity mode. The motion continues until the
+ StopPlatenMovement command is received, or the software fence is reached.
+ API Status: internal
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 240000
+ Example:MovePlatenVelocity + + 0 67 50 0
+ """
+ MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the movement of a set of platen axes immediately.
+ API Status: internal
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 10000
+ Example:StopPlatenMovement 4
+ """
+ MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align and separation height. A command without data sets contact height at
+ current position.
+ API Status: internal
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 10000
+ Example:SetPlatenHeight C V Y 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the current status of the manual platen. THis is only supported for
+ Nucleus and Summit200.
+ API Status: internal
+ Returns:
+ IsUp:int
+ IsDown:int
+ IsSafe:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+ global ReadManualPlatenState_Response
+ if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+ return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+ """
+ Returns the current scope status.
+ API Status: published
+ Returns:
+ FlagsInit:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ IsScopeLiftUp:int
+ PresetHeight:str
+ IsScopeLight:int
+ FlagsMode:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadScopeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+ global ReadScopeStatus_Response
+ if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+ return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual scope stage position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadScopePosition Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+ global ReadScopePosition_Response
+ if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+ return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit:str=""):
+ """
+ Returns the actual settings of the focus height, align gap, and separation gap
+ for the scope Z axis.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ FocusHeight:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeHeights Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+ global ReadScopeHeights_Response
+ if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+ return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+ """
+ Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+ the Direction default is XY in minus and Z in plus. Should be used only in cases
+ when the reported coordinates do not correspond to real position of mechanics.
+ Find Move Range starts the initialization in the defined direction and then
+ moves to the other limit and finds the whole range of the axes.
+ API Status: published
+ Args:
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ Command Timeout: 240000
+ Example:InitScope 3 0 0
+ """
+ MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 70000
+ Example:MoveScope 5000 5000 R Y 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves the microscope stage in index steps. If no PositionReference byte is
+ passed the scope will step relative to the wafer home position. ('R' means the
+ step relative to current position).
+ API Status: published
+ Args:
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeIndex 1 1 R 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves the microscope Z axis to the specified height. Default velocity is 100%.
+ API Status: published
+ Args:
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Command Timeout: 120000
+ Example:MoveScopeZ 1000. R Y 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode:int="", FollowMode:int=""):
+ """
+ Scope mode is made up of two flags which can be controlled using this command.
+ Each flag can be turned on by using value 1 or turned off by using value 0. If
+ you do not want to change a flag, use value of 2.
+ API Status: published
+ Args:
+ QuietMode:int = 2
+ FollowMode:int = 2
+ Command Timeout: 5000
+ Example:SetScopeMode 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ Moves the microscope stage in velocity mode. The motion continues until the
+ StopScopeMovement command is received, or the end limit (error condition) is
+ reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+ in minus direction '0' Do not change this axis
+ API Status: published
+ Args:
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Command Timeout: 30000
+ Example:MoveScopeVelocity + + 0 67 100 0
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop:int=""):
+ """
+ Stops scope movement for the given axis. A smooth stop is executed, no emergency
+ stop.
+ API Status: published
+ Args:
+ FlagsStop:int = 7
+ Command Timeout: 5000
+ Example:StopScopeMovement 7
+ """
+ MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the scope Home position in X and Y. It identifies the scope coordinate
+ system for later movements. Usually this position is identical to the die home
+ location.
+ API Status: published
+ Args:
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHome 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the microscope index size. Normally set in relation to the wafer index
+ size.
+ API Status: published
+ Args:
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Command Timeout: 5000
+ Example:SetScopeIndex 5000. 5000. Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ This command defines scope focus height and the corresponding gaps for alignment
+ or separation. No data sets focus height at current position.
+ API Status: published
+ Args:
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeHeight F 0 Y
+ """
+ MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit:str=""):
+ """
+ Returns the actual scope stage index values in X and Y.
+ API Status: published
+ Args:
+ Unit:str = "Microns"
+ Returns:
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeIndex Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+ global ReadScopeIndex_Response
+ if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+ return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity:Decimal=""):
+ """
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 25000
+ Example:MoveScopeFocus 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity:Decimal=""):
+ """
+ Moves the Scope Z axis to the alignment height. If no focus height is set an
+ error will bereturned.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 10000
+ Example:MoveScopeAlign 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity:Decimal=""):
+ """
+ Moves the scope Z axis to the separation height. Returns an error if no focus
+ height is set.
+ API Status: published
+ Args:
+ Velocity:Decimal = 100
+ Command Timeout: 60000
+ Example:MoveScopeSeparation 100
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift:int=""):
+ """
+ Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+ initiates the motion only, the actual movement may take some seconds.
+ API Status: published
+ Args:
+ SetLift:int = 1
+ Command Timeout: 10000
+ Example:MoveScopeLift 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current status of the motorized turret.
+ API Status: internal
+ Returns:
+ IsMoving:int
+ Command Timeout: 5000
+ Example:ReadTurretStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+ return int(rsp[0])
+
+def SelectLens(Lens:int=""):
+ """
+ Parfocality and para-centricity are adjusted according to the stored values.
+ This can be used with manual turrets to compensate for XYZ differences between
+ lenses.
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 30000
+ Example:SelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return the TableID Number of the stored chuck table or create a new table. The
+ ID Number is unique for the name and the chuck. The table itself has a string
+ name, this name is not case sensitive. This command has to be used before all
+ other table commands can be used. Accesses to the table is possible only with an
+ ID Number (name dependet).
+ API Status: internal
+ Args:
+ TableName:str = "ScopeTable"
+ Returns:
+ TableID:int
+ Command Timeout: 5000
+ Example:GetScopeTable ScopeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+ return int(rsp[0])
+
+def MoveScopeTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the microscope stage to the specified X,Y position relative to the per
+ PosRef specified reference position.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Velocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveScopeTablePoint 10 5 67
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read back the scope table site Information for this point from the Kernel.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadScopeTablePoint 2 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+ global ReadScopeTablePoint_Response
+ if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+ return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+ """
+ Returns the number of the current microscope lens.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:ReadCurrentLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+ return int(rsp[0])
+
+def SetScopeTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set one point of the scope table inside of the Kernel. If there is still a point
+ with this index loaded, the Kernel returns an error. Number of positions and
+ number of tables are dependet on the internal memory. All positions are stored
+ persistent, that means after switching power on or off the positions are still
+ available. The table starts with point number 1 and ends with the ID 16. The
+ table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ return int(rsp[0])
+
+def ClearScopeTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of scope table site points in the Kernel. If Start Point is
+ -1 or negative the whole table will be deleted.
+ API Status: internal
+ Args:
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearScopeTablePoint 2 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+ global ClearScopeTablePoint_Response
+ if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+ return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+ """
+ Returns the number of silos in the scope fence. Will be zero if no silos are
+ configured.
+ API Status: published
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadScopeSiloCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+ return int(rsp[0])
+
+def ReadProbeStatus(Probe:int=""):
+ """
+ Returns the current positioner's status.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Returns:
+ ProbeEcho:int
+ FlagsInit:int
+ FlagsMode:int
+ FlagsLimit:int
+ FlagsMoving:int
+ Comp:str
+ Side:str
+ PresetHeight:str
+ IsLiftUp:int
+ IsQuiet:int
+ Command Timeout: 5000
+ Example:ReadProbeStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+ global ReadProbeStatus_Response
+ if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+ return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe:int="", Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual positioner's position in X, Y and Z. The default Compensation
+ Mode is the currently activated compensation mode of the kernel.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadProbePosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+ global ReadProbePosition_Response
+ if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+ return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe:int="", Unit:str=""):
+ """
+ Returns the actual settings for the probe Z movement.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+ global ReadProbeHeights_Response
+ if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe:int="", Side:str=""):
+ """
+ Defines the orientation of the positioner's coordinate system and turns the
+ Y-axis of the probe coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Side:str = "Left"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:OrientProbe 1 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+ return int(rsp[0])
+
+def InitProbe(Probe:int="", FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int="", FlagsInitInPlace:int=""):
+ """
+ Performs an initialization move and resets the coordinate system of the given
+ positioner.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsMoveRange:int = 0
+ FlagsInitInPlace:int = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 120000
+ Example:InitProbe 1 7 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+ return int(rsp[0])
+
+def MoveProbe(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbe 1 1000. 1000. R Y 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeIndex(Probe:int="", XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ XSteps:int = 0
+ YSteps:int = 0
+ PosRef:str = "Home"
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeIndex 1 1 1 R 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+ return int(rsp[0])
+
+def MoveProbeContact(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+ height is set, the kernel will return a 'Contact height not set' error.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeContact 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeAlign(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves the given ProbeHeads Z axis to the align height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeAlign 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeSeparation(Probe:int="", Velocity:Decimal=""):
+ """
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: published
+ Args:
+ Probe:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeSeparation 1 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+ return int(rsp[0])
+
+def MoveProbeZ(Probe:int="", Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+ """
+ Moves a given ProbeHeads Z axis to a defined Z height.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Height:Decimal = 0
+ PosRef:str = "Zero"
+ Unit:str = "Microns"
+ Velocity:Decimal = 100
+ Comp:str = "Default"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeZ 1 1000. R Y 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+ return int(rsp[0])
+
+def MoveProbeLift(Probe:int="", SetLift:int=""):
+ """
+ Moves the positioner to the lower (0) or upper = lifted (1) position. The
+ command initiates the motion only, the whole movement may take some seconds.
+ API Status: published
+ Args:
+ Probe:int = 1
+ SetLift:int = 1
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:MoveProbeLift 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+ return int(rsp[0])
+
+def MoveProbeVelocity(Probe:int="", PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+ """
+ '+' Move this axis into plus direction '-' Move this axis into minus direction
+ '0' Do not change this axis
+ API Status: published
+ Args:
+ Probe:int = 1
+ PolarityX:str = "Fixed"
+ PolarityY:str = "Fixed"
+ PolarityZ:str = "Fixed"
+ VelocityX:Decimal = 100
+ VelocityY:Decimal = 0
+ VelocityZ:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeVelocity 1 + + Z 67 100 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+ return int(rsp[0])
+
+def StopProbeMovement(Probe:int="", FlagsStop:int=""):
+ """
+ Stops positioner movement for the given axes immediately. A smooth stop is
+ performed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ FlagsStop:int = 7
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:StopProbeMovement 1 7
+ """
+ rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+ return int(rsp[0])
+
+def SetProbeMode(Probe:int="", Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+ """
+ The mode manages the way the chuck behaves when it is in contact height.
+ Positioner mode is made up from 5 flags and the user can control all of them by
+ using this command. Every flag can be turned on by setting value 1, or turned
+ off by setting value 0. Use the value 2 if no change for a flag is needed.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Overtravel:int = 2
+ AutoZ:int = 2
+ Interlock:int = 2
+ AutoZFollow:int = 2
+ AutoQuiet:int = 2
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeMode 1 2 2 2 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+ return int(rsp[0])
+
+def SetProbeHome(Probe:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the positioner's Home position in X and Y. This position identifies the
+ probe coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetProbeIndex(Probe:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the positioner's index size or the location of the reference die relative
+ to the home die.
+ API Status: published
+ Args:
+ Probe:int = 1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetProbeHeight(Probe:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Defines the predefined contact height and corresponding gaps for overtravel,
+ align, load and separation height. No data sets contact height at current
+ position.
+ API Status: published
+ Args:
+ Probe:int = 1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 5000
+ Example:SetProbeHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadProbeIndex(Probe:int="", Unit:str=""):
+ """
+ Returns the current positioner's wafer index values or the current positioner's
+ index positions for X and Y.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+ global ReadProbeIndex_Response
+ if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+ return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe:int="", NewLEDState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the positioner LED On or Off.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ NewLEDState:int = 0
+ Returns:
+ ProbeEcho:int
+ LEDState:int
+ Command Timeout: 5000
+ Example:SetProbeLED 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+ global SetProbeLED_Response
+ if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+ return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe:int="", TableName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the ID of a stored probe table or creates a new table. The ID is unique
+ for the name and the probe. The table itself has a string name. This name is not
+ case sensitive. The command has to be used before all other table commands can
+ be used. Access to tables is possible only with an ID Number (name dependent).
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableName:str = "ProbeTable"
+ Returns:
+ ProbeEcho:int
+ TableID:int
+ Command Timeout: 5000
+ Example:GetProbeTableID 1 ProbeTable
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+ global GetProbeTableID_Response
+ if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+ return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves a defined positioner to a X, Y position relative to a per PosRef specified
+ reference position. Notifications: 51 / 52 / 5
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 1
+ PointID:int = 1
+ Velocity:Decimal = 100
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 30000
+ Example:MoveProbeTablePoint 3 14 10 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+ return int(rsp[0])
+
+def ReadProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads the data from a point of a stored table in the Kernel.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ Unit:str = "Microns"
+ Returns:
+ ProbeEcho:int
+ CoordX:Decimal
+ CoordY:Decimal
+ CoordSystem:str
+ Command Timeout: 5000
+ Example:ReadProbeTablePoint 2 4 10 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+ global ReadProbeTablePoint_Response
+ if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+ return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+ point with this index loaded, the Kernel returns an error. Number of positions
+ and number of tables are dependet on the internal memory. All positions are
+ stored persistent, that means after switching power on or off the positions are
+ still available. The table starts with point number 1 and ends with the ID 16.
+ The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+ position points is not possible. The point has to be deleted before other values
+ are set.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ PointID:int = 0
+ CoordX:Decimal = 0
+ CoordY:Decimal = 0
+ Unit:str = "Microns"
+ CoordSystem:str = "HomeSystem"
+ Returns:
+ ProbeEcho:int
+ ValidPoint:int
+ Command Timeout: 5000
+ Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+ global SetProbeTablePoint_Response
+ if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+ return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe:int="", TableID:int="", StartPoint:int="", EndPoint:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+ is a negative value, the whole table will be deleted.
+ API Status: internal
+ Args:
+ Probe:int = 1
+ TableID:int = 0
+ StartPoint:int = -1
+ EndPoint:int = 0
+ Returns:
+ ProbeEcho:int
+ ClearNumber:int
+ ValidNumber:int
+ Command Timeout: 5000
+ Example:ClearProbeTablePoint 3 4 10 15
+ """
+ rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+ global ClearProbeTablePoint_Response
+ if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+ return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index:int=""):
+ """
+ Move the scope to the reference position of the given silo. The reference
+ position should be - if not defined otherwise - 200 um above the safe z-height
+ in the center of the scope.
+ API Status: published
+ Args:
+ Index:int = 1
+ Command Timeout: 70000
+ Example:MoveScopeSilo 1
+ """
+ MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index:int="", X:Decimal="", Y:Decimal="", Z:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the reference position of a silo. The next time the scope moves to this
+ silo, it woll go to this position. The Referenceposition must be inside the silo
+ in xy and above the lower Z-Fence of the silo. Setting the reference position
+ directly on the fence in x, y or z typically leads to errors. Try to keep a
+ safety margin.
+ API Status: internal
+ Args:
+ Index:int = 1
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ Command Timeout: 5000
+ Example:SetScopeSiloReference 1 1000 2000 3000
+ """
+ MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a chuck Theta axis rotation to align the wafer to the chuck
+ X,Y movements. It can be used to perform a two point alignment with
+ P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line. The units of
+ the distances are not important - but both distances should use the same unit.
+ If one or both distances are zero, the command does not return an error and
+ instead ignore this alignment
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignChuckTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a virtual rotation of the scope coordinate system to align
+ the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of X and Y distances:
+ API Status: published
+ Args:
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignScopeTheta 10000 10 R
+ """
+ MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe:int="", XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+ """
+ This command causes a rotation of the coordinate system of given probe to align
+ the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+ perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+ Calculation of Y and Y distances:
+ API Status: published
+ Args:
+ Probe:int = 1
+ XDistance:Decimal = 0
+ YDistance:Decimal = 0
+ PosRef:str = "Relative"
+ Returns:
+ ProbeEcho:int
+ Command Timeout: 10000
+ Example:AlignProbeTheta 1 10000 10 R
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+ return int(rsp[0])
+
+def AlignCardTheta(Angle:Decimal="", Unit:str="", PosRef:str=""):
+ """
+ This command causes a rotation of the chuck coordinate system to align the chuck
+ X, Y axis to the probecard. The polarity of the data determines a left or a
+ right rotation of the chuck coordinate system.
+ API Status: published
+ Args:
+ Angle:Decimal = 0
+ Unit:str = "Degrees"
+ PosRef:str = "Relative"
+ Command Timeout: 10000
+ Example:AlignCardTheta 2.5 D R
+ """
+ MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit:str=""):
+ """
+ Returns the angle between the chuck-coordinate-system and the probecard-
+ coordinate-system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadCardTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit:str=""):
+ """
+ Returns the current chuck alignment angle which is identical to the current
+ value of theta rotation.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadChuckTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit:str=""):
+ """
+ Returns the scope's alignment angle, which is the angle between the chuck
+ coordinate system and the scope coordinate system.
+ API Status: published
+ Args:
+ Unit:str = "Degrees"
+ Returns:
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeTheta D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+ return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe:int="", Unit:str=""):
+ """
+ Returns the actual positioner's alignment angle, which is the angle between the
+ chuck coordinate system and the positioner coordinate system.
+ API Status: published
+ Args:
+ Probe:int = 1
+ Unit:str = "Degrees"
+ Returns:
+ ProbeEcho:int
+ Angle:Decimal
+ Command Timeout: 5000
+ Example:ReadProbeTheta 1 D
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+ global ReadProbeTheta_Response
+ if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+ return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the preset speeds, which are used by the joystick controller for moving a
+ single stage. The speeds can be read for XY, for Z and for Theta axis
+ separately. Jog timing and index timing are the times, the joystick controller
+ waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "X"
+ Returns:
+ JogTime:Decimal
+ Speed2:Decimal
+ Speed3:Decimal
+ Speed4:Decimal
+ IndexTime:Decimal
+ Command Timeout: 5000
+ Example:ReadJoystickSpeeds S Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+ global ReadJoystickSpeeds_Response
+ if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+ return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage:str="", JogTime:Decimal="", Speed2:Decimal="", Speed3:Decimal="", Speed4:Decimal="", IndexTime:Decimal="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the preset speeds, which are used by the joystick controller for moving a
+ single stage. After setting, the speeds can be selected by pressing the Speed n
+ buttons at the controller. The speeds must be set separately for XY, for Z and
+ for Theta axis. Jog timing and index timing are the times, the joystick
+ controller waits between two single jog or index moves.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ JogTime:Decimal = 0
+ Speed2:Decimal = 0
+ Speed3:Decimal = 0
+ Speed4:Decimal = 0
+ IndexTime:Decimal = 0
+ Axis:str = "X"
+ Command Timeout: 5000
+ Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open:int=""):
+ """
+ Opens or closes the loader gate. Automatic handling systems can load wafers to
+ the chuck through the gate.
+ API Status: published
+ Args:
+ Open:int = 0
+ Command Timeout: 5000
+ Example:SetLoaderGate 0
+ """
+ MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+ """
+ Returns whether the system detected a wafer. This feature can be used if the
+ probe station is equipped with a vacuum sensor and while vacuum is activated.
+ API Status: published
+ Returns:
+ SensedByVac:str
+ Command Timeout: 5000
+ Example:ReadWaferStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage:str=""):
+ """
+ Returns the number of times this stage moved to contact since the last time the
+ counter was reset.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Count:int
+ Command Timeout: 5000
+ Example:ReadContactCount C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+ return int(rsp[0])
+
+def ResetContactCount(Stage:str=""):
+ """
+ Resets the contact counter for the specified stage to zero. Notifications: 23
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Command Timeout: 5000
+ Example:ResetContactCount C
+ """
+ MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command enables the manual mode on Elite/Summit/S300 systems. This mode
+ will allow to move the chuck using the knobs.
+ API Status: internal
+ Args:
+ Enable:int = 1
+ Command Timeout: 10000
+ Example:SetManualMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of the manual mode on Elite/Summit/S300 stations.
+ API Status: internal
+ Returns:
+ Enable:int
+ Command Timeout: 10000
+ Example:GetManualMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+ return int(rsp[0])
+
+def GetAxisReverse(Stage:str="", Axis:str=""):
+ """
+ Allows reading if an axis is reverse.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ IsReverse:int
+ Command Timeout: 5000
+ Example:GetAxisReverse C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+ return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor:int="", Enable:int=""):
+ """
+ Enables/disables the use of an edge sensor.
+ API Status: published
+ Args:
+ EdgeSensor:int = 1
+ Enable:int = 1
+ Command Timeout: 5000
+ Example:EnableEdgeSensor 1 1
+ """
+ MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel:str="", WantOutputOn:int="", PulseTime:int=""):
+ """
+ Controls the kernel valve driver signals and can be used to drive the outputs.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ WantOutputOn:int = 0
+ PulseTime:int = -1
+ Command Timeout: 5000
+ Example:SetTypedOutput WaferVacuum 1
+ """
+ MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel:str=""):
+ """
+ Returns the status of the specified input channel, output channel, or edge
+ sensor.
+ API Status: published
+ Args:
+ Channel:str = "NoSensor"
+ Returns:
+ IsSensorOn:int
+ Command Timeout: 10000
+ Example:ReadTypedSensor EmoIn I
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+ return int(rsp[0])
+
+def MoveCoolDownPosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck to the cool down position that is defined in KernelSetup. The
+ cooldown position is used to move the chuck away in XY while the robot is in the
+ chamber and tries to get a hot wafer.
+ API Status: internal
+ Command Timeout: 30000
+ Example:MoveCoolDownPosition
+ """
+ MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the cycling speeds - these are the speeds that are used by
+ the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ CycleJog:int
+ CycleSpeed2:int
+ CycleSpeed3:int
+ CycleSpeed4:int
+ CycleIndex:int
+ Command Timeout: 5000
+ Example:ReadJoystickSpeedsCycle S
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+ global ReadJoystickSpeedsCycle_Response
+ if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+ return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage:str="", CycleJog:int="", CycleSpeed2:int="", CycleSpeed3:int="", CycleSpeed4:int="", CycleIndex:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets the cycling speeds - these are the speeds that are used by the
+ USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CycleJog:int = 0
+ CycleSpeed2:int = 0
+ CycleSpeed3:int = 0
+ CycleSpeed4:int = 0
+ CycleIndex:int = 0
+ Command Timeout: 5000
+ Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+ """
+ MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows sending low level AUCS commands to the ECX box stage. Only
+ applies to Elite/Summit/S300 stations.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 60000
+ Example:SendAUCSCommand "MM 1 0 INIT 0"
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage:str="", Compensation:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command allows reading if a specific type of compensation is enabled or
+ disabled. Returns an error if this type of compensation is not available for
+ this stage.
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Returns:
+ Enabled:int
+ Active:int
+ Command Timeout: 5000
+ Example:ReadCompensationStatus C A
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+ global ReadCompensationStatus_Response
+ if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+ return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode:int="", WantNotification:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deprecated. All Kernel notifications are now enabled by default.
+ API Status: internal
+ Args:
+ NotificationCode:int = 0
+ WantNotification:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId:int="", Value1:Decimal="", Value2:Decimal="", Value3:Decimal=""):
+ """
+ This is not a regular command. Asynchronous notifications will be sent from the
+ Kernel controller to the host system only. All notifications can be switched off
+ and on, except the Prober reset notification (ID01). /warning This is a stub
+ implementation without appropriate handling
+ API Status: published
+ Args:
+ NotificationId:int = 0
+ Value1:Decimal = 0
+ Value2:Decimal = 0
+ Value3:Decimal = 0
+ Command Timeout: 5000
+ Example:AlertNotification 31 195000 160000 0
+ """
+ MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage:str="", Compensation:str="", Status:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables a compensation mode for the specified stage
+ API Status: internal
+ Args:
+ Stage:str = "None"
+ Compensation:str = "None"
+ Status:int = -1
+ Command Timeout: 5000
+ Example:SetCompensationStatus C A 1
+ """
+ MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command gets the value "Value" for the parameter "Parameter". The unit is
+ parameter specific.
+ API Status: internal
+ Args:
+ ControllerInfo:str = "Unknown"
+ Returns:
+ Value:Decimal
+ Command Timeout: 1000
+ Example:GetControllerInfo HasScanChuckZ
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+ return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ In unprotected mode a number of security features like software fence and
+ initialization necessity are deactivated. Unprotected mode is
+ deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+ anytime before resets the timer back to 5 minutes. It is not necessary to
+ deactivate it before. **WARNING**: If unprotected mode is enabled, even the
+ most basic safety- and sanity-checks are skipped. Any movement may cause
+ irreparable damage to the prober or attached hardware.
+ API Status: internal
+ Args:
+ OperationalMode:str = "ProtectedMode"
+ Command Timeout: 5000
+ Example:SetOperationalMode P
+ """
+ MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured Nano-chamber-state.
+ API Status: internal
+ Returns:
+ NanoChamberState:str
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the NanoChamber-state.
+ API Status: internal
+ Args:
+ NanoChamberState:str = "Free"
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows to force activate/deactivate the camera cool output or to let it be set
+ automatically by purge control.
+ API Status: internal
+ Args:
+ State:int = 2
+ Command Timeout: 10000
+ Example:SetCameraCool 0
+ """
+ MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the chuck vacuum and forces it to be on. This command ignores the
+ vacuum sensor and timeout.
+ API Status: internal
+ Command Timeout: 10000
+ Example:ActivateChuckVacuum
+ """
+ MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns a point from the matrix compensation table for the
+ specified axis from the kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ Returns:
+ XVal:Decimal
+ YVal:Decimal
+ Command Timeout: 5000
+ Example:ReadMatrixValues C 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+ global ReadMatrixValues_Response
+ if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+ return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int="", XVal:Decimal="", YVal:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Downloads a point of the matrix compensation table for a specified stage to the
+ kernel. All command parameters are mandatory.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ MatrixIndexX:int = 0
+ MatrixIndexY:int = 0
+ XVal:Decimal = 0
+ YVal:Decimal = 0
+ Command Timeout: 5000
+ Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+ """
+ MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage:str="", Type:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+ only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Returns:
+ Enable:int
+ Command Timeout: 5000
+ Example:ReadMEAStatus C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+ return int(rsp[0])
+
+def LoadMEAFile(Stage:str="", Type:int="", Load:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Load the MEA file for a stage (Nucleus legacy stations only)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Type:int = 0
+ Load:int = 0
+ Command Timeout: 5000
+ Example:LoadMEAFile C 0 1
+ """
+ MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The command returns the positions of the actual software limits (end of move
+ range) for each axis of the specified stage in microns. If the Theta stage is
+ selected Z1 and Z2 include the values for the Theta limits.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ ZLowValue:Decimal
+ ZHighValue:Decimal
+ X1Value:Decimal
+ Y1Value:Decimal
+ X2Value:Decimal
+ Y2Value:Decimal
+ X3Value:Decimal
+ Y3Value:Decimal
+ X4Value:Decimal
+ Y4Value:Decimal
+ Command Timeout: 5000
+ Example:ReadSoftwareLimits C
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+ global ReadSoftwareLimits_Response
+ if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+ return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage:str="", AuxID:int="", FenceForm:str="", XBase:Decimal="", YBase:Decimal="", XDist:Decimal="", YDist:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command sets types and dimensions of technological software fences. It can
+ also be used for enabling and disabling the software fence.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ FenceForm:str = "None"
+ XBase:Decimal = 0
+ YBase:Decimal = 0
+ XDist:Decimal = 0
+ YDist:Decimal = 0
+ Command Timeout: 10000
+ Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage:str="", AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the type and the dimensions of an actual set technological
+ software fence. In case of a rectangular software fence, X and Y coordinates of
+ the four edge points of the fence are given back. In case of a circular software
+ fence, X and Y coordinates of the center point and the radius are given back.
+ All other return values are filled with zeros. All position values are in
+ microns from zero.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxID:int = 0
+ Returns:
+ FenceForm:str
+ XValue1:Decimal
+ YValue1:Decimal
+ XValue2:Decimal
+ YValue2:Decimal
+ XValue3:Decimal
+ YValue3:Decimal
+ XValue4:Decimal
+ YValue4:Decimal
+ Command Timeout: 10000
+ Example:GetSoftwareFence C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+ global GetSoftwareFence_Response
+ if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+ return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage:str="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands reads if the Z-Fence is activated and the currently set Z-fence
+ values for the specified stage.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ CompLayer:str = "Default"
+ Returns:
+ Enabled:int
+ ZLow:Decimal
+ ZHigh:Decimal
+ Command Timeout: 10000
+ Example:GetZFence S
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+ global GetZFence_Response
+ if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+ return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage:str="", Enabled:int="", ZLow:Decimal="", ZHigh:Decimal="", CompLayer:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This commands sets Z-Fence and the Z-fence values for the specified stage.
+ Values are stored uncompensated internally and set default compensated as
+ default.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Enabled:int = 0
+ ZLow:Decimal = 0
+ ZHigh:Decimal = 0
+ CompLayer:str = "Default"
+ Command Timeout: 10000
+ Example:SetZFence S 1 5000 10000
+ """
+ MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the Prober and replaces the current configuration with a formerly
+ written recovery file. If no recovery file was written, the configuration is
+ reset to the version of the last Prober restart. For ProberBench electronics,
+ 'H' will restart the Operating system, 'S' will only restart the Kernel
+ application. For Windows Kernel, 'H' and 'S' are identical.
+ API Status: internal
+ Args:
+ Mode:str = "S"
+ Command Timeout: 20000
+ Example:ResetProber S
+ """
+ MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reboots the operation system inside the Joystick Controller and restarts the
+ functionality. The restart will need a time of around 20 seconds.
+ API Status: internal
+ Args:
+ ResetMode:str = "S"
+ Command Timeout: 20000
+ Example:ResetCBox S
+ """
+ MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage:str="", LocationType:str="", AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The Home Position on the Chuck or ProbeHead Z axis is also called contact
+ height. The Home Position on the Scope Z axis is also called focus height.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ LocationType:str = "Center"
+ AuxID:int = 0
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 5000
+ Example:ReadStageLocations C C 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+ global ReadStageLocations_Response
+ if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+ return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters.
+ and requires the GetNextDatum command.
+ API Status: internal
+ Args:
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 10000
+ Example:GetDataIterator 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+ global GetDataIterator_Response
+ if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ Attributes:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:GetNextDatum 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+ global GetNextDatum_Response
+ if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+ return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:SetDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ PathName:str = ""
+ Returns:
+ Attributes:int
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:GetDatum Chuck:AlignGap
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+ global GetDatum_Response
+ if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+ return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ PathNameAndValue:str = ""
+ Command Timeout: 5000
+ Example:SetRecoveryDatum Chuck:AlignGap:25
+ """
+ MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the motion recording. The recording parameters are set in dynamic
+ kernel setup.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStart C
+ """
+ MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Checks the motion recording status for one stage.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Returns:
+ IsReady:int
+ SizeCh0Raw:int
+ SizeCh0Comp:int
+ SizeCh1Raw:int
+ SizeCh1Comp:int
+ SizeCh2Raw:int
+ SizeCh2Comp:int
+ SizeCh3Raw:int
+ SizeCh3Comp:int
+ Command Timeout: 10000
+ Example:TraceStatus C
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+ global TraceStatus_Response
+ if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+ return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller:str="", Channel:int="", PointOne:int="", IsCompress:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a collection of five data pairs. A pair is the index and the value of a
+ recording point. If the stream is empty or at the end the index is 1 and the
+ value 0. The index is relative to the start of the motion recording. The
+ recording is clocked by the motion controller cycle. The cycle time is contained
+ in the Kernel setup. In the raw stream all recorded trace points are contained.
+ But in the compressed stream only the non-linear depending trace points are
+ contained. To reload the recording points the stream must be reset to the first
+ recording point.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ PointOne:int = 1
+ IsCompress:int = 1
+ Returns:
+ Point1:int
+ Value1:int
+ Point2:int
+ Value2:int
+ Point3:int
+ Value3:int
+ Point4:int
+ Value4:int
+ Point5:int
+ Value5:int
+ Command Timeout: 10000
+ Example:TraceGetData C 0 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+ global TraceGetData_Response
+ if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+ return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller:str="", Channel:int="", NewPos:int="", IsCompress:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the index position in the raw or compressed stream for the next call of the
+ command TraceGetData.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Channel:int = 0
+ NewPos:int = 0
+ IsCompress:int = 1
+ Command Timeout: 10000
+ Example:TraceSetDataPosition C 0 1000 1
+ """
+ MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the motion recording.
+ API Status: internal
+ Args:
+ Controller:str = "Chuck"
+ Command Timeout: 10000
+ Example:TraceStop C
+ """
+ MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage:str="", XValue:Decimal="", YValue:Decimal="", ZGap:Decimal="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set a point for the Z height profile. If this profile is enabled, the Z height
+ depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+ Positive values are elevated spots, negative values are hollows. The height
+ profile is used to adjust the Z height. The adjusted Z height at a X and Y
+ position is derivated from the nearest profile point. The Z contact level will
+ be calculated from the contact height and the stored Z gap at this point. See
+ GetZProfilePoint for details.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZGap:Decimal = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ ValueCount:int
+ Command Timeout: 5000
+ Example:SetZProfilePoint C 5000 5000 -3 H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+ return int(rsp[0])
+
+def ReadZProfilePoint(Stage:str="", Index:int="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get a single point and the corresponding Z gap of the Z height profile. The
+ different z profiles are: - transient: meant to be used on a per-wafer-basis,
+ default - persistent: configured once, stays in memory - persistent-offset: same
+ as persistent, active when offset is enabled - scratch: not used internaly. Can
+ be used to translate KernelDatums <-> ZProfile-Points
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Index:int = 0
+ PosRef:str = "Home"
+ Unit:str = "Microns"
+ ZProfileType:int = 0
+ Returns:
+ XValue:Decimal
+ YValue:Decimal
+ ZGap:Decimal
+ ValueCount:int
+ Command Timeout: 5000
+ Example:ReadZProfilePoint C 1 H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+ global ReadZProfilePoint_Response
+ if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+ return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage:str="", ZProfileType:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Clears all profile points. See GetZProfile for type description.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZProfileType:int = 0
+ Command Timeout: 5000
+ Example:ClearZProfile C
+ """
+ MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index:int=""):
+ """
+ Returns the definition of a silo. If the type is rectangle, center means
+ _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+ API Status: published
+ Args:
+ Index:int = 1
+ Returns:
+ Type:str
+ CenterX:Decimal
+ CenterY:Decimal
+ Radius:Decimal
+ Pos2X:Decimal
+ Pos2Y:Decimal
+ ZHigh:Decimal
+ RefX:Decimal
+ RefY:Decimal
+ RefZ:Decimal
+ Command Timeout: 5000
+ Example:ReadScopeSilo 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+ global ReadScopeSilo_Response
+ if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+ return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName:str=""):
+ """
+ Alerts applications if the project file was changed.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName:str=""):
+ """
+ Alerts applications to save the current project. This notification _MUST_ only
+ be invoked by CommonCommands. Sending this notification directly _WILL_ give
+ erroneous results.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel:str="", UserName:str="", VeloxLocked:int=""):
+ """
+ Alerts applications of new access level.
+ API Status: published
+ Args:
+ AccessLevel:str = "Engineer"
+ UserName:str = ""
+ VeloxLocked:int = 0
+ Command Timeout: 5000
+ Example:NewAccessLevel 1
+ """
+ MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled:int="", AnnualDaysLeft:int="", VeloxProEnabled:int="", VueTrackEnabled:int="", VueTrack4PEnabled:int="", ReAlignEnabled:int="", AutomationEnabled:int="", IdToolsEnabled:int="", IVistaEnabled:int="", IVistaProEnabled:int="", LaserCutterEnabled:int="", SiPToolsEnabled:int="", AutoRfEnabled:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener about the licensed Velox features. Is sent cyclically by
+ CommonCommands.
+ API Status: internal
+ Args:
+ AnnualEnabled:int = 1
+ AnnualDaysLeft:int = 460
+ VeloxProEnabled:int = 0
+ VueTrackEnabled:int = 0
+ VueTrack4PEnabled:int = 0
+ ReAlignEnabled:int = 0
+ AutomationEnabled:int = 0
+ IdToolsEnabled:int = 0
+ IVistaEnabled:int = 0
+ IVistaProEnabled:int = 0
+ LaserCutterEnabled:int = 0
+ SiPToolsEnabled:int = 0
+ AutoRfEnabled:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName:str="", SecName:str="", NewRegistered:int=""):
+ """
+ Alerts applications that an application is registered or unregistered on
+ MsgServer.
+ API Status: published
+ Args:
+ AppName:str = "SharedTest"
+ SecName:str = "SharedTest"
+ NewRegistered:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications of a change of the current alignment mode
+ API Status: internal
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ Example:AlignmentModeChange OnAxis
+ """
+ MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum:int="", Type:str="", Result:str="", Desc:str=""):
+ """
+ An example of Kernel Connection Status is "Windows Socket Error Number and
+ Error Description."
+ API Status: published
+ Args:
+ ControllerNum:int = 1
+ Type:str = "Socket"
+ Result:str = "Disconnected"
+ Desc:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage:str="", Compensation:str="", Enabled:int="", Active:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Compensation:str = "None"
+ Enabled:int = 0
+ Active:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage:str="", Comp:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Alerts applications that a Kernel compensation level has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Comp:str = "None"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status:str="", PlatenSafe:int="", Height:Decimal="", HeightMax:Decimal="", HeightRelative:Decimal="", SafeHeight:Decimal="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the combined-z-move-system
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ PlatenSafe:int = 0
+ Height:Decimal = 0
+ HeightMax:Decimal = 0
+ HeightRelative:Decimal = 0
+ SafeHeight:Decimal = 0
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies about changes in the machine state
+ API Status: internal
+ Args:
+ MachineState:str = "Off"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if the user requests a chuck vacuum change
+ API Status: internal
+ Args:
+ VacuumState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies if software stop was activated or deactivated
+ API Status: internal
+ Args:
+ SoftwareStopState:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet:int="", Stage:str="", IsStageQuiet:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs if the overall quiet mode changes and about changes of single stages
+ API Status: internal
+ Args:
+ IsQuiet:int = 0
+ Stage:str = "None"
+ IsStageQuiet:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies that a configuration item has changed by some application
+ API Status: internal
+ Args:
+ ParameterChanged:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Informs that a new working stage is active
+ API Status: internal
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage:str="", Axis:str="", State:str="", AdditionalStateInfo:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the user Interface and Kernel if the state of the axis has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ State:str = "NotExisting"
+ AdditionalStateInfo:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the stage status has changed.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an input channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel:str="", State:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state of an output channel has changed.
+ API Status: internal
+ Args:
+ Channel:str = "0"
+ State:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage:str="", Axis:str="", Initialized:int="", PositiveLimit:int="", NegativeLimit:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifys the listener that an axis status has changed. Currently used to notify
+ the Kernel about the init state of a BnR axis.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Initialized:int = 0
+ PositiveLimit:int = 0
+ NegativeLimit:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+ AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+ when stepping.
+ API Status: internal
+ Args:
+ AutoXYModeOn:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+ handle this so it doesn't have to poll OpticalControl for the current zoom
+ level.
+ API Status: internal
+ Args:
+ ZoomLevel:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO:str="", ValuePercent:Decimal="", UnderOverflow:int="", Error:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notify the listener that the state or value of an analog input or output channel
+ has changed.
+ API Status: internal
+ Args:
+ AnalogIO:str = "AO_PurgeDewPoint"
+ ValuePercent:Decimal = 0
+ UnderOverflow:int = 0
+ Error:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum:int="", ControllerInfo:str="", Value:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notifies the listener about changed controller info. Currently used to inform
+ Toolbar about the battery state of the BnR controller.
+ API Status: internal
+ Args:
+ ControllerNum:int = 1
+ ControllerInfo:str = "BatteryOK"
+ Value:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage:str="", XorT:Decimal="", Y:Decimal="", Z:Decimal="", CommandedXorT:Decimal="", CommandedY:Decimal="", CommandedZ:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by BnR controller if a axis position has changed. Currently
+ used to notify the Kernel about the new axis position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XorT:Decimal = 0
+ Y:Decimal = 0
+ Z:Decimal = 0
+ CommandedXorT:Decimal = 0
+ CommandedY:Decimal = 0
+ CommandedZ:Decimal = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType:str="", Info:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Generic Information Notification
+ API Status: internal
+ Args:
+ InfoType:str = ""
+ Info:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX:int="", DieY:int="", XFromHome:Decimal="", YFromHome:Decimal="", CurSite:int="", LastSiteIndex:int=""):
+ """
+ Alerts applications that WaferMap has a new position.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ XFromHome:Decimal = 0
+ YFromHome:Decimal = 0
+ CurSite:int = 1
+ LastSiteIndex:int = 1
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+ """
+ Alerts applications that a wafer's parameters have been changed.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+ the identifier for the button as defined for the guided workflow.
+ API Status: internal
+ Args:
+ TargetIdent:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State:str="", Error:int="", ErrorDescription:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sent when the cooling or heating process was terminated successfully or
+ incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+ COOL DOWN, WARMUP) and sends the error code and error message.
+ API Status: internal
+ Args:
+ State:str = "IDLE"
+ Error:int = 0
+ ErrorDescription:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent when Spectrum VS project has finished loading.
+ API Status: internal
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access:str="", FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent when a probe card file is loaded.
+ API Status: internal
+ Args:
+ Access:str = "L"
+ FileName:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+ """
+ Alerts applications that the TTL Test is ready.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State:str="", SubState:str="", Message:str="", Error:int=""):
+ """
+ Notification sent when VeloxPro changes its running state.
+ API Status: published
+ Args:
+ State:str = "Unknown"
+ SubState:str = "Unknown"
+ Message:str = ""
+ Error:int = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification sent during wafer stepping process. It updates the progress
+ information. 'Progress' is the relationship of dies tested to dies to be tested.
+ API Status: internal
+ Args:
+ ProgressPercent:Decimal = 0
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader:int="", UseAutoWafer:int="", WaferSizes:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent to notify the listener about usage of Loader, usage of
+ fully/semiautomatic mode and supported wafer sizes of process station.
+ API Status: internal
+ Args:
+ UseLoader:int = 0
+ UseAutoWafer:int = 0
+ WaferSizes:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Notification is sent by loader to display a message on the process station.
+ API Status: internal
+ Args:
+ Message:str = ""
+ Command Timeout: 30000
+ """
+ MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename:str="", Option:int=""):
+ """
+ Asks if the current project should be saved and then brings up the Open Project
+ window which opens the selected project file if the user clicks ok.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Option:int = 0
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+ """
+ Brings up the Save Project window which saves the project if the user clicks ok.
+ API Status: published
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer:str=""):
+ """
+ Brings up the Login window and sends a New Access Level alert if the user enters
+ a valid password.
+ API Status: published
+ Args:
+ LevelToOffer:str = "1"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+ """
+ Returns the current software status. The server holds and maintains the software
+ status. Status can be changed by using any of the following commands:
+ BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+ UnloadWafer, ResumeProbing
+ API Status: published
+ Returns:
+ DummyCommonMode:int
+ RunningMode:str
+ AccessLevel:str
+ ExternalMode:int
+ LicenseDaysLeft:int
+ MKH:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetStatus")
+ global GetStatus_Response
+ if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+ return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Licensing window.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current license information.
+ API Status: internal
+ Returns:
+ AnnualEnabled:int
+ AnnualDaysLeft:int
+ VeloxProEnabled:int
+ VueTrackEnabled:int
+ VueTrack4PEnabled:int
+ ReAlignEnabled:int
+ AutomationEnabled:int
+ IdToolsEnabled:int
+ IVistaEnabled:int
+ IVistaProEnabled:int
+ LaserCutterEnabled:int
+ SiPToolsEnabled:int
+ AutoRfEnabled:int
+ SecsGemEnabled:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+ global GetLicenseInfo_Response
+ if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+ return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+ """
+ Returns the current project file.
+ API Status: published
+ Returns:
+ ProjectFilename:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+ """
+ Returns the Velox software version as string.
+ API Status: published
+ Returns:
+ SoftwareVersion:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename:str=""):
+ """
+ The OpenProject command opens the specified project.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application:str=""):
+ """
+ Checks the server to see if the application "AppName" is registered with the
+ server.
+ API Status: published
+ Args:
+ Application:str = ""
+ Returns:
+ IsAppRegistered:int
+ Command Timeout: 5000
+ Example:IsAppRegistered WaferMap
+ """
+ rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+ return int(rsp[0])
+
+def SaveProject(ProjectFilename:str=""):
+ """
+ Saves the current data to the project file.
+ API Status: published
+ Args:
+ ProjectFilename:str = ""
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType:str=""):
+ """
+ Returns the path for either the applications/data or project files.
+ API Status: published
+ Args:
+ PathType:str = "User"
+ Returns:
+ SoftwarePath:str
+ Command Timeout: 5000
+ Example:GetSoftwarePath User
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command.
+ API Status: internal
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:CCSelectLens 1
+ """
+ MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Internal AZoom Helper Command. Probably no longer used.
+ API Status: internal
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+ return int(rsp[0])
+
+def CCMoveAuxSite(AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calls the Kernel command MoveAuxSite to move the chuck to the
+ position of a given AUX site. For the transfer move a safe height is used. If
+ AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+ Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+ command AlignAux is executed after MoveAuxSite to align the site automatically.
+ The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+ installed. AUX ID in the response is the ID of the new active site.
+ API Status: internal
+ Args:
+ AuxID:int = 1
+ Command Timeout: 200000
+ """
+ MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName:str="", AllowMediaReuse:int="", SkipAlignAux:int="", SkipReturnMove:int=""):
+ """
+ This command moves to the single cleaning site, executes CleanProbeTip, moves to
+ the contact verify site, and then moves to contact. Returns an error if the
+ clean or verify sites aren't defined.
+ API Status: published
+ Args:
+ SequenceName:str = ""
+ AllowMediaReuse:int = 0
+ SkipAlignAux:int = 0
+ SkipReturnMove:int = 0
+ Command Timeout: 1800000
+ Example:ExecuteCleaningSequence "DeepClean"
+ """
+ MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+ """
+ Get the active alignment mode (either on axis or off axis).
+ API Status: published
+ Returns:
+ AlignmentMode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode:str=""):
+ """
+ Sets the active alignment mode (either on axis or off axis).
+ API Status: published
+ Args:
+ AlignmentMode:str = "OnAxis"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName:str=""):
+ """
+ Gets the Velox user data: name, full name, group, access level. If the
+ commanded user name is empty, the data of the current user will be responded
+ API Status: published
+ Args:
+ CmdUserName:str = ""
+ Returns:
+ UserName:str
+ LongUserName:str
+ UserGroup:str
+ AccessLevel:str
+ VeloxLocked:int
+ Command Timeout: 5000
+ Example:GetLoginData
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+ global GetLoginData_Response
+ if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+ return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to warn user of chuck initialization for Nucleus stations.
+ Allows user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up message box to allow saving project before shutting down Velox. Allows
+ user to OK/Cancel.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCal command to WinCal.
+ API Status: internal
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCheckAutoRFStability command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Returns:
+ StabilityPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+ return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalCloseRFStabilityReport command to WinCal.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+ reference. The ISS index is the IssIdxMap index as returned from
+ WinCalGetIssListForAuxSite.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+ as 1 if stage and positioners at home.
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ AllRefAtHome:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+ return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+ information for the given aux site ID.
+ API Status: internal
+ Args:
+ AuxID:int = 0
+ Returns:
+ IssIdx:int
+ IssPN:str
+ IssDescription:str
+ IssEnabled:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+ global WinCalGetIssForAuxSite_Response
+ if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+ return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalGetNameAndVersion command to WinCal.
+ API Status: internal
+ Returns:
+ ServerName:str
+ Version:str
+ MajorVersion:int
+ MinorVersion:int
+ Revision:int
+ Build:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+ global WinCalGetNameAndVersion_Response
+ if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+ return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+ monitor portion of the current calibration setup.
+ API Status: internal
+ Returns:
+ MonitorPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+ return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing:Decimal="", ResetTrace:int="", AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+ the currently selected calibration setup. Resets the controller used in WinCal
+ for validataion.
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ ResetTrace:int = 1
+ AllowMove:int = 1
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+ return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalMeasureMonitorReference command to WinCal.
+ API Status: internal
+ Args:
+ AllowMove:int = 0
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumValidationPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumValidationPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+ return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumValidationPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumValidationPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumMonitoringPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+ return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumMonitoringPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumMonitoringPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Returns:
+ NumRepeatabilityPorts:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+ return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalSetNumRepeatabilityPorts command to WinCal.
+ API Status: internal
+ Args:
+ NumRepeatabilityPorts:int = 2
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalValidate command to WinCal. Performs the validation step of the
+ currently selected calibration setup in WinCal.
+ API Status: internal
+ Returns:
+ ValidationPassed:int
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+ return int(rsp[0])
+
+def WinCalGetValidationSetup(Port:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+ parameters.
+ API Status: internal
+ Args:
+ Port:int = 1
+ Returns:
+ StandardType:str
+ StandardPorts:int
+ StandardCompareType:int
+ StructureType:str
+ PostCorrect:int
+ PostCorrectMatching:int
+ AutoConfigure:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+ global WinCalGetValidationSetup_Response
+ if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+ return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+ without the validation step
+ API Status: internal
+ Args:
+ ProbeSpacing:Decimal = 130
+ Command Timeout: 300000
+ """
+ MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+ windows
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+ index it will return a string with the reference information
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Returns:
+ ReferenceInfo:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+ if WinCal has unapplied changes
+ API Status: internal
+ Args:
+ ShowErrors:int = 0
+ Returns:
+ HasUnappliedChanges:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+ return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+ indicated by the index, reference as being the current location
+ API Status: internal
+ Args:
+ IssIdx:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the Save Project as Template window which saves the project template
+ if the user clicks ok.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Brings up the New Project from Template dialog which allows the user to select a
+ template and create a new project.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns Max Ports and Number of probes connected to a port
+ API Status: internal
+ Returns:
+ MaxPorts:int
+ NumPortsConnectedtoProbes:int
+ Command Timeout: 1000
+ Example:WinCalGetNumPortsAndProbes
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+ global WinCalGetNumPortsAndProbes_Response
+ if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+ return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the properties from one probe, based on the passed in index. Pass in a
+ physical VNA port number that is less than or equal to Max Probes from the call
+ to CalGetNumPortsAndProbes
+ API Status: internal
+ Args:
+ VnaPortNum:int = 1
+ Returns:
+ IsSelected:int
+ BaseProbe:str
+ Options:str
+ PhysicalOrient:str
+ IsDual:int
+ IsSymmetric:int
+ SignalConfig:str
+ SelectedPitch:int
+ Command Timeout: 1000
+ Example:WinCalGetProbeInfoForPort 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+ global WinCalGetProbeInfoForPort_Response
+ if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+ return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current state of the machine.
+ API Status: internal
+ Returns:
+ MachineState:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the help about dialog for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid:int="", TimeoutMs:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shows the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ TimeoutMs:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the splash screen for the given application
+ API Status: internal
+ Args:
+ Pid:int = -1
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the last four project files that were opened.
+ API Status: internal
+ Returns:
+ ProjectFile1:str
+ ProjectFile2:str
+ ProjectFile3:str
+ ProjectFile4:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+ global GetLastFourProjects_Response
+ if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+ return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command:str=""):
+ """
+ Sends the WinCalExecuteCommand command to WinCal and returns the response
+ string.
+ API Status: published
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 300000
+ """
+ rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will return an error if its called with any other parameter as 0.
+ API Status: internal
+ Args:
+ TurnOnDemoMode:int = 1
+ Command Timeout: 5000
+ Example:SetDemoMode 0
+ """
+ MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Override a command with a demo response. The command will not reach its
+ destination but the supplied demo response will be returned. An active overide
+ for a command will be removed if the provided timeout is negative. Format: [ID]
+ [Time] [ErrorCode]:[Response] - Id: command id in hex withoud leding 0x - Time:
+ time in ms between command and response, negativ to reset demo mode for this
+ command - Errorcode: 0 for success, everything else indicates an error -
+ Response: response string
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 5000
+ Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+ """
+ MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+ This command will always return 0.
+ API Status: internal
+ Returns:
+ DemoModeOn:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+ return int(rsp[0])
+
+def ResetNetworkPort(Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+ tries to connect to (IP address and listen port of Kernel socket). Dummy
+ implementation for Kernel to support backwards.
+ API Status: internal
+ Args:
+ Param:str = ""
+ Command Timeout: 10000
+ Example:ResetNetworkPort 192.168.3.1 10000
+ """
+ MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum:int="", Param:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets status information about the connection NetworkDriver to Kernel. Socket
+ Error is the Windows socket error, Description the Windows socket error
+ description. If Socket Error is 0, the description 'Registered' informs that the
+ Kernel is ready to receive Remote Commands.
+ API Status: internal
+ Args:
+ ClientNum:int = 1
+ Param:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:GetNDriverClientStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID:int="", TimeoutMilliSec:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows specifying a separate command timeout for a single instance
+ of a command. This is especially useful if the application that receives a
+ command knows how long a command will take. This command had been added for
+ SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+ 5s.
+ API Status: internal
+ Args:
+ CmdID:int = 0
+ TimeoutMilliSec:int = 1000
+ Command Timeout: 5000
+ Example:OverrideCommandTimeout 3234 20000
+ """
+ MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Shutdown all Velox applications in an ordered fashion. When this command returns
+ success, all non-mandatory apps are closed and the mandatory ones will follow
+ shortly
+ API Status: internal
+ Args:
+ IgnorePID:int = 0
+ Command Timeout: 120000
+ Example:ShutdownVelox
+ """
+ MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Registration of an application can be delayed. To trigger this behavior,
+ RegisterProberApp has to be called with flag 3 set (0x04). From
+ RegisterProberApp to the time this command is sent, the application can send
+ commands but can't receive commands. This is necessary because some application
+ have to communicate with others during initialization and can not handle
+ commands properly during this time. The command group is necessary because of
+ architectural reasons (By design, the command receiver does not now the sender
+ of a command).
+ API Status: internal
+ Args:
+ CommandGroup:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos:Decimal="", YPos:Decimal="", NumberOfPoints:int="", NumberOfEPoints:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+ only) and pauses after it (even in the automatic mode)
+ API Status: internal
+ Args:
+ XPos:Decimal = 0
+ YPos:Decimal = 0
+ NumberOfPoints:int = 0
+ NumberOfEPoints:int = 0
+ Command Timeout: 60000
+ Example:StepFirstZProfilePoint 10000 20000 5 5
+ """
+ MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command calculates a delta value for the current point and then moves to
+ the specified point (if it's presented) or to the next one. Note, that in case
+ of the automatic Z detecting a return ZDelta parameter is a value for the
+ current point, but in case of the semiautomatic mode the command returns ZDelta
+ as a value for a previous tested point. If the profiling is finished this
+ command will return #807 error (End of the profile). Point indices are started
+ from 1 (1 is first, 2 is second, and so on).
+ API Status: internal
+ Args:
+ Point:int = 0
+ Returns:
+ XPos:Decimal
+ YPos:Decimal
+ Delta:Decimal
+ CurPoint:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 60000
+ Example:StepNextZProfilePoint 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+ global StepNextZProfilePoint_Response
+ if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+ return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode:str="", SepSpeed:Decimal="", ProfileSensor:str="", Stage:str="", SearchSpeed:Decimal="", Gap:Decimal="", Units:str="", ClearElectronics:int="", ClearRefZ:int="", Inaccuracy:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets some Z Profile Program Options remotely.
+ API Status: internal
+ Args:
+ ProfileMode:str = "S"
+ SepSpeed:Decimal = 25
+ ProfileSensor:str = "E"
+ Stage:str = "C"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ Units:str = "Y"
+ ClearElectronics:int = 1
+ ClearRefZ:int = 1
+ Inaccuracy:Decimal = 0
+ Command Timeout: 10000
+ Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Return predefined settings of the Z Profile Program.
+ API Status: internal
+ Returns:
+ ProfileMode:str
+ SepSpeed:Decimal
+ ProfileSensor:str
+ Stage:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ Units:str
+ ClearElectronics:int
+ ClearRefZ:int
+ Inaccuracy:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileOptions
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+ global GetZProfileOptions_Response
+ if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+ return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command opens the file inside of the Z Profiling.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 240000
+ Example:OpenZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+ global OpenZProfileFile_Response
+ if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves the current profile in the specified file.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:SaveZProfileFile Profile1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+ global SaveZProfileFile_Response
+ if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+ return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Read a profile from the ProberBench Electronics II to the application. Return a
+ number of available points.
+ API Status: internal
+ Args:
+ NewOrigin:str = "Z"
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:ReadZProfile H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+ return int(rsp[0])
+
+def SetZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Uploads the current profile to the ProberBench Electronics II. Returns a number
+ of written points.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:SetZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+ return int(rsp[0])
+
+def CloseZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Z-Profiling application.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseZProfiling
+ """
+ MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X:Decimal="", Y:Decimal="", PosRef:str="", Units:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets new start point for the profile. All points of the profile will be shifted
+ accordingly.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Command Timeout: 10000
+ Example:SetZProfileStartPoint 0 0 H Y
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the profiling process. If this status is true it means the
+ process is started.
+ API Status: internal
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ Example:GetZProfilingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+ return int(rsp[0])
+
+def StopZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the profiling process.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos:str="", X:Decimal="", Y:Decimal="", Z:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an origin for the profile. If the origin position is H the command ignores
+ X and Y parameters. If Z is None the command clears Z value of the origin.
+ Otherwise it tries to extract a double value from the string and set it.
+ API Status: internal
+ Args:
+ Pos:str = "H"
+ X:Decimal = 0
+ Y:Decimal = 0
+ Z:str = "None"
+ Command Timeout: 10000
+ Example:SetZProfileOrigin H 0 0 None
+ """
+ MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current parameters of the profile origin. If the origin Z has no value
+ the return string for it will be None, otherwise it consists a double value of
+ the profile Z.
+ API Status: internal
+ Returns:
+ Pos:str
+ X:Decimal
+ Y:Decimal
+ Z:str
+ Command Timeout: 10000
+ Example:GetZProfileOrigin
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+ global GetZProfileOrigin_Response
+ if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+ return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Command Timeout: 10000
+ Example:StartZProfiling
+ """
+ MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command works in the automatic mode only. It starts the profiling process,
+ profiles the entire wafer and then returns a number of tested points. This
+ command does upload the current profile to the ProberBench Electronics II. To do
+ it please use SetZProfile command
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 36000000
+ Example:ZProfileWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+ global ZProfileWafer_Response
+ if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+ return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef:str="", Units:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current start point of the profile by using given units and a
+ reference position.
+ API Status: internal
+ Args:
+ PosRef:str = "Z"
+ Units:str = "Y"
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ Example:GetZProfileStartPoint H Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+ global GetZProfileStartPoint_Response
+ if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+ return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X:Decimal="", Y:Decimal="", After:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Adds new point to the profile at the end (default) or after the given point.
+ Returns an index of new point and a number of all points in the profile. Point
+ indices are started from 1.
+ API Status: internal
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ After:int = 0
+ Returns:
+ Index:int
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:AddZProfilePoint 50000 50000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+ global AddZProfilePoint_Response
+ if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+ return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Deletes the point from the profile. Returns a number of all and enabled points
+ in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ NumberOfPoints:int
+ NumberOfEPoints:int
+ Command Timeout: 10000
+ Example:DeleteZProfilePoint 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+ global DeleteZProfilePoint_Response
+ if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+ return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index:int="", Status:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ Example:SetZProfilePointStatus 11 E
+ """
+ MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a status of the point in the profile. Point indices are started from 1.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ Example:GetZProfilePointStatus 11
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ All points are covered by triangles, each vertex of the triangle is a point of
+ the profile. The centers of the triangles are new points of the profile. If all
+ three vertexes of the triangle are tested points the new point will be marked as
+ tested also and has Z value equal to average Z of all three vertexes. Otherwise
+ the new point will be marked as untested. The command returns a number of points
+ in the profile after the update.
+ API Status: internal
+ Returns:
+ NumberOfPoints:int
+ Command Timeout: 10000
+ Example:PreciseZProfile
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+ return int(rsp[0])
+
+def CloseTableView():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the TableView application.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+ If no Site no is specified the chuck will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+ return int(rsp[0])
+
+def StepChuckSubsite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+ table view. If no Subsite no. is specified the chuck will step automatically to
+ the next logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+ return int(rsp[0])
+
+def StepScopeSite(Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the microscope stage to the requested Site no. of the scope table view. If
+ no Site no is specified the scope will step automatically to the next logical
+ site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Site:int = -1
+ Returns:
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+ return int(rsp[0])
+
+def StepProbeSite(Probe:int="", Site:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Steps the specified probe to the requested Site no. of the Probe no table view.
+ If no Site no. is specified the Probe no. will step automatically to the next
+ logical site location. The first site in the table is site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Site:int = -1
+ Returns:
+ ProbeRet:int
+ SiteRet:int
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+ global StepProbeSite_Response
+ if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+ return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual chuck site position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+ global ReadChuckSitePosition_Response
+ if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+ return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+ global ReadScopeSitePosition_Response
+ if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+ return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the site position of the specified probe. The first site in the table is
+ site 1.
+ API Status: internal
+ Args:
+ Probe:int = -1
+ Returns:
+ ProbeRet:int
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+ global ReadProbeSitePosition_Response
+ if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+ return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the chuck subsite position. The first site in the table is site 1.
+ API Status: internal
+ Returns:
+ Site:int
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+ global ReadChuckSubsitePosition_Response
+ if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+ return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins:int="", RecalcRoute:int=""):
+ """
+ Steps the chuck to the first die of the wafer map. Returns the row and column
+ number of the actual die location after the move is completed. If ClearBins is
+ 1, all binning data will be cleared from dies. If yes the route will be
+ recalculated. All dies marked to skip during the last test (marked to skip with
+ SetDieStatus) will be eliminated from the route.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ DieX:int
+ DieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+ global StepFirstDie_Response
+ if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+ return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Steps the chuck to the specified x,y die location of the wafer map. If no
+ command data is passed, the chuck automatically steps to the next logical wafer
+ map die location. Returns the row and column number of the actual die location
+ after the move is completed. In addition, the SubDie location, and total number
+ of SubDies is also returned. If Site (i.e. SubDie) is -1, the chuck will move
+ to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+ If sent without parameters, it will literally 'step to the next die'. When using
+ this command from shared code, use SendWithoutParameter().
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+ global StepNextDie_Response
+ if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin:int="", CDieX:int="", CDieY:int=""):
+ """
+ Assigns the bin information to the wafer map at the current die, unless a row
+ and column is specified. Inks the device if the real time inking option (of the
+ wafer map) is enabled.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 30000
+ Example:BinMapDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+ global BinMapDie_Response
+ if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+ return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins:str=""):
+ """
+ Assigns the pass or fail information to the actual bin value. Redundant to
+ SetBinCode.
+ API Status: published
+ Args:
+ Bins:str = ""
+ Command Timeout: 10000
+ Example:AssignMapBins PFFFFFF
+ """
+ MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+ """
+ Steps the chuck back the number of consecutive failed dies (goes back to the
+ last known good die) and returns the number of consecutive failed dies.
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+ return int(rsp[0])
+
+def StepFailedForward():
+ """
+ Steps the chuck forward the number of consecutive failed dies (goes to next
+ untested die).
+ API Status: published
+ Returns:
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+ return int(rsp[0])
+
+def ReadMapPosition(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+ the first value is 1, not 0. M_pnCurSite returns the currently selected
+ Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+ ReadMapPosition) has been included for legacy support. ReadMapPosition2 is
+ the preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+ global ReadMapPosition_Response
+ if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+ """
+ Returns the actual wafer map yield data information.
+ API Status: published
+ Returns:
+ TotalDies:int
+ TestedDies:int
+ Passed:int
+ Failed:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+ global ReadMapYield_Response
+ if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+ return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Bins the current die and steps the chuck to the next selected die location of
+ the wafer map (default) or steps to the specified Column and Row position, if
+ these values are passed. In contrast to StepNextDie, the BinStepDie command
+ will only step from die to die while staying on the current subdie. It will not
+ step through the subdies so it cannot be used for subdie stepping.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ Example:BinStepDie 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+ global BinStepDie_Response
+ if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX:int="", DieY:int=""):
+ """
+ If the command has no parameters it sets the current position as home position
+ both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+ home position using the given die coordinates.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName:str="", FileType:str=""):
+ """
+ Saves current map file with specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ FileType:str = "m"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode:str=""):
+ """
+ Enables or disables an external mode for the application. In the external mode,
+ all controls are disabled. The application handles all its remote commands in
+ both modes. Special interactive modes can also be turned on.
+ API Status: published
+ Args:
+ Mode:str = ""
+ Returns:
+ ModeType:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType:str=""):
+ """
+ Returns whether the application is in external mode or not.
+ API Status: published
+ Args:
+ ModeType:str = ""
+ Returns:
+ Mode:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number:str=""):
+ """
+ Specifies the wafer number.
+ API Status: published
+ Args:
+ Number:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+ """
+ Returns the wafer number for the current wafer.
+ API Status: published
+ Returns:
+ Number:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID:str=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+ """
+ Returns the wafer ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID:str=""):
+ """
+ Specifies the product ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+ """
+ Displays the product ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProductID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+ """
+ Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+ number of dies which were inked during the inker run.
+ API Status: published
+ Returns:
+ InkedDies:int
+ Command Timeout: 30000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+ return int(rsp[0])
+
+def CloseWaferMap():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the Wafer Map application.
+ API Status: internal
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+ """
+ Gets the number of dies in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedDies:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+ return int(rsp[0])
+
+def GetSelectedDieCoords(Die:int=""):
+ """
+ Given the index of a selected die in the range [1..NumSelectedDies], returns the
+ column and row indices for the selected die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+ global GetSelectedDieCoords_Response
+ if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+ return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset:Decimal="", YOffset:Decimal="", CDieX:int="", CDieY:int=""):
+ """
+ Moves to a user-specified offset within a die. The optional col row params can
+ be used to specify the die. If they are omitted, WaferMap moves to the specified
+ offset within the next selected die.
+ API Status: published
+ Args:
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+ global StepNextDieOffset_Response
+ if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+ return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+ the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+ (0-based) or -1 if no Subdie is currently selected. This command is the
+ preferred method for reading Wafer Map chuck position.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ DieX:int
+ DieY:int
+ XFromHome:Decimal
+ YFromHome:Decimal
+ CurSite:int
+ LastSiteIndex:int
+ CurDie:int
+ DiesCount:int
+ CurCluster:int
+ ClustersCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+ global ReadMapPosition2_Response
+ if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+ return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site:int=""):
+ """
+ Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+ not 1. This command is the preferred method for deleting a selected
+ subdie.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+ return int(rsp[0])
+
+def DeleteAllSubDie():
+ """
+ Deletes all subdies for all dies.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX:int="", DieY:int=""):
+ """
+ Returns a label from the wafer map at the current die, unless a row and column
+ are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label:str="", DieX:int="", DieY:int=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a row and column are
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site:int=""):
+ """
+ Steps the chuck to the specified SubDie number relative to the current die
+ origin of the wafer map. Returns the SubDie number of the actual die location
+ after the move is completed and the total number of subdies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+ global StepNextSubDie_Response
+ if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+ return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName:str=""):
+ """
+ Opens a Wafer Map file.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result:str="", DieX:int="", DieY:int=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX:int="", DieY:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a row
+ and column are specified.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result:str="", DieX:int="", DieY:int="", Site:int=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die and the
+ current subdie, unless a subdie, row, and column are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX:int="", DieY:int="", Site:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die and current
+ subdie, unless a row, column, and subdie are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Assigns the bin information for the current subdie in the current die, unless a
+ subdie, row, and column are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ Bin:int = 0
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+ global BinSubDie_Response
+ if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site:int="", X:Decimal="", Y:Decimal="", Label:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ CurSite:int
+ X:Decimal
+ Y:Decimal
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+ global GetSubDieData_Response
+ if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+ return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the home die location of the WaferMap.
+ API Status: internal
+ Returns:
+ DieX:int
+ DieY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+ global GetMapHome_Response
+ if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+ return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+ """
+ Returns the parameters for the current wafer.
+ API Status: published
+ Returns:
+ MapType:str
+ XIndex:Decimal
+ YIndex:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+ global GetMapDims_Response
+ if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+ return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are percentages.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth:Decimal="", DieHeight:Decimal="", Columns:int="", Rows:int=""):
+ """
+ Creates the rectangle wafer with specified parameters.
+ API Status: published
+ Args:
+ DieWidth:Decimal = 0
+ DieHeight:Decimal = 0
+ Columns:int = 0
+ Rows:int = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber:int="", Site:int=""):
+ """
+ Steps the chuck to the die location specified by the die number of the wafer
+ map. If no command data is passed, the chuck automatically steps to the next
+ logical wafer map die location. Returns the row and column number of the actual
+ die location after the move is completed. In addition, the SubDie location, and
+ total number of SubDies is also returned.
+ API Status: published
+ Args:
+ DieNumber:int = -1
+ Site:int = 0
+ Returns:
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ LastSiteIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+ global StepToDie_Response
+ if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+ return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift:int=""):
+ """
+ Returns parameters of the map coordinate system.
+ API Status: published
+ Args:
+ UseOrientationCornerForShift:int = 0
+ Returns:
+ Orientation:int
+ OriginShiftX:int
+ OriginShiftY:int
+ UseAlphas:int
+ UseIOs:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+ global GetMapOrientation_Response
+ if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+ return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation:int="", OriginShiftX:int="", OriginShiftY:int="", UseAlphas:int="", UseIOs:int="", UseOrientationCornerForShift:int=""):
+ """
+ Sets up new map origin and new coordinate system after that.
+ API Status: published
+ Args:
+ Orientation:int = 0
+ OriginShiftX:int = 0
+ OriginShiftY:int = 0
+ UseAlphas:int = 0
+ UseIOs:int = 1
+ UseOrientationCornerForShift:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX:int="", DieY:int="", Status:str=""):
+ """
+ Sets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX:int="", DieY:int=""):
+ """
+ Gets the die status.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site:int="", Status:str=""):
+ """
+ Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+ not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Status:str = "0"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site:int=""):
+ """
+ Returns the SubDie status. The SubDie collection is 0-based, the first value is
+ 0, not 1.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin:int=""):
+ """
+ Returns the Die size from the current map.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Returns:
+ Chars:str
+ Color:int
+ Status:str
+ Inker1:int
+ Inker2:int
+ Inker3:int
+ Inker4:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+ global GetBinCode_Response
+ if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+ return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin:int="", Chars:str="", Color:int="", Status:str="", Inker1:int="", Inker2:int="", Inker3:int="", Inker4:int=""):
+ """
+ Appends the Bin information to a bin code.
+ API Status: published
+ Args:
+ Bin:int = 0
+ Chars:str = ""
+ Color:int = 0
+ Status:str = ""
+ Inker1:int = 0
+ Inker2:int = 0
+ Inker3:int = 0
+ Inker4:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex:int=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Number is absent it uses the current die
+ on the wafer.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+ global GetDieDataAsNum_Response
+ if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+ return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex:int="", Bin:int="", Result:str=""):
+ """
+ Sets the Die Information. If the Die Number is invalid it returns an error.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ RDieIndex:int
+ DieX:int
+ DieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+ global GetSubDieDataAsNum_Response
+ if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+ return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex:int="", Site:int="", Bin:int="", Result:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieIndex:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX:int="", CDieY:int=""):
+ """
+ Returns the Die Information in the Row Column format. If the Die Number is
+ invalid it returns an error. If the Die Column and Row are absent it uses the
+ current die on the wafer.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+ global GetDieDataAsColRow_Response
+ if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+ return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX:int="", DieY:int="", Bin:int="", Result:str=""):
+ """
+ Sets the Data in the Row Column format. If the Die is invalid it returns an
+ error.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX:int="", CDieY:int="", Site:int=""):
+ """
+ Returns the information of a SubDie. The SubDie collection is 0-based, the first
+ value is 0, not 1.
+ API Status: published
+ Args:
+ CDieX:int = 0
+ CDieY:int = 0
+ Site:int = 0
+ Returns:
+ DieIndex:int
+ RDieX:int
+ RDieY:int
+ CurSite:int
+ Bin:int
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+ global GetSubDieDataAsColRow_Response
+ if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+ return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX:int="", DieY:int="", Site:int="", Bin:int="", Result:str=""):
+ """
+ Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+ 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Bin:int = 0
+ Result:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll:int="", DoEdgeDies:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables all dies.
+ API Status: internal
+ Args:
+ DoSelectAll:int = 0
+ DoEdgeDies:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current WaferMap Filename.
+ API Status: internal
+ Returns:
+ Name:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapName")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID:str=""):
+ """
+ Specifies the ID for the current wafer.
+ API Status: published
+ Args:
+ ID:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+ """
+ Returns the Lot ID for the current wafer.
+ API Status: published
+ Returns:
+ ID:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetLotID")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins:int="", RecalcRoute:int=""):
+ """
+ Steps the chuck to the first die cluster of the cluster map. If clusters are not
+ defined, the first Die is used. Returns the row and column information of the
+ actual cluster and die location after the move is completed. Switches to remote
+ control if the "Disable Velox" flag is set in the external options window.
+ API Status: published
+ Args:
+ ClearBins:int = 1
+ RecalcRoute:int = 1
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+ global StepFirstCluster_Response
+ if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX:int="", CClusterY:int=""):
+ """
+ Steps the chuck to the specified x,y cluster die location of the cluster map. If
+ no command data is passed, the chuck automatically steps to the next logical
+ cluster map location. If clusters are not defined, the Die information is used.
+ Returns the row and column number of the actual die location after the move is
+ completed.
+ API Status: published
+ Args:
+ CClusterX:int = 0
+ CClusterY:int = 0
+ Returns:
+ RClusterX:int
+ RClusterY:int
+ ClusterIndex:int
+ IncompleteCluster:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+ global StepNextCluster_Response
+ if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+ return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode:str="", StartColumn:str="", StartRow:str="", MoveParam:str=""):
+ """
+ Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+ is done for the shortest move way for the station.
+ API Status: published
+ Args:
+ MoveMode:str = "B"
+ StartColumn:str = "L"
+ StartRow:str = "T"
+ MoveParam:str = "H"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+ """
+ Returns the specified move path for the probe station inside the Wafer Map.
+ API Status: published
+ Returns:
+ MoveMode:str
+ StartColumn:str
+ StartRow:str
+ MoveParam:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+ global GetMapRoute_Response
+ if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+ return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters:int="", ClusterWidth:int="", ClusterHeight:int="", TestIncomplete:int=""):
+ """
+ Specifies the clusters parameters.
+ API Status: published
+ Args:
+ UseClusters:int = 0
+ ClusterWidth:int = 1
+ ClusterHeight:int = 1
+ TestIncomplete:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+ """
+ Returns current clusters parameters.
+ API Status: published
+ Returns:
+ UseClusters:int
+ ClusterWidth:int
+ ClusterHeight:int
+ TestIncomplete:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+ global GetClusterParams_Response
+ if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+ return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+ """
+ Deletes current wafer map, sub dies and binning information; then creates new
+ wafer map with defaults parameters.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X:Decimal="", Y:Decimal="", Label:str=""):
+ """
+ Adds new subdie at the end of the table.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Label:str = ""
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+ return int(rsp[0])
+
+def DeleteSubDie(Site:int=""):
+ """
+ Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+ not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+ for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+ support. DeleteSubDie2 is the preferred method for deleting a selected
+ subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+ dies.
+ API Status: published
+ Args:
+ Site:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+ return int(rsp[0])
+
+def GetNumSelectedClusters():
+ """
+ Gets the number of clusters in the map which are selected for probing.
+ API Status: published
+ Returns:
+ SelectedClusters:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+ return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex:int=""):
+ """
+ Given the index of a selected cluster in the range [1..NumSelectedClusters],
+ returns the column and row indices for the selected cluster.
+ API Status: published
+ Args:
+ ClusterIndex:int = 0
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+ global GetSelectedClusterCoords_Response
+ if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+ return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int=""):
+ """
+ Gets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ Status:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int="", Status:str=""):
+ """
+ Sets the die status in the cluster. Die coordinates are internal for the cluster
+ using the wafer map coordinate system. (0,0) die in the cluster is left top
+ corner (whether this die exists or not).
+ API Status: published
+ Args:
+ ClusterX:int = 0
+ ClusterY:int = 0
+ DieX:int = 0
+ DieY:int = 0
+ Status:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName:str=""):
+ """
+ Opens a Bin Code Table file (.bct) with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName:str=""):
+ """
+ Saves bin code table to a file with the specified name.
+ API Status: published
+ Args:
+ FileName:str = ""
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize:int=""):
+ """
+ Sets size of the bin code table. This is the size of bins used in statistics and
+ binning.
+ API Status: published
+ Args:
+ BinsSize:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+ """
+ Gets size of the bin code table.
+ API Status: published
+ Returns:
+ BinsSize:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+ return int(rsp[0])
+
+def StepFailedClusterBack():
+ """
+ Steps the chuck the consecutive failed clusters back (goes back to the last
+ known good cluster) and returns the number of consecutive failed clusters.
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+ return int(rsp[0])
+
+def StepFailedClusterForward():
+ """
+ Steps the chuck the consecutive failed clusters forward and returns the number
+ of consecutive failed clusters (goes to next untested cluster).
+ API Status: published
+ Returns:
+ FailedClusters:int
+ Command Timeout: 6000000
+ """
+ rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+ return int(rsp[0])
+
+def GoToWaferHome():
+ """
+ Moves the chuck to the wafer home position.
+ API Status: published
+ Command Timeout: 6000000
+ """
+ MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+ """
+ Returns a number of all units marked to test. Note that TestSites is a number of
+ all sites for all dies.
+ API Status: published
+ Returns:
+ ClustersCount:int
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+ global GetWaferInfo_Response
+ if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+ return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster:int=""):
+ """
+ Returns a number of all dies and sites marked to test in the given cluster.
+ API Status: published
+ Args:
+ Cluster:int = 0
+ Returns:
+ DiesCount:int
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+ global GetClusterInfo_Response
+ if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+ return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die:int=""):
+ """
+ Returns a number of sites marked to test in the given die.
+ API Status: published
+ Args:
+ Die:int = 0
+ Returns:
+ SitesCount:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+ return int(rsp[0])
+
+def ConvertToAlphas(Start:int="", Finish:int=""):
+ """
+ Returns a string of the alpha column coordinates for the given range divided by
+ spaces.
+ API Status: published
+ Args:
+ Start:int = 0
+ Finish:int = 0
+ Returns:
+ Alphas:str
+ Command Timeout: 240000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer:str=""):
+ """
+ Sets new active layer.
+ API Status: published
+ Args:
+ Layer:str = ""
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+ """
+ Returns current active layer.
+ API Status: published
+ Returns:
+ Layer:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX:Decimal="", RefY:Decimal=""):
+ """
+ Sets a new reference point for the die. This point is NOT used for die stepping,
+ nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+ GUI setting, the Die Reference Point can be set to be more representative of the
+ actual reference location within the die. A setting of (0.0, 0.0) is defined as
+ the upper left corner of the die. All subdie coordinates are relative to upper
+ left corner of the die.
+ API Status: published
+ Args:
+ RefX:Decimal = 0
+ RefY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+ """
+ Returns current reference point for the die. For details see SetDieRefPoint
+ command.
+ API Status: published
+ Returns:
+ RefX:Decimal
+ RefY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+ global GetDieRefPoint_Response
+ if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+ return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+ """
+ Clears all binning data in the wafer map.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State:str="", Window:str=""):
+ """
+ Has sense in the application only (not for ActiveX controls). It shows or hides
+ a window. All parameters are case-insensitive.
+ API Status: published
+ Args:
+ State:str = "s"
+ Window:str = "setup"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin:int="", ButtonStatus:int=""):
+ """
+ Sets the current bin for the application. Second parameter allows to enable or
+ disable "Mark with Bin" mode in the application.
+ API Status: published
+ Args:
+ Bin:int = 0
+ ButtonStatus:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+ """
+ Returns the current bin in the application.
+ API Status: published
+ Returns:
+ Bin:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+ return int(rsp[0])
+
+def ReadClusterPosition(Pos:int="", FromPos:str=""):
+ """
+ Returns the actual wafer map cluster position. If the cluster probing is
+ disabled, the command will assume a cluster of size 1x1.
+ API Status: published
+ Args:
+ Pos:int = 0
+ FromPos:str = "R"
+ Returns:
+ ClusterX:int
+ ClusterY:int
+ ClusterIndex:int
+ DieX:int
+ DieY:int
+ DieIndex:int
+ ClusterWidth:int
+ ClusterHeight:int
+ EnabledDies:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+ global ReadClusterPosition_Response
+ if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+ return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are percentages.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+ global GetWaferMapParams_Response
+ if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+ """
+ Creates a rectangular wafermap with specified parameters.
+ API Status: published
+ Returns:
+ DieWidth:Decimal
+ DieHeight:Decimal
+ Columns:int
+ Rows:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+ global GetRectMapParams_Response
+ if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+ return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X:Decimal="", Y:Decimal=""):
+ """
+ Tries to find an appropriate position in the wafer for the current chuck
+ position. X and Y describe the chuck position of the wafer center relatively to
+ the chuck zero position. If the wafer position is found the command sets it as
+ the wafer map home position and sets the current chuck position as the chuck
+ home position. If there is no corresponding wafer position the command returns
+ error 701. Command is used by AutoAlign for the BuildMap feature.
+ API Status: published
+ Args:
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor:str="", SearchSpeed:Decimal="", Gap:Decimal="", SuccessRatio:Decimal="", ProfDistX:Decimal="", ProfDistY:Decimal=""):
+ """
+ Sets some WaferMap profiling options remotely.
+ API Status: published
+ Args:
+ ProfileSensor:str = "e"
+ SearchSpeed:Decimal = 50
+ Gap:Decimal = 10
+ SuccessRatio:Decimal = 75
+ ProfDistX:Decimal = 0
+ ProfDistY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+ """
+ Returns predefined settings of the WaferMap profiling options.
+ API Status: published
+ Returns:
+ ProfileSensor:str
+ SearchSpeed:Decimal
+ Gap:Decimal
+ SuccessRatio:Decimal
+ ProfDistX:Decimal
+ ProfDistY:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+ global GetWaferProfileOptions_Response
+ if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+ return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue:int=""):
+ """
+ Starts the profiling process. To determine the current profiling state, use
+ GetWaferProfilingStatus command.
+ API Status: published
+ Args:
+ DoContinue:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+ """
+ Returns status of the profiling process. If this status is true, the process is
+ started.
+ API Status: published
+ Returns:
+ Started:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+ return int(rsp[0])
+
+def StopWaferProfiling():
+ """
+ Stops the profiling process.
+ API Status: published
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+ """
+ Profiles the wafer and returns a status of the profiling as an error code.
+ API Status: published
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Profiles the wafer and returns a status of the profiling as an error code.
+ Executes profiling using the off axis camera
+ API Status: internal
+ Command Timeout: 36000000
+ """
+ MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX:int="", DieY:int="", Site:int=""):
+ """
+ Returns a label from the wafer map at the current die and current subdie, unless
+ a row, column, and subdie are specified. The SubDie collection is 0-based, the
+ first value is 0, not 1.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label:str="", DieX:int="", DieY:int="", Site:int=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, row, and column are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ DieX:int = 0
+ DieY:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns a label from the wafer map the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label:str="", CDieIndex:int="", Site:int=""):
+ """
+ Assigns a label to the wafer map at the current die and the current subdie,
+ unless a subdie, and die number are specified. The SubDie collection is 0-based,
+ the first value is 0, not 1.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex:int=""):
+ """
+ Returns a label from the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Label:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label:str="", CDieIndex:int=""):
+ """
+ Assigns a label to the wafer map at the current die, unless a die number is
+ specified.
+ API Status: published
+ Args:
+ Label:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the XY offset from the reference position of the Home Die to wafer
+ center in chuck coordinates.
+ API Status: internal
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+ global GetHomeDieOffset_Response
+ if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+ return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+ """
+ Creates the circle wafer with specified parameters. If parameter is omitted,
+ then zero is used. For this version of the command, units for XOffset and
+ YOffset are microns.
+ API Status: published
+ Args:
+ Diameter:Decimal = 200
+ DieWidth:Decimal = 10000
+ DieHeight:Decimal = 10000
+ FlatLength:Decimal = 20
+ FlatAngle:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ EdgeArea:Decimal = 0
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+ """
+ Returns the circle wafer parameters. For this version of the command, units for
+ XOffset and YOffset are microns.
+ API Status: published
+ Returns:
+ Diameter:Decimal
+ DieWidth:Decimal
+ DieHeight:Decimal
+ FlatLength:Decimal
+ FlatAngle:int
+ XOffset:Decimal
+ YOffset:Decimal
+ EdgeArea:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+ global GetWaferMapParams2_Response
+ if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+ return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle:int=""):
+ """
+ This command sets the Wafer Test Angle. This is different from the notch angle
+ and allows rotating the WaferMap.
+ API Status: published
+ Args:
+ Angle:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+ """
+ This returns the Wafer Test Angle. This is different from the notch angle and
+ allows rotating the WaferMap.
+ API Status: published
+ Returns:
+ Angle:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+ return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName:str="", ClearMap:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads the Pre-Mapped Dies Table file with specified name.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ ClearMap:int = 1
+ Command Timeout: 240000
+ """
+ MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX:int="", DieY:int=""):
+ """
+ This command is valid when a PreMapped Dies Table has been loaded. Returns
+ values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+ specified. Returns actual (as measured during the Pre-Mapping) x, y, z, and
+ theta die positions. Also returns whether or not Z and Theta are being used.
+ This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+ PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+ returned.
+ API Status: published
+ Args:
+ DieX:int = 0
+ DieY:int = 0
+ Returns:
+ UseZ:int
+ UseTheta:int
+ ActualX:Decimal
+ ActualY:Decimal
+ ActualZ:Decimal
+ Theta:Decimal
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+ global GetPreMappedDieInfo_Response
+ if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+ return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex:int=""):
+ """
+ Returns a measurement result from the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result:str="", CDieIndex:int=""):
+ """
+ Assigns a measurement result to the wafer map at the current die, unless a die
+ number is specified.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex:int="", Site:int=""):
+ """
+ Returns a measurement result from the wafer map the current die and the current
+ subdie, unless a subdie, and die number are specified. The SubDie collection is
+ 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ CDieIndex:int = 0
+ Site:int = 0
+ Returns:
+ Result:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result:str="", CDieIndex:int="", Site:int=""):
+ """
+ Assigns a measurement result to the wafer die map at the current die at the
+ current subdie, unless a subdie, and die number are specified. The SubDie
+ collection is 0-based, the first value is 0, not 1.
+ API Status: published
+ Args:
+ Result:str = ""
+ CDieIndex:int = 0
+ Site:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Enables or disables edge dies for test
+ API Status: internal
+ Args:
+ Enable:int = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows access to read any data item in Spectrum explorer. GetSpectrumData
+ AlignWafer/ProjectData/Mark1/ChuckPosition/X GetSpectrumData Chuck
+ Camera/Camera Settings/Shutter
+ API Status: internal
+ Args:
+ DataPath:str = ""
+ Returns:
+ Value:str
+ Command Timeout: 6000
+ Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Allows changing any data item in Spectrum explorer. Works independent of access
+ level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+ SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+ API Status: internal
+ Args:
+ PathAndValue:str = ""
+ Command Timeout: 6000
+ Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName:str="", XY:int="", Z:int="", Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command reads the current chuck and microscope position and sets them as
+ new controller or chuck and microscope positions. The command was originally used
+ by ReAlignWizard but may be removed in the future because of direct access to
+ tooldata within Spectrum.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XY:int = 1
+ Z:int = 0
+ Model:int = -1
+ Command Timeout: 60000
+ Example:ReadVMPosition AlignWafer 1 0 0
+ """
+ MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName:str="", XYChuck:int="", ZChuck:int="", XYScope:int="", ZScope:int="", Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command moves to trained stages positions of a requested tool. Command is
+ used by ReAlignWizard to move to the trained positions for AutoAlign and
+ DetectWaferHeight.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ XYChuck:int = 1
+ ZChuck:int = 1
+ XYScope:int = 0
+ ZScope:int = 0
+ Model:int = -1
+ Command Timeout: 120000
+ Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+ """
+ MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome:int="", AutoEdgeFind:int="", FileName:str=""):
+ """
+ ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+ to determine the contour of it. The data will be memorized as xy coordinates of
+ contour points referenced to the home position. These Points are written to a
+ file after tracking the shape.
+ API Status: published
+ Args:
+ SetHome:int = 1
+ AutoEdgeFind:int = 0
+ FileName:str = ""
+ Command Timeout: 600000
+ Example:ShapeTracker 1
+ """
+ MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition:int="", Synchronize:int="", ChuckX:Decimal="", ChuckY:Decimal=""):
+ """
+ Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+ focused on the trained chuck position or the manual adjusted reference position.
+ This tool uses the FindFocus tool with its own Range.
+ API Status: published
+ Args:
+ SetStartPosition:int = 0
+ Synchronize:int = 0
+ ChuckX:Decimal = -1
+ ChuckY:Decimal = -1
+ Returns:
+ PositionX:Decimal
+ PositionY:Decimal
+ WaferHeight:Decimal
+ SynchGap:Decimal
+ ZOffset:Decimal
+ Stage:str
+ Command Timeout: 300000
+ Example:DetectWaferHeight 0 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+ global DetectWaferHeight_Response
+ if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+ return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command checks if a plugin is trained and returns a string of error/warning
+ messages including information about what is not trained, setup for the tool to
+ run.
+ API Status: internal
+ Args:
+ Plugin:str = ""
+ Returns:
+ PluginAvailable:int
+ Message:str
+ Command Timeout: 1000
+ Example:CheckSpectrumPlugin AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+ global CheckSpectrumPlugin_Response
+ if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+ return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue:int="", SkipSettingHome:int=""):
+ """
+ Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+ index calculation or thermal expansion measurement. The command will update home
+ if home was trained. It will only move to its trained chuck/scope position
+ before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+ "MoveToTrainedZPosition" is true.
+ API Status: published
+ Args:
+ SetValue:int = 0
+ SkipSettingHome:int = 0
+ Command Timeout: 300000
+ Example:AutoAlign 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active:int=""):
+ """
+ Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+ SPS300/SUMMIT200 stations.) The camera quiet mode deactivates the chuck,
+ platen and contact view camera and triggers a digital output which
+ connects/disconnects these cameras firewire connection to the PC.
+ API Status: published
+ Args:
+ Active:int = 0
+ Command Timeout: 30000
+ Example:SetCameraQuiet 1
+ """
+ MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol:int="", RefDieRow:int="", RefDieDistToCentreX:Decimal="", RefDieDistToCentreY:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is based on the SetMapOrientation command. It allows shifting the
+ center of the reference die to the center of the wafer.
+ API Status: internal
+ Args:
+ RefDieCol:int = 0
+ RefDieRow:int = 0
+ RefDieDistToCentreX:Decimal = 0
+ RefDieDistToCentreY:Decimal = 0
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition:int=""):
+ """
+ Performs a two-point alignment and moves chuck to the trained align position. XY
+ correction is made afterwards to calculate the new home position.
+ API Status: published
+ Args:
+ TrackPosition:int = 0
+ Returns:
+ ThetaOffset:Decimal
+ Command Timeout: 120000
+ Example:AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+ return Decimal(rsp[0])
+
+def AlignChip():
+ """
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). The
+ current chip is assumed to be in the region of interest when the command is
+ called.
+ API Status: published
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChip
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChip")
+ global AlignChip_Response
+ if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount:int="", Range:Decimal=""):
+ """
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search.
+ API Status: published
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocus 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+ global FindFocus_Response
+ if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+ return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID:int=""):
+ """
+ Performs an automated aux site alignment in XYZ. Tool can correct reference
+ position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAux 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model:int="", ReturnDistanceFromModelOrigin:int="", UseSingleImageAcquisition:int=""):
+ """
+ Search user-defined models. Up to 40 different models can be trained. After
+ training, these models can be searched on screen either by direct user
+ interaction or from external applications with a remote command. The remote
+ command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+ each instance of the controller found in the region of interest.
+ API Status: published
+ Args:
+ Model:int = 1
+ ReturnDistanceFromModelOrigin:int = 0
+ UseSingleImageAcquisition:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 10000
+ Example:FindFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+ during Project loading. Does save configuration data but does not save project
+ data.
+ API Status: internal
+ Command Timeout: 6000
+ Example:CloseSpectrum
+ """
+ MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+ """
+ Saves the currently displayed image to the specified file. The image is stored
+ in the requested file format (bmp, jpg or png). By default. it will save the raw
+ camera image and an image with the overlays that are currently visible on the
+ camera view. Using a parameter, one can decide to only save either raw image,
+ overlay image or both. By Specifying 'ALL' as the mount position, the captured
+ screenshot will consist of the currently selected camera layout without
+ providing the raw image. If MountPos and FullPath are empty then the current
+ camera view with overlays is copied to the clipboard.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ FullPath:str = "Image.bmp"
+ SnapShotMode:int = 2
+ Command Timeout: 60000
+ Example:SnapImage Scope C:/Temp/Image.bmp
+ """
+ MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name:str="", Zoom:int="", LiveVideo:int="", WindowState:int=""):
+ """
+ Switches the desired video window of Spectrum as foreground and active view. The
+ camera view can be determined over a tool name or the camera mount position. The
+ second parameter defines the displays zoom factor to be used. Third parameter is
+ used to toogle the live video. Last parameter can be used to maximize a window.
+ API Status: published
+ Args:
+ Name:str = ""
+ Zoom:int = 0
+ LiveVideo:int = 2
+ WindowState:int = 1
+ Command Timeout: 6000
+ Example:SetCameraView AlignWafer 0 2 2
+ """
+ MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name:str="", State:int="", Shutter:Decimal="", Gain:Decimal="", Brightness:int="", Contrast:int="", Sharpness:int="", Illumination:int=""):
+ """
+ Switches the light of the choosen camera on or off. Light values of -1 will
+ cause that the parameter is not affected.
+ API Status: published
+ Args:
+ Name:str = ""
+ State:int = 0
+ Shutter:Decimal = -1
+ Gain:Decimal = -1
+ Brightness:int = -1
+ Contrast:int = -1
+ Sharpness:int = -1
+ Illumination:int = -1
+ Command Timeout: 6000
+ Example:SetCameraLight AlignWafer 1 20 5
+ """
+ MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName:str="", MountPosition:str="", AskExecute:int=""):
+ """
+ Starts the wizard of a given tool on the display defined in the tool settings.
+ Additionally it can start a wizard for training single models with the syntax
+ e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+ MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+ e.g. ShowWizard Calibrate Platen
+ API Status: published
+ Args:
+ ToolName:str = ""
+ MountPosition:str = ""
+ AskExecute:int = 0
+ Returns:
+ Cancelled:int
+ Command Timeout: 10000000
+ Example:ShowWizard AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+ return int(rsp[0])
+
+def ProbeToPadAlign(Position:str=""):
+ """
+ Sets a new Home position. The command is used during ReAlign to search the
+ trained home reference controller and to calculate the new xy home position.
+ API Status: published
+ Args:
+ Position:str = "H"
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ Command Timeout: 120000
+ Example:ProbeToPadAlign H
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+ global ProbeToPadAlign_Response
+ if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+ return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+ """
+ Reads the wafer ID string from the wafer's surface. Returns the read ID as
+ string. Requires IDTools license.
+ API Status: published
+ Returns:
+ OcrString:str
+ Command Timeout: 60000
+ Example:ReadOcrString
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+ """
+ Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+ API Status: published
+ Returns:
+ BarCodeString:str
+ Command Timeout: 60000
+ Example:ReadBarCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+ """
+ Reads the wafers matrix code and decodes it to a string. Requires IDTools
+ license.
+ API Status: published
+ Returns:
+ MatrixCodeString:str
+ Command Timeout: 60000
+ Example:Read2DMatrixCode
+ """
+ rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Activates the Spectrum remote mode. In this mode all user interface elements are
+ hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+ API Status: internal
+ Args:
+ Activate:int = 1
+ Command Timeout: 10000
+ Example:SetSpectrumRemote 1
+ """
+ MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name:str=""):
+ """
+ Returns light properties of choosen camera.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ State:int
+ Shutter:Decimal
+ Gain:Decimal
+ Brightness:int
+ Contrast:int
+ Sharpness:int
+ Illumination:int
+ Command Timeout: 6000
+ Example:GetCameraLight Scope
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+ global GetCameraLight_Response
+ if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+ return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name:str=""):
+ """
+ Returns the present camera view state of a desired tool or active view.
+ API Status: published
+ Args:
+ Name:str = ""
+ Returns:
+ MountPosition:str
+ Zoom:int
+ LiveVideo:int
+ WindowState:int
+ Command Timeout: 6000
+ Example:GetCameraView AlignWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+ global GetCameraView_Response
+ if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+ return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName:str="", ModelName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+ be stored in the same folder as the project file. The command was originally
+ required by ReAlignWizard and is currently no longer in use.
+ API Status: internal
+ Args:
+ ToolName:str = ""
+ ModelName:str = ""
+ Returns:
+ BitmapPath:str
+ Command Timeout: 30000
+ Example:GetPattern AlignWafer Model1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition:str="", DistPositionX:Decimal="", DistPositionY:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the ChuckCenter under a given camera. When no camera mount position is
+ given, Spectrum uses active view. If there is an Offset different from zero,
+ this position will be moved under the camera.
+ API Status: internal
+ Args:
+ MountPosition:str = ""
+ DistPositionX:Decimal = 0
+ DistPositionY:Decimal = 0
+ Command Timeout: 60000
+ Example:ShowPosition Scope
+ """
+ MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the home die coordinates when the home die is under the alignment camera
+ (for instance, the top camera). Command was used during TrainReAlign to get
+ the start position for Z-Profiling. Command is no longer used.
+ API Status: internal
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 6000
+ Example:GetCameraHomePosition
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+ global GetCameraHomePosition_Response
+ if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+ return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos:str="", SynchronizeXY:int="", SynchronizeZ:int=""):
+ """
+ Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+ the chuck camera. The chuck must be moved to get the mark in view of the
+ specified camera.
+ API Status: published
+ Args:
+ MountPos:str = "Scope"
+ SynchronizeXY:int = 0
+ SynchronizeZ:int = 0
+ Returns:
+ XPosition:Decimal
+ YPosition:Decimal
+ ZPosition:Decimal
+ Command Timeout: 120000
+ Example:SynchronizeCamera S 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+ global SynchronizeCamera_Response
+ if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+ return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ:int="", MeasureBothGroups:int=""):
+ """
+ Determines the chuck XYZ axis position where the needles of the probe card are
+ in focus. The output parameter is the Z axis value in microns from zero of the
+ new focus height.
+ API Status: published
+ Args:
+ UpdateZ:int = 1
+ MeasureBothGroups:int = 1
+ Returns:
+ ZPosition:Decimal
+ Command Timeout: 360000
+ Example:ProbeCardOCS 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+ return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition:Decimal="", YPosition:Decimal="", XSubsiteOffset:Decimal="", YSubsiteOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+ move. Automation must be activated/trained before command can be used. Response
+ is X, Y relative distance of adjustment from requested position.
+ API Status: internal
+ Args:
+ XPosition:Decimal = 0
+ YPosition:Decimal = 0
+ XSubsiteOffset:Decimal = 0
+ YSubsiteOffset:Decimal = 0
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:MoveChuckAutoXY 5000 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+ global MoveChuckAutoXY_Response
+ if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+ return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign:int=""):
+ """
+ Alignment for the next wafer when using VueTrack.
+ API Status: published
+ Args:
+ FullVueTrackAlign:int = 1
+ Command Timeout: 6000000
+ Example:VueTrackAlign
+ """
+ MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow:Decimal="", DistAbove:Decimal="", XOffsetCenter:int="", YOffsetCenter:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command is only used internally for software testing and for providing backwards
+ compatibility with SCPI legacy commands. It executes a focus search using the
+ eVue focus drive.
+ API Status: internal
+ Args:
+ DistBelow:Decimal = 0
+ DistAbove:Decimal = 0
+ XOffsetCenter:int = 0
+ YOffsetCenter:int = 0
+ Returns:
+ FocusScore:Decimal
+ ZPosition:Decimal
+ Command Timeout: 30000
+ Example:AutoFocusEVue 200 200 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+ global AutoFocusEVue_Response
+ if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+ return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+ with optional index calculation or thermal expansion measurement. AutoAlign is
+ performed using the Platen camera. Only supported for systems with off-axis
+ camera.
+ API Status: internal
+ Args:
+ SetValue:int = 0
+ Command Timeout: 300000
+ Example:AutoAlignOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount:int="", Range:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Focus search is performed using the Platen camera. Only supported for
+ systems with off-axis camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusOffAxis 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+ global FindFocusOffAxis_Response
+ if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+ return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID:int=""):
+ """
+ Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+ can correct reference position and contact height for the given aux site.
+ API Status: published
+ Args:
+ AuxSiteID:int = 0
+ Command Timeout: 300000
+ Example:AlignAuxOffAxis 1
+ """
+ MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount:int="", Range:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Determines the Z axis position where an object in the region of interest is in
+ focus. First output parameter is the Z axis value in microns from zero of the
+ new focus height. Second output parameter is the used stage to perform focus
+ search. Uses the FindFocus tool settings but always the Platen camera -
+ independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+ that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+ have an upward looking camera.
+ API Status: internal
+ Args:
+ StepCount:int = -1
+ Range:Decimal = -1
+ Returns:
+ ZPosition:Decimal
+ Stage:str
+ Command Timeout: 120000
+ Example:FindFocusPlaten 50 500
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+ global FindFocusPlaten_Response
+ if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+ return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a single or two point alignment and moves the current chip to the
+ trained aligned position in Theta (in degrees) and X, Y (in microns). This
+ command is using the off axis platen camera with functionality of ReAlign.
+ API Status: internal
+ Returns:
+ ThetaOffset:Decimal
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 180000
+ Example:AlignChipOffAxis
+ """
+ rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+ global AlignChipOffAxis_Response
+ if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+ return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens:int=""):
+ """
+ Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+ API Status: published
+ Args:
+ Lens:int = 1
+ Command Timeout: 10000
+ Example:SelectAZoomLens 1
+ """
+ MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+ """
+ Returns 1 of 4 symbolic lenses, coarse ranges.
+ API Status: published
+ Returns:
+ Lens:int
+ Command Timeout: 5000
+ Example:GetAZoomLens
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+ return int(rsp[0])
+
+def AZoomSetupDialog():
+ """
+ Opens the operator panel. In this window you can change the settings for all
+ defined lenses.
+ API Status: published
+ Command Timeout: 5000
+ Example:AZoomSetupDialog
+ """
+ MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus:int="", Ref:str=""):
+ """
+ Changes the focus magnitude.
+ API Status: published
+ Args:
+ Focus:int = 100
+ Ref:str = "R"
+ Returns:
+ RetFocus:int
+ Command Timeout: 10000
+ Example:MoveAZoomFocus 100
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+ return int(rsp[0])
+
+def ReadAZoomFocus():
+ """
+ Returns the focus magnitude.
+ API Status: published
+ Returns:
+ Focus:int
+ Command Timeout: 5000
+ Example:ReadAZoomFocus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+ return int(rsp[0])
+
+def MoveAZoomVelocity(Direction:str="", Velocity:int=""):
+ """
+ Moves the A-Zoom using the set focus speed.
+ API Status: published
+ Args:
+ Direction:str = ""
+ Velocity:int = 100
+ Returns:
+ RetVelocity:Decimal
+ Command Timeout: 240000
+ Example:MoveAZoomVelocity + 67
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+ return Decimal(rsp[0])
+
+def StopAZoom():
+ """
+ Stops the A-Zoom movements.
+ API Status: published
+ Command Timeout: 5000
+ Example:StopAZoom
+ """
+ MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light:int=""):
+ """
+ Switches all lights ON or OFF. ON means the values defined by the current lens.
+ 1 switches the light on, 0 switches the light off. Without parameter toggles
+ between on an off.
+ API Status: published
+ Args:
+ Light:int = 0
+ Command Timeout: 5000
+ Example:SetAZoomLight 1
+ """
+ MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the OpticalControl application. Used during Project File handling.
+ API Status: internal
+ Command Timeout: 5000
+ Example:CloseAZoom
+ """
+ MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value:int="", Channel:int="", Segment:int=""):
+ """
+ Set the brightness of given channel and segment to the given value.
+ API Status: published
+ Args:
+ Value:int = 0
+ Channel:int = 1
+ Segment:int = 1
+ Command Timeout: 5000
+ Example:OCLightVal 128 1 4
+ """
+ MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On:int="", Channel:int=""):
+ """
+ Switch the light (if it has segments then all) in a given channel ON or OFF.
+ Switch ON - that means: light to the before adjusted brightness.
+ API Status: published
+ Args:
+ On:int = 0
+ Channel:int = 1
+ Command Timeout: 5000
+ Example:OCLightOn 1 1
+ """
+ MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom:int="", Motor:int=""):
+ """
+ Set logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Zoom:int = 0
+ Motor:int = 1
+ Command Timeout: 5000
+ Example:OCSetZoomLevel 50 1
+ """
+ MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor:int=""):
+ """
+ Get logical zoom factor for given motor (if has more then one, else to the one)
+ API Status: published
+ Args:
+ Motor:int = 1
+ Returns:
+ Zoom:int
+ Command Timeout: 5000
+ Example:OCGetZoomLevel 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+ return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int=""):
+ """
+ Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+ wafer during ramping to the new target temperature. Command returns immediately.
+ The status of temperature ramping must be checked using the
+ GetReAlignTemperatureStatus command.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ Command Timeout: 5000
+ Example:StartReAlignTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+ """
+ Stops temperature ramping using ReAlign.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopReAlignTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using ReAlign process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetReAlignTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+ global GetReAlignTemperatureStatus_Response
+ if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+ """
+ Performs an automatic realignment of the wafer. This includes measuring the
+ needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+ drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+ ProbeToDie Alignment to correct the needle position for the current die. Command
+ returns once ReAlign is finished or aborted because of an error.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Returns:
+ XOffsetWafer:Decimal
+ YOffsetWafer:Decimal
+ ZOffsetWafer:Decimal
+ XOffsetCard:Decimal
+ YOffsetCard:Decimal
+ ZOffsetCard:Decimal
+ Command Timeout: 1000000
+ Example:ReAlign 2 H 0 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+ global ReAlign_Response
+ if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+ return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+ """
+ Starts the NextWafer routine.
+ API Status: published
+ Returns:
+ Canceled:int
+ Command Timeout: 60000000
+ Example:NextWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("NextWafer")
+ return int(rsp[0])
+
+def StartReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+ """
+ Starts an automatic realignment of the wafer. This includes measuring the needle
+ drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+ XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+ Alignment to correct the needle position for the current die. Command returns
+ immediately. The status of the asynchronous ReAlign execution must be checked
+ using the GetReAlignStatus command.
+ API Status: published
+ Args:
+ Repeats:int = 1
+ Mode:str = "H"
+ AlignProbeCard:int = 2
+ CorrectZ:int = 2
+ Command Timeout: 60000
+ Example:StartReAlign 2 H 0 0
+ """
+ MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+ """
+ Stops the ReAlign procedure.
+ API Status: published
+ Command Timeout: 120000
+ Example:StopReAlign
+ """
+ MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+ """
+ Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+ is running.
+ API Status: published
+ Returns:
+ Running:int
+ Command Timeout: 60000
+ Example:GetReAlignStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+ return int(rsp[0])
+
+def EnableOverlay(Overlay:int=""):
+ """
+ Allows activating the overlay of the needles for the top camera.
+ API Status: published
+ Args:
+ Overlay:int = 0
+ Command Timeout: 6000
+ Example:EnableOverlay 0
+ """
+ MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Switches the offset compensation. Applicable for MicroAlign stations only.
+ API Status: internal
+ Args:
+ Offset:int = 0
+ Command Timeout: 60000
+ Example:SwitchOffset 1
+ """
+ MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command was only implemented for supporting a SCPI legacy command. Does not make
+ sense in Velox, as there is no default training rectangle on the screen as in
+ Nucleus.
+ API Status: internal
+ Args:
+ Model:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 30000
+ Example:TrainFeature 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Returns:
+ Exposure:Decimal
+ Command Timeout: 10000
+ Example:GetEvueExposureLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+ return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+ command.
+ API Status: internal
+ Args:
+ Exposure:Decimal = 0
+ Command Timeout: 10000
+ Example:SetEvueExposureLevel
+ """
+ MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ:Decimal="", EvueVelocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the eVue focus stage to a specified position. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ EvueZ:Decimal = 0
+ EvueVelocity:Decimal = 100
+ Command Timeout: 30000
+ Example:MoveEvueFocusStage 1000
+ """
+ MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the eVue focus stage. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Returns:
+ EvueZ:Decimal
+ Command Timeout: 5000
+ Example:GetEvueFocusStagePos
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+ return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command runs the AutoExpose function for the eVue. Implemented for supporting
+ SCPI legacy command.
+ API Status: internal
+ Args:
+ UseCB:int = 1
+ Command Timeout: 20000
+ Example:RunEvueAutoExpose 1
+ """
+ MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope that is connected to Velox. On eVue
+ systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+ and 0.5 to 20.0 for a 40x system.
+ API Status: internal
+ Returns:
+ Zoom:Decimal
+ Command Timeout: 5000
+ Example:GetEvueZoomLevel
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+ return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+ Velox. On eVue systems, this command sets the proper CCD zoom level to the
+ appropriate optical path.
+ API Status: internal
+ Args:
+ Zoom:Decimal = 0
+ Command Timeout: 5000
+ Example:SetEvueZoomLevel 2.0
+ """
+ MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int="", AlignOnFinish:int=""):
+ """
+ Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+ will re-adjust the probes and wafer during ramping to the new target
+ temperature.
+ API Status: published
+ Args:
+ TargetTemperature:Decimal = 0
+ ThetaAlignOnFinish:int = 0
+ ContactOnFinish:int = 0
+ AlignOnFinish:int = 1
+ Command Timeout: 5000
+ Example:StartAutomationTemperature 150
+ """
+ MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+ """
+ Stops temperature ramping using Automation.
+ API Status: published
+ Command Timeout: 10000
+ Example:StopAutomationTemperature
+ """
+ MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+ """
+ Returns the status of the current temperature ramping using automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 300000
+ Example:GetAutomationTemperatureStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+ global GetAutomationTemperatureStatus_Response
+ if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+ return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+ """
+ Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+ active. Command is used by WaferMap to read if it must send MoveChuckAutoXY
+ instead of MoveChuck
+ API Status: published
+ Returns:
+ Active:int
+ Command Timeout: 1000
+ Example:GetAutomationActive
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+ return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex:int="", MoveScope:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ VueTrack vision search of the given needle index.
+ API Status: internal
+ Args:
+ NeedleIndex:int = 1
+ MoveScope:int = 1
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ ZMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationNeedleSearch 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+ global AutomationNeedleSearch_Response
+ if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+ return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ AutomationReferenceSearch exposes the functionality of searching the Automation
+ reference target via remote command
+ API Status: internal
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ ZOffset:Decimal
+ XYMatchScore:Decimal
+ Command Timeout: 60000
+ Example:AutomationReferenceSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+ global AutomationReferenceSearch_Response
+ if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+ return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the configured motorized positioners to a safe position
+ API Status: internal
+ Command Timeout: 60000
+ Example:MovePositionersSafe
+ """
+ MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn:int="", ForceLastCorrection:int=""):
+ """
+ Starts Constant Contact mode using Automation. The Automation will re-adjust the
+ wafer during ramping to the new target temperature.
+ API Status: published
+ Args:
+ IsOn:int = 0
+ ForceLastCorrection:int = 0
+ Command Timeout: 5000
+ Example:SetConstantContactMode 1
+ """
+ MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+ """
+ Returns the status of the current ConstantContact automation process.
+ API Status: published
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 5000
+ Example:GetConstantContactModeStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+ global GetConstantContactModeStatus_Response
+ if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+ return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate:int=""):
+ """
+ Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+ be used to e.g. deactivate automation programmatically in case it is no
+ longer used. When activating automation, the command will return an error in
+ case it is not possible (e.g. not trained)
+ API Status: published
+ Args:
+ Activate:int = 0
+ Command Timeout: 1000
+ Example:SetAutomationActive 1
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+ """
+ Performs an Automation search and position correction using the current chuck
+ position. Response is X, Y relative distance of adjustment.
+ API Status: published
+ Returns:
+ XOffset:Decimal
+ YOffset:Decimal
+ Command Timeout: 6000000
+ Example:AutomationSearchCurrentDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+ global AutomationSearchCurrentDie_Response
+ if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+ return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+ """
+ PreMapWafer finds actual singulated die locations and updates positions used by
+ WaferMap.
+ API Status: published
+ Returns:
+ NumberOfDies:int
+ Command Timeout: 14400000
+ Example:PreMapWafer
+ """
+ rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+ return int(rsp[0])
+
+def ISSProbeAlign():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs an probe to pad operation on the ISS with two RF positioners.
+ API Status: internal
+ Command Timeout: 6000000
+ Example:ISSProbeAlign
+ """
+ MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery:int=""):
+ """
+ FindWaferCenter finds the center of the wafer using edge detection.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:FindWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+ global FindWaferCenter_Response
+ if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+ return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery:int=""):
+ """
+ LocateHomeDie finds the center of the wafer using edge detection and sets the
+ home position.
+ API Status: published
+ Args:
+ NoManualRecovery:int = 0
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 300000
+ Example:LocateHomeDie
+ """
+ rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+ global LocateHomeDie_Response
+ if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+ return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName:str="", ProbeID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stores the provided X or Y offset for the given probe for the specified layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Command Timeout: 10000
+ Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+ """
+ MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+ If optional ProbeID parmameter is set, it removes just that probe from the
+ layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 10000
+ Example:DeleteAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+ just that probe from the layout.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ ProbeID:int = 0
+ Command Timeout: 30000
+ Example:CaptureAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move to the probes to specfied layout which are offsets from the trained
+ positions.
+ API Status: internal
+ Args:
+ LayoutName:str = ""
+ Command Timeout: 300000
+ Example:MoveToAutomationProbeLayout "layout1"
+ """
+ MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+ """
+ Reset automation data back to trained values.
+ API Status: published
+ Command Timeout: 10000
+ Example:ResetAutomation
+ """
+ MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+ """
+ GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+ returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+ API Status: published
+ Returns:
+ ChuckX:Decimal
+ ChuckY:Decimal
+ Command Timeout: 10000
+ Example:GetWaferCenter
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+ global GetWaferCenter_Response
+ if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+ return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initializes the eVue focus stage by finding the limit switches
+ API Status: internal
+ Command Timeout: 30000
+ Example:InitEvueFocusStage
+ """
+ MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Args:
+ NumTraceEntriesPreTrigger:int = 0
+ Command Timeout: 30000
+ Example:EvueSetNumTraceEntriesPreTrigger 14
+ """
+ MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the number of trace log items to preserve prior to the trigger event. With
+ the continuous event capture log in Bluestone, up to {X} events are captured and
+ kept after the trigger event is sensed. Then, events are captured after the
+ trigger event until the trace log is full and then trace capture is halted.
+ API Status: internal
+ Returns:
+ NumTraceEntriesPreTrigger:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntriesPreTrigger
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+ return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts capturing events in the eVue motion capture log. Capture continues until
+ the log is full. However, log entries will overwrite the oldest entry until the
+ trigger event is encountered. Then, {X} events are preserved prior to the
+ trigger event and the oldest events are only overwritten if they are not part of
+ that preserved set.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EvueStartCaptureServoTrace
+ """
+ MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+ 16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+ trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+ stopped on requested server state entry bit4 - stopped by immediate command
+ bit5..31 - reserved
+ API Status: internal
+ Returns:
+ TraceMachineStatus:int
+ Command Timeout: 30000
+ Example:EvueGetTraceMachineStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+ return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+ bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+ lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+ stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+ an index but the 4-bit state that, if seen, is the trigger for trace capture)
+ bit8..31 - reserved
+ API Status: internal
+ Args:
+ TraceCaptureStopBits:int = 0
+ Command Timeout: 30000
+ Example:EvueSetTraceCaptureStopBits
+ """
+ MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the current status of the trace machine.
+ API Status: internal
+ Returns:
+ TraceEntries:int
+ Command Timeout: 30000
+ Example:EvueGetNumTraceEntries
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+ return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the N'th trace entry in the log.
+ API Status: internal
+ Args:
+ EntryIdx:int = 0
+ Returns:
+ CommandedPositionMotorCounts:int
+ CommandedPositionMicrons:Decimal
+ MeasuredPositionMotorCounts:int
+ MeasuredPositionMicrons:Decimal
+ TimestampMicroseconds:int
+ ServoStatus:int
+ PwmVal:int
+ Command Timeout: 30000
+ Example:EvueGetTraceEntry 32
+ """
+ rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+ global EvueGetTraceEntry_Response
+ if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+ return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the distance in X,Y between the center tips of the RF probes.
+ API Status: internal
+ Args:
+ ImageFilename:str = ""
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 5000
+ Example:AutomationRFProbeSearch
+ """
+ rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+ global AutomationRFProbeSearch_Response
+ if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+ return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the AutoRF calibration sequence.
+ API Status: internal
+ Command Timeout: 3000
+ Example:StartAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the currently running AutoRF calibraiton.
+ API Status: internal
+ Command Timeout: 10000
+ Example:StopAutoRFCalibration
+ """
+ MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the status of the AutoRF calibration sequence.
+ API Status: internal
+ Returns:
+ StatusId:int
+ StatusStr:str
+ Command Timeout: 1000
+ Example:GetAutoRFCalibrationStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+ global GetAutoRFCalibrationStatus_Response
+ if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+ return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the diagnostic state information for the provided index.
+ API Status: internal
+ Args:
+ Index:int = 0
+ Returns:
+ DiagnosticInfo:str
+ Command Timeout: 5000
+ Example:GetAutomationLastStepDiagnostics
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the WLEM Nano Chamber State.
+ API Status: internal
+ Args:
+ State:str = "Free"
+ Command Timeout: 5000
+ Example:SetWLEMNanoChamberState Free
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the WLEM Nano Chamber State.
+ API Status: internal
+ Returns:
+ State:str
+ Command Timeout: 5000
+ Example:GetWLEMNanoChamberState
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMState NCSeal 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the state of a WLEM pneumatic control (valve).
+ API Status: internal
+ Args:
+ State:str = "NCSeal"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMState NCSeal
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+ return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets the value of a WLEM Sensor.
+ API Status: internal
+ Args:
+ Sensor:str = "O2Concentration"
+ Returns:
+ Value:Decimal
+ Command Timeout: 5000
+ Example:GetWLEMSensorValue O2Concentration
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+ return Decimal(rsp[0])
+
+def SetWLEMOption(Option:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Value:int = 0
+ Command Timeout: 5000
+ Example:SetWLEMOption MinimizeToTray 1
+ """
+ MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets a WLEM Control program option.
+ API Status: internal
+ Args:
+ Option:str = "MinimizeToTray"
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:GetWLEMOption MinimizeToTray
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+ return int(rsp[0])
+
+def NewTesterProject(LotID:str="", TileID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a new Lot/Tile is to be tested. The tester
+ responds with the correct project name for the test. This is needed because the
+ prober needs to verify that the correct project is loaded. In case no valid
+ project is available, the command is returned with an error.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ TileID:str = ""
+ Returns:
+ ProjectName:str
+ Command Timeout: 30000
+ Example:NewTesterProject Lot01 Tile01
+ """
+ rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn:int="", DieRow:int="", ActiveDies:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester to begin measuring (Needles are in correct
+ position and in contact). The command is responded when the measurement has
+ finished. The response string holds the binning information separated by comma.
+ For deactivated dies, a bin value of '0' should be responded.
+ API Status: internal
+ Args:
+ DieColumn:int = 0
+ DieRow:int = 0
+ ActiveDies:str = ""
+ Returns:
+ BinNumbers:str
+ Command Timeout: 100000
+ Example:StartMeasurement 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current substrate has
+ finished. It enables the tester application to save measurement data and/or
+ prepare for the next substrate.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfWafer
+ """
+ MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command tells the tester, that the test of the current lot has finished. It
+ enables the tester application to save measurement data and/or prepare for the
+ next lot.
+ API Status: internal
+ Command Timeout: 30000
+ Example:EndOfLot
+ """
+ MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProductID that is to be tested. The
+ tester can respond with an error in case the ProductID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ ProductID:str = ""
+ Command Timeout: 30000
+ Example:VerifyProductID Product123
+ """
+ MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the LotID that is to be tested. The tester
+ can respond with an error in case the LotID is not allowed for testing.
+ API Status: internal
+ Args:
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyLotID Lot123
+ """
+ MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the SubstrateID that is to be tested. The
+ tester can respond with an error in case the SubstrateID is not allowed for
+ testing.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ Command Timeout: 30000
+ Example:VerifySubstrateID Substrate123
+ """
+ MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard:str="", Touchdowns:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the ProbecardID and touchdowns that is
+ used for testing. The tester can respond with an error in case the Probecard is
+ not allowed for testing.
+ API Status: internal
+ Args:
+ ProbeCard:str = ""
+ Touchdowns:int = 0
+ Command Timeout: 30000
+ Example:VerifyProbecard Probecard123 10596
+ """
+ MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester about the User ID. The tester can respond with
+ an error in case the User ID is not allowed for testing.
+ API Status: internal
+ Args:
+ User:str = ""
+ Command Timeout: 30000
+ Example:VerifyUserID User123
+ """
+ MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the job was aborted and no more test will
+ happen.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbort
+ """
+ MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that a wafer is ready for testing which will
+ immediately start. This command is sent in the recipe sequence "Verify
+ SOTReady".
+ API Status: internal
+ Command Timeout: 30000
+ Example:VerifySOTReady
+ """
+ MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID:str="", CassettePlace:str="", LotID:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+ informs the tester about the current wafer on the chuck.
+ API Status: internal
+ Args:
+ SubstrateID:str = ""
+ CassettePlace:str = ""
+ LotID:str = ""
+ Command Timeout: 30000
+ Example:VerifyWaferStart Wafer01 1 Lot01
+ """
+ MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command will be sent after the user selected which wafers are to be tested.
+ It contains a string which represents the state of each wafer: 0 = empty, 1 =
+ full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+ deselected
+ API Status: internal
+ Args:
+ CassetteCmd:str = ""
+ Returns:
+ CassetteRsp:str
+ Command Timeout: 30000
+ Example:TesterCassetteInfo 0000001110000000010010111
+ """
+ rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is sent after selecting a project file in the VeloxPro product
+ setup page. The command sends the name of the project to tester for
+ verification.
+ API Status: internal
+ Args:
+ ProjectName:str = ""
+ Command Timeout: 30000
+ Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+ """
+ MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command informs the tester that the test for the current wafer was aborted
+ and no more tests will happen with the current wafer. The job will continue
+ though.
+ API Status: internal
+ Command Timeout: 30000
+ Example:TesterAbortWafer
+ """
+ MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts execution of one test. It returns a bin number or multple bin numbers
+ when clusters are enabled in the WaferMap (one number for each die in a
+ cluster). The command starts execution of one test. It returns a bin number or
+ multple bin numbers when clusters are enabled in the WaferMap (one number for
+ each die in a cluster).
+ API Status: internal
+ Returns:
+ BitNumber:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+ return int(rsp[0])
+
+def StartTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Starts the test of a wafer. Depending on the cluster definitions queried from
+ the WaferMap, all clusters or all dies will be tested. The command starts the
+ test of a wafer. Depending on the cluster definitions queried from the WaferMap
+ all clusters or all dies will be tested.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops the wafer test.
+ API Status: internal
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line:int="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the selected line of PA port.
+ API Status: internal
+ Args:
+ Line:int = 0
+ Value:int = 0
+ Command Timeout: 10000
+ Example:SetTTLLine 2 0
+ """
+ MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the I/O lines as bit array.
+ API Status: internal
+ Returns:
+ LineA:int
+ LineB:int
+ LineC:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+ global GetTTLLines_Response
+ if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+ return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns returns the error 914 if the test is in progress.
+ API Status: internal
+ Returns:
+ ErrCode:int
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+ return int(rsp[0])
+
+def StartScript(ScriptName:str=""):
+ """
+ Starts the script and returns the response immediately.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000
+ Example:StartScript myscript
+ """
+ MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName:str=""):
+ """
+ Command returns information about Communicator status.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Returns:
+ Running:int
+ LastError:int
+ Title:str
+ Command Timeout: 5000
+ Example:GetRunStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+ global GetRunStatus_Response
+ if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+ return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+ """
+ Command closes the program. Used during ProjectFile handling.
+ API Status: published
+ Command Timeout: 10000
+ Example:CloseCommunicator
+ """
+ MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName:str=""):
+ """
+ Executes the script and returns the response afterwards.
+ API Status: published
+ Args:
+ ScriptName:str = ""
+ Command Timeout: 10000000
+ Example:DoScript myscript
+ """
+ MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Reads Kernel Data to KernelSetup (Left Program pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReadKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves Kernel Data (Left Program pane) to File. An existing File will be
+ overwritten. If the Folder does not exist, it will be created
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Loads File Data to KernelSetup (Right Program pane).
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+ """
+ MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces Kernel Data (Left pane) by File Data (Right pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceKernelDataByFileData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Replaces File Tree (Right pane) by Kernel Data (Left pane).
+ API Status: internal
+ Args:
+ SilentMode:int = 0
+ Command Timeout: 300000
+ Example:ReplaceFileTreeByKernelData 0
+ """
+ MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+ the Folder does not exist, it will be created.
+ API Status: internal
+ Args:
+ FileName:str = ""
+ Command Timeout: 10000
+ Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+ """
+ MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature:Decimal="", Unit:str="", ReduceContact:int=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the chuck. An
+ answer to the command will be returned after reaching the given temperature and
+ waiting the soak time or an unexpected interrupt of the process. Given back is
+ the already reached temperature.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ ReduceContact:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 36000000
+ Example:HeatChuck 61.3 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+ global HeatChuck_Response
+ if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+ return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature:Decimal="", Unit:str="", UseContactSafety:int=""):
+ """
+ Sets a new target temperature and starts the heating or cooling of the
+ temperature chuck. The new target temperature is returned immediately as the
+ command does not wait until heating is complete.
+ API Status: published
+ Args:
+ Temperature:Decimal = 25
+ Unit:str = "Celsius"
+ UseContactSafety:int = 1
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:SetHeaterTemp 55.5 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+ global SetHeaterTemp_Response
+ if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+ return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit:str="", ExternalHeaterID:int=""):
+ """
+ Reads the current temperature of the chuck and determines the status of the
+ thermal system.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ ExternalHeaterID:int = 0
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Status:str
+ Command Timeout: 60000
+ Example:GetHeaterTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+ global GetHeaterTemp_Response
+ if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+ return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode:int=""):
+ """
+ Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+ chuck is heated with a constant current to avoid noise from the temperature
+ control. The hold mode can be enabled only in HoldReady state.
+ API Status: published
+ Args:
+ HoldMode:int = 1
+ Returns:
+ RespHoldMode:int
+ Command Timeout: 60000
+ Example:EnableHeaterHoldMode 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+ return int(rsp[0])
+
+def StopHeatChuck():
+ """
+ Stops a pending heating or cooling process. If the device is not at temperature,
+ the actual temperature is set as target temperature.
+ API Status: published
+ Command Timeout: 60000
+ Example:StopHeatChuck
+ """
+ MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit:str=""):
+ """
+ Returns the current dew point temperature, if a dew point sensor is connected.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetDewPointTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+ global GetDewPointTemp_Response
+ if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+ return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the currently set temperature chuck options.
+ API Status: internal
+ Returns:
+ UseSoakTime:int
+ SyncTemp:int
+ CurrConnection:int
+ MinTemperature:Decimal
+ MaxTemperature:Decimal
+ UsePurge:int
+ UseDynamicSoakTime:int
+ UseFixedDieSoakTime:int
+ UseDynamicDieSoakTime:int
+ UseEcoMode:int
+ PurgeOnChamberDoor:int
+ ForceBypassPurge:int
+ DoorClosedTime:int
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+ global GetTemperatureChuckOptions_Response
+ if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+ return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak:int="", SyncTemp:int="", CurrConnection:int="", UsePurge:int="", UseDynamicWaferSoak:int="", UseFixedDieSoakTime:int="", UseDynamicDieSoakTime:int="", UseEcoMode:int="", PurgeOnChamberDoor:int="", ForceBypassPurge:int="", DoorClosedTime:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command is used to change the currently set temperature chuck options.
+ API Status: internal
+ Args:
+ UseFixedWaferSoak:int = -1
+ SyncTemp:int = -1
+ CurrConnection:int = -1
+ UsePurge:int = -1
+ UseDynamicWaferSoak:int = -1
+ UseFixedDieSoakTime:int = -1
+ UseDynamicDieSoakTime:int = -1
+ UseEcoMode:int = -1
+ PurgeOnChamberDoor:int = -1
+ ForceBypassPurge:int = -1
+ DoorClosedTime:int = -1
+ Returns:
+ UseFixedWaferSoakRsp:int
+ SyncTempRsp:int
+ CurrConnectionRsp:int
+ UsePurgeRsp:int
+ UseDynamicWaferSoakRsp:int
+ UseFixedDieSoakTimeRsp:int
+ UseDynamicDieSoakTimeRsp:int
+ UseEcoModeRsp:int
+ PurgeOnChamberDoorRsp:int
+ ForceBypassPurgeRsp:int
+ DoorClosedTimeRsp:int
+ Command Timeout: 300000
+ Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+ global SetTemperatureChuckOptions_Response
+ if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+ return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+ """
+ Returns the current soak time values in seconds and the soaking status.
+ API Status: published
+ Returns:
+ FixedWaferSoakTime:int
+ FixedWaferSoakStatus:int
+ DynamicWaferSoakTime:Decimal
+ DynamicWaferSoakStatus:int
+ FixedDieSoakTime:Decimal
+ DynamicDieSoakTime:Decimal
+ FixedDieSoakStatus:int
+ DynamicDieSoakStatus:int
+ Command Timeout: 60000
+ Example:GetHeaterSoak
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+ global GetHeaterSoak_Response
+ if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+ return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime:int="", DynamicWaferSoakTime:Decimal="", FixedDieSoakTime:Decimal="", DynamicDieSoakTime:Decimal=""):
+ """
+ Sets the new soak time values. The unit of the values is seconds. If soak time
+ is actually running, it may be affected by the change.
+ API Status: published
+ Args:
+ FixedWaferSoakTime:int = 60
+ DynamicWaferSoakTime:Decimal = -1
+ FixedDieSoakTime:Decimal = -1
+ DynamicDieSoakTime:Decimal = -1
+ Command Timeout: 60000
+ Example:SetHeaterSoak 60
+ """
+ MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby:int=""):
+ """
+ Switches the power save (standby) mode of the device on or off. If the device is
+ in power save mode, setting and reading temperatures switches off the power save
+ mode automatically.
+ API Status: published
+ Args:
+ Standby:int = 1
+ Returns:
+ RespStandby:int
+ Command Timeout: 60000
+ Example:EnableHeaterStandby 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+ return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+ """
+ Returns values of the temperature chuck status. The status byte gives
+ information about the current controller's action. The dew point sensor status
+ encapsulates information, if such a sensor is connected, and if the actual dew
+ point difference temperature is readable (active). It can be used for purge
+ control. Soak time left (in seconds) is used when soak time is actually running.
+ API Status: published
+ Returns:
+ Status:str
+ DPSensor:int
+ SoakTimeLeft:int
+ HasEcoMode:int
+ Command Timeout: 60000
+ Example:ReadTemperatureChuckStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+ global ReadTemperatureChuckStatus_Response
+ if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+ return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit:str=""):
+ """
+ Reads the target temperature of the chuck.
+ API Status: published
+ Args:
+ Unit:str = "Celsius"
+ Returns:
+ RespTemperature:Decimal
+ RespUnit:str
+ Command Timeout: 60000
+ Example:GetTargetTemp C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+ global GetTargetTemp_Response
+ if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+ return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command sets the window for the target temperture which is the window in which a
+ station is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Args:
+ Window:Decimal = 1
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:SetThermoWindow 2.0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+ return Decimal(rsp[0])
+
+def GetThermoWindow():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command returns the current thermo window which is the window in which a station
+ is assumed to be at temp. Only supported on Nucleus stations.
+ API Status: internal
+ Returns:
+ RespWindow:Decimal
+ Command Timeout: 60000
+ Example:GetThermoWindow
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+ return Decimal(rsp[0])
+
+def SendThermoCommand(Command:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sends a command string to the thermal chuck using the thermal chuck protocol and
+ returns the thermal chucks response as command response. This command can be
+ used to access thermal chuck features that are not exposed as standalone SCI
+ commands. Command is currently implemented for ERS and ATT chucks.
+ API Status: internal
+ Args:
+ Command:str = ""
+ Returns:
+ Response:str
+ Command Timeout: 5000
+ Example:SendThermoCommand RH
+ """
+ rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID:int=""):
+ """
+ Returns the status of a single AUX site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ FlagsMode:int
+ Comp:str
+ PresetHeight:str
+ AuxSiteType:str
+ Command Timeout: 10000
+ Example:ReadAuxStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+ global ReadAuxStatus_Response
+ if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+ return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID:int="", Unit:str="", PosRef:str="", Comp:str=""):
+ """
+ Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+ position is read for the chuck stage. If no AUX ID is given, it tries to read
+ the position from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ PosRef:str = "Home"
+ Comp:str = "Default"
+ Returns:
+ AuxIDEcho:int
+ X:Decimal
+ Y:Decimal
+ Z:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxPosition 1 Y Z
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+ global ReadAuxPosition_Response
+ if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+ return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID:int="", Unit:str=""):
+ """
+ Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+ all response values are read from chuck stage. If no AUX ID is given, it tries
+ to read the heights from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Contact:Decimal
+ Overtravel:Decimal
+ AlignDist:Decimal
+ SepDist:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxHeights 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+ global ReadAuxHeights_Response
+ if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+ return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID:int="", Overtravel:int=""):
+ """
+ Modes manage the way a stage behaves when it is in contact height. AUX site mode
+ holds only a single flag. Flags can be turned on by using the value 1 or turned
+ off by using the value 0. If you do not want to change the flag - use the value
+ of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+ move an additional overtravel on every contact move.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Overtravel:int = 2
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxMode 1 2
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+ return int(rsp[0])
+
+def SetAuxHome(AuxID:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+ """
+ Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+ sites coordinate system for later movements. Usually this position is identical
+ to the die home position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHome 1 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+ return int(rsp[0])
+
+def SetAuxIndex(AuxID:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+ """
+ Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+ chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxIndex 1 1000. 1000. Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+ return int(rsp[0])
+
+def SetAuxHeight(AuxID:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+ """
+ Sets the AUX sites contact height and corresponding gaps for overtravel,
+ alignment and separation height. A contact height search gap for contact search
+ with edge sensor can also be set. This search gap is always identical for all
+ AUX sites. Without any optional parameters the command sets contact height to
+ the current position.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ PresetHeight:str = "Contact"
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Value:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxHeight 1 C 0 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+ return int(rsp[0])
+
+def ReadAuxIndex(AuxID:int="", Unit:str=""):
+ """
+ Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+ is read from chuck stage. If no AUX ID is given, it tries to read the index from
+ the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Unit:str = "Microns"
+ Returns:
+ AuxIDEcho:int
+ IndexX:Decimal
+ IndexY:Decimal
+ Command Timeout: 10000
+ Example:ReadAuxIndex 1 Y
+ """
+ rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+ global ReadAuxIndex_Response
+ if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+ return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID:int="", Mode:str="", Unit:str="", Position:Decimal=""):
+ """
+ Sets the AUX sites theta home position. It defines the origin of the AUX sites
+ theta coordinate system for later movements. If AUX ID is set to 0, theta home
+ position is set for chuck stage.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Mode:str = "0"
+ Unit:str = "Microns"
+ Position:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxThetaHome 1 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+ return int(rsp[0])
+
+def EnableOffset(Stage:str="", Enable:int="", Move:int=""):
+ """
+ Enables or disables the Offset XY compensation for the selected stage. If the
+ compensation holds an offset different from zero, the chuck is automatically
+ moved the distance of the offset. The chuck also moves automatically to a safe
+ height. The move can be disabled by the third parameter. This may put the stage
+ outside the software fence.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Enable:int = 1
+ Move:int = 1
+ Command Timeout: 60000
+ Example:EnableOffset C 1
+ """
+ MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+ """
+ Sets the offset values for the Offset XY compensation for the selected stage.
+ The changes take effect immediately. Note that the Offset XY compensation must
+ be enabled for the values to take effect. The compensation is enabled or
+ disabled using EnableOffset command.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Command Timeout: 5000
+ Example:SetOffset C 100000.0 0.0
+ """
+ MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage:str=""):
+ """
+ Gets information about the Offset XY compensation of the selected stage,
+ including the stored offset values and whether the compensation is enabled or
+ disabled.
+ API Status: published
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ Enable:int
+ OffsetX:Decimal
+ OffsetY:Decimal
+ Command Timeout: 5000
+ Example:GetOffsetInfo C
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+ global GetOffsetInfo_Response
+ if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+ return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage:str="", AuxSite:int="", X:Decimal="", Y:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the switch position of a stage. This is the position to move to if an aux
+ site gets active. This is only supported for the chuck and it's aux sites. Aux
+ index 0 means wafer site, 1 means aux site 1 and so on.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ AuxSite:int = 0
+ X:Decimal = 0
+ Y:Decimal = 0
+ Command Timeout: 5000
+ Example:SetSwitchPosition C 0 5000 5000
+ """
+ MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID:int=""):
+ """
+ Moves the chuck to the position of a given AUX site. A safe height is used for
+ the move. If AUX ID is set to 0, the target of the move is the wafer site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 60000
+ Example:MoveAuxSite 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount:int=""):
+ """
+ Sets the number of available AUX sites. For preparing for example two cal
+ chucks, the count must be set to 2. For the changes to take effect the system
+ needs to be restarted.
+ API Status: published
+ Args:
+ AuxSiteCount:int = 0
+ Command Timeout: 10000
+ Example:SetAuxSiteCount 2
+ """
+ MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+ """
+ Reads the number of available AUX sites and the ID of the actual active AUX
+ site. If this is 0, the chuck stage is currently active.
+ API Status: published
+ Returns:
+ AuxSiteCount:int
+ ActualAuxSite:int
+ Command Timeout: 10000
+ Example:GetAuxSiteCount
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+ global GetAuxSiteCount_Response
+ if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+ return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID:int="", AuxSiteName:str=""):
+ """
+ Sets the description of an AUX site. With AUX ID zero, the description of the
+ wafer site can be set.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteName:str = ""
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteName 1 Aux site 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+ return int(rsp[0])
+
+def GetAuxSiteName(AuxID:int=""):
+ """
+ This command reads the description of an AUX site. If AUX ID is set to 0, the
+ description of the chuck stage is given back. If no AUX ID is given, it tries to
+ read from the active site.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ AuxSiteName:str
+ Command Timeout: 10000
+ Example:GetAuxSiteName 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+ global GetAuxSiteName_Response
+ if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+ return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID:str=""):
+ """
+ Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+ dependent from the type of the AUX site and from the duration and the cleaning
+ count that is set in configuration. The cleaning algorithm includes both a move
+ to the pad site and a move back to the source site.
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 300000
+ Example:CleanProbeTip 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+ return int(rsp[0])
+
+def SetAuxSiteType(AuxID:int="", AuxSiteType:str=""):
+ """
+ Sets the type for a given AUX site. It depends on the type of the AUX site, if
+ there is a cleaning algorithm available. It is not possible to set the type of
+ the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ AuxSiteType:str = "AuxUnknown"
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetAuxSiteType 1 G
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+ return int(rsp[0])
+
+def SetCleaningParams(AuxID:int="", Count:int="", Time:int=""):
+ """
+ Sets the cleaning parameters for a given AUX site. It is not possible to set the
+ cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+ tries to set the parameters of the active site. The cleaning count defines,
+ how much times the cleaning is performed repeatedly. The cleaning time defines,
+ how much milliseconds the needles wait in cleaning position during each
+ cleaning cycle.
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Count:int = 1
+ Time:int = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:SetCleaningParams 1 5 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+ return int(rsp[0])
+
+def GetCleaningParams(AuxID:int=""):
+ """
+ Reads the cleaning parameters of a given AUX site. It is not possible to read
+ cleaning parameters of the wafer site (AUX site 0).
+ API Status: published
+ Args:
+ AuxID:int = -1
+ Returns:
+ AuxIDEcho:int
+ Count:int
+ Time:int
+ Remaining:int
+ Command Timeout: 30000
+ Example:GetCleaningParams
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+ global GetCleaningParams_Response
+ if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+ return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Rotate the switch, home, and fence positions to match the current chuck theta
+ angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+ that don't move theta.
+ API Status: internal
+ Args:
+ AuxID:int = -1
+ XOffset:Decimal = 0
+ YOffset:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 5000
+ Example:UpdateAuxSitePositions 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+ return int(rsp[0])
+
+def ResetCleaningPosition(AuxID:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+ """
+ Resets the cleaning position to the beginning of the cleaning aux site (home).
+ API Status: published
+ Args:
+ AuxID:str = "-1"
+ OffsetX:Decimal = 0
+ OffsetY:Decimal = 0
+ Returns:
+ AuxIDEcho:int
+ Command Timeout: 10000
+ Example:ResetCleaningPosition 5
+ """
+ rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+ return int(rsp[0])
+
+def BnR_EchoData(ControllerID:int="", TestCmd:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Test Command for the Kernel Communication. It is like a ping command. The given
+ text string is returned unchanged.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ TestCmd:str = "Test"
+ Returns:
+ TestRsp:str
+ Command Timeout: 5000
+ Example:BnR_EchoData 1 Hello World
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID:int="", Module:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the actual version information of the controller software.
+ The 'Version' value contains version number and revision level of the actual
+ implementation. The text string contains a
+ code description, version number and the revision date.
+ The 'Module' byte is optional (default is K).
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Module:str = "K"
+ Returns:
+ Version:Decimal
+ Description:str
+ Command Timeout: 5000
+ Example:BnR_ReportKernelVersion 1 K
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+ global BnR_ReportKernelVersion_Response
+ if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+ return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns information about the connected station.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StationType:str
+ Type:str
+ Command Timeout: 5000
+ Example:BnR_GetStationType 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+ global BnR_GetStationType_Response
+ if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+ return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID:int="", Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Restarts the BnR controller.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:str = "X"
+ Command Timeout: 10000
+ Example:BnR_ResetController 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID:int="", Channel:str="", State:int="", CycleTime:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Controls the Velox output channel signals. It can be used to activate/deactivate
+ outputs.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ State:int = 0
+ CycleTime:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetOutput 1 1000 1 2000
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an output channel. By using the string identifier DO_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DO_WaferVacuum"
+ Returns:
+ State:int
+ AllOutputs:str
+ Command Timeout: 5000
+ Example:BnR_GetOutput 1 DO_WaferVacuum
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+ global BnR_GetOutput_Response
+ if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+ return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the state of an input channel. By using the string identifier DI_ALL, a
+ string list of all outputs is returned in addition
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "DI_MotorPower"
+ Returns:
+ State:int
+ AllInputs:str
+ Command Timeout: 5000
+ Example:BnR_GetInput 1 DI_MotorPower
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+ global BnR_GetInput_Response
+ if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+ return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID:int="", Channel:str="", OutputPercent:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets an analog output channel to a given value.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ OutputPercent:Decimal = 50
+ Command Timeout: 5000
+ Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID:int="", Channel:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current value of an analog output or input.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Channel:str = "AO_PurgeDewPoint"
+ Returns:
+ Value:Decimal
+ UnderOverflow:int
+ Command Timeout: 5000
+ Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+ global BnR_GetAnalogIO_Response
+ if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+ return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the startup status of the BnR controller to determine if the controller
+ is properly booted or still starting.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ StartupStatus:str
+ AdditionalStatusInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetStartupStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+ global BnR_GetStartupStatus_Response
+ if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+ return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Creates a Sdm System Dump file on the B&R flash
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 60000
+ Example:BnR_CreateSdmSystemDump
+ """
+ MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Gets controller data from the B&R controller. Currently used for init
+ information.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Command Timeout: 10000
+ Example:BnR_GetControllerData 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID:int="", MessageType:str="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to write a (native) message to Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Message:str = ""
+ Command Timeout: 5000
+ Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID:int="", MessageType:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to read a (native) message from Controller
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ MessageType:str = "mtCryoLoader"
+ Returns:
+ Message:str
+ Command Timeout: 5000
+ Example:BnR_ReadMessage 1 mtCryoLoader
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID:int="", ShowAll:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a data stream handle which represents a data stream of setup parameters
+ and requires the BnR_GetNextDatum command.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ ShowAll:int = 0
+ Returns:
+ IdentityToken:int
+ SizeNoAll:int
+ Command Timeout: 5000
+ Example:BnR_GetDataIterator 1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+ global BnR_GetDataIterator_Response
+ if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+ return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID:int="", IdentityToken:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the next parameter from the data stream. Fields are separated by a
+ colon. Structure of the response parameter Value:
+ Path_Path:Name:Description:Value
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ IdentityToken:int = 0
+ Returns:
+ IsLastDatum:int
+ DatumCode:int
+ PathNameDescrValue:str
+ Command Timeout: 10000
+ Example:BnR_GetNextDatum 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+ global BnR_GetNextDatum_Response
+ if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+ return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID:int="", PathNameAndValue:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the value of a parameter. An empty parameter string saves the whole
+ configuration to non-volatile memory. Fields are separated by a colon.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathNameAndValue:str = ""
+ Command Timeout: 20000
+ Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID:int="", PathName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a value string. The Value string consists of the value and the
+ description. The Locator only consists of the path and the name. All fields are
+ separated by a colon. Structure of the command parameter Locator:
+ Path_Path:Name Structure of the response parameter Value: Value:Description
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ PathName:str = ""
+ Returns:
+ DatumCode:int
+ ValueDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+ global BnR_GetDatum_Response
+ if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+ return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID:int="", Task:str="", PCmdInt1:int="", PCmdInt2:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes an internal BnR Task
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Task:str = ""
+ PCmdInt1:int = 0
+ PCmdInt2:int = 0
+ Returns:
+ RspInt:int
+ RspString:str
+ Command Timeout: 10000
+ Example:BnR_DoInternalTask 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+ global BnR_DoInternalTask_Response
+ if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+ return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage:str="", Unit:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+ as well as the commanded positions.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Unit:str = "Microns"
+ Returns:
+ XorT:Decimal
+ Y:Decimal
+ Z:Decimal
+ CommandedXorT:Decimal
+ CommandedY:Decimal
+ CommandedZ:Decimal
+ Command Timeout: 5000
+ Example:BnR_GetPosition 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+ global BnR_GetPosition_Response
+ if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+ return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage:str="", XValue:Decimal="", YValue:Decimal="", VelX:Decimal="", VelY:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a XY movement for a specified stage. This can be either a
+ blocking or non blocking move.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ VelX:Decimal = 0
+ VelY:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ X:Decimal
+ Y:Decimal
+ Command Timeout: 60000
+ Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+ global BnR_Move_Response
+ if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+ return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage:str="", ZValue:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the stage Z axis to a new position.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZValue:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ Z:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZ 1 C 12000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID:int="", Stage:str="", ZDistance:Decimal="", TriggerEveryNthCycle:int="", Vel:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command executes a scan movement of the Z axis that sets a digital output
+ every couple microns to trigger e.g. a camera. After the move is finished, the
+ command returns a list of Z heights at which the digital output was set.
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Stage:str = "Chuck"
+ ZDistance:Decimal = 1000
+ TriggerEveryNthCycle:int = 2
+ Vel:Decimal = 10
+ Command Timeout: 300000
+ Example:BnR_ScanMoveZ 1 C 1000 6 10
+ """
+ MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue:Decimal="", Vel:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Executes a movement of the theta axis, either blocking or non blocking
+ API Status: internal
+ Args:
+ TValue:Decimal = 0
+ Vel:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ T:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveT 1 1.003 10 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage:str="", FlagsStop:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Stops 1... all axes of a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsStop:int = 15
+ Command Timeout: 5000
+ Example:BnR_StopAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage:str="", FlagsInit:int="", FlagsDirection:int="", FlagsInitInPlace:int="", LowLimitX:Decimal="", LowLimitY:Decimal="", LowLimitZ:Decimal="", LowLimitTh:Decimal="", InitInPlaceMoveRangeX:Decimal="", InitInPlaceMoveRangeY:Decimal="", InitInPlaceMoveRangeZ:Decimal="", InitInPlaceMoveRangeTh:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Machine Coordinate System: X Y Z Theta - _FlagsInit_: X, Y, Z, Theta -
+ _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+ _FlagsInitInPlace_: X, Y, Z, Theta All flags can be accessed by indirect
+ members. Initializes the stage and resets current coordinate system. Should be
+ used only in cases when the reported coordinates do not correspond to real
+ position of mechanics. Init in Place performs the initialization without any
+ movements.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ FlagsInit:int = 0
+ FlagsDirection:int = 0
+ FlagsInitInPlace:int = 0
+ LowLimitX:Decimal = 0
+ LowLimitY:Decimal = 0
+ LowLimitZ:Decimal = 0
+ LowLimitTh:Decimal = 0
+ InitInPlaceMoveRangeX:Decimal = 0
+ InitInPlaceMoveRangeY:Decimal = 0
+ InitInPlaceMoveRangeZ:Decimal = 0
+ InitInPlaceMoveRangeTh:Decimal = 0
+ Command Timeout: 300000
+ Example:BnR_InitAxis 1 C 7
+ """
+ MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+ g/homing/continuousmotion/discretemotion/synchronizedmotion)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ State:str
+ AdditionalStateInfo:str
+ Command Timeout: 5000
+ Example:BnR_GetAxisState 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+ global BnR_GetAxisState_Response
+ if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+ return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns some axis status information
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ Initialized:int
+ PositiveEndlimit:int
+ NegativeEndlimit:int
+ Command Timeout: 5000
+ Example:BnR_GetAxisStatus 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+ global BnR_GetAxisStatus_Response
+ if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+ return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage:str="", QuietMode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to enable the quiet mode for a stage (quiet turns motors powerless)
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ QuietMode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetQuietMode 1 C 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to query the quiet mode for a stage
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Returns:
+ QuietMode:int
+ Command Timeout: 5000
+ Example:BnR_GetQuietMode 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+ return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage:str="", Axis:str="", InfoType:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command returns various axis information, dependent on the InfoType
+ parameter
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ InfoType:str = "StallInfo"
+ Returns:
+ RspString:str
+ Command Timeout: 5000
+ Example:BnR_GetInternalAxisInfo 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage:str="", Axis:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command to get various information required for the BnR wiring tester tool.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Returns:
+ STIn_ModuleOK:int
+ STIn_LifeCnt:int
+ STIn_DrvOK:int
+ STIn_OvertemperatureError:int
+ STIn_CurrentError:int
+ STIn_OvercurrentError:int
+ STIn_RefPulsePos:int
+ STIn_RefPulseCnt:int
+ STIn_ModulePowerSupplyError:int
+ STOut_SetTime:int
+ STOut_MotorStep0:int
+ STOut_DriveEnable:int
+ STOut_BoostCurrent:int
+ STOut_StandStillCurrent:int
+ STOut_ClearError:int
+ CMIn_ModuleOK:int
+ CMIn_SDCLifeCount:int
+ CMIn_Encoder:int
+ CMIn_EncoderTimeValid:int
+ CMIn_DigitalInput1:int
+ CMIn_DigitalInput2:int
+ CMIn_BWChannelA:int
+ CMIn_BWChannelB:int
+ CMIn_PowerSupply2:int
+ CMOut_QuitChannelA:int
+ CMOut_QuitChannelB:int
+ SWAxisErrorID:int
+ SWAxisErrorDesc:str
+ Command Timeout: 5000
+ Example:BnR_GetWiringTesterData 1 C X
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+ global BnR_GetWiringTesterData_Response
+ if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+ return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage:str="", Axis:str="", Value:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command allows moving a single axis to and e.g. in case of X does not
+ trigger a Y movement
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ Value:Decimal = 0
+ Vel:Decimal = 0
+ Dec:Decimal = 0
+ WaitFinished:int = 1
+ Returns:
+ PositionAfterMove:Decimal
+ Command Timeout: 60000
+ Example:BnR_MoveAxis 1 C X 20000 100 100 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+ return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ:Decimal="", WaitFinished:int="", ForcedAbsVelocity:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+ API Status: internal
+ Args:
+ ChuckTargetZ:Decimal = 0
+ WaitFinished:int = 1
+ ForcedAbsVelocity:int = 0
+ Returns:
+ ChuckZ:Decimal
+ ScopeX:Decimal
+ ScopeY:Decimal
+ ScopeZ:Decimal
+ Command Timeout: 600000
+ Example:BnR_MoveZCombined 1 17592.5 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+ global BnR_MoveZCombined_Response
+ if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+ return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage:str="", ZDown:Decimal="", XValue:Decimal="", YValue:Decimal="", ZUp:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ This command does a combined Z-XY-Z- move completely on the BnR-controller
+ without WinKernel interaction. This is a part of an ongoing optimization.
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ ZDown:Decimal = 0
+ XValue:Decimal = 0
+ YValue:Decimal = 0
+ ZUp:Decimal = 0
+ Command Timeout: 60000
+ Example:BnR_StepMove 1 C 250 1000 1000 250
+ """
+ MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos:Decimal="", Velocity:Decimal=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Performs a search move until the search end position is reached or the edge
+ sensor triggers. If the edge sensor triggers during the move, the trigger
+ position is returned.Otherwise, an edge sensor not found error is returned.
+ API Status: internal
+ Args:
+ SearchEndPos:Decimal = 0
+ Velocity:Decimal = 0
+ Returns:
+ EdgeSensorTriggerPos:Decimal
+ Command Timeout: 300000
+ Example:BnR_SearchEdgeSensor 3000 10
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+ return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns a collection of trace data
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Returns:
+ Data:str
+ Command Timeout: 5000
+ Example:BnR_GetTraceData 1 C
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID:int="", Mode:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Commands sets the trace mode
+ API Status: internal
+ Args:
+ ControllerID:int = 1
+ Mode:int = 0
+ Command Timeout: 5000
+ Example:BnR_SetTraceMode 1 1
+ """
+ MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str="", Value:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to change a module register value without controller restart
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Value:int = 0
+ Command Timeout: 5000
+ Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+ """
+ MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Development command to get any desired module register value
+ API Status: internal
+ Args:
+ Stage:str = "Chuck"
+ Axis:str = "XAxis"
+ MotorModule:int = 0
+ RegisterName:str = ""
+ Returns:
+ Value:int
+ Command Timeout: 5000
+ Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+ """
+ rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+ return int(rsp[0])
+
+def ProcessStationGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+ Initialized) and error code with error message when error.
+ API Status: internal
+ Returns:
+ Status:str
+ SubstratePresent:int
+ LastError:int
+ UseLoaderModule:int
+ WaferSizes:str
+ StatusMessage:str
+ IsLoaderJobRunning:int
+ Command Timeout: 25000
+ Example:ProcessStationGetStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+ global ProcessStationGetStatus_Response
+ if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+ return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Initialize process station machine. This is not the prober init it is a fast
+ program initialization. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 2400000
+ Example:ProcessStationInit
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Finishes a process station process. This resets some internal test information
+ for the probe station. Some data is only reset in case this command is sent
+ after the last wafer in the job was tested. Only applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 7500000
+ Example:ProcessStationFinish
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Command moves the chuck of the probe station to the secondary load position and
+ if available also checks the table level sensor. Only applies to fully auto
+ systems.
+ API Status: internal
+ Command Timeout: 120000
+ Example:ProcessStationPrepareForLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Moves the chuck out of the load position and checks if a wafer is placed. Only
+ applies to fully auto systems.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should do whatever is necessary to prepare the current wafer for
+ unload. Typically this includes things such as moving lift pins and opening
+ doors.
+ API Status: internal
+ Command Timeout: 1000000
+ Example:ProcessStationPrepareForUnLoad
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The module should so whatever is necessary after a wafer is unloaded. This may
+ for example include closing doors.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationUnLoadComplete
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject:int="", ProjectFileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ The recipe is a zipped archive that includes all project data. This command
+ tells the device to load the recipe.
+ API Status: internal
+ Args:
+ ForceReOpenProject:int = 0
+ ProjectFileName:str = ""
+ Command Timeout: 60000
+ Example:ProcessStationLoadRecipe 1 SampleProject.spp
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Requests that the device verify that the recipe given can be executed on the
+ device. It should check that the recipe is correctly formed and conforms to the
+ hardware of the device. It should not check for transient things such as whether
+ there is sufficient media or facilities available. those kinds of checks should
+ be done in PrepareForProcess
+ API Status: internal
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 60000
+ Example:ProcessStationVerifyRecipe SampleProject.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+ global ProcessStationVerifyRecipe_Response
+ if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+ return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob:int="", TotalWafersInJob:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells VeloxPro to start the current recipe. The station will switch to error if
+ an error occurs. If VeloxPro recipe execution is currently paused, this command
+ tells the system to continue execution.
+ API Status: internal
+ Args:
+ CurrentWaferInJob:int = -1
+ TotalWafersInJob:int = -1
+ Command Timeout: 25000
+ Example:ProcessStationStartRecipe 1
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the device to stop the current recipe. The station will switch to error if
+ an error occurs.
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationStopRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Tells the module to do whatever is necessary to recover from an error condition.
+ API Status: internal
+ Command Timeout: 60000
+ Example:ProcessStationRecoverError
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get substrate information from process station controller application.
+ API Status: internal
+ Returns:
+ Result:str
+ PercentDone:Decimal
+ AllowSkipWafer:int
+ TestInformation:str
+ Command Timeout: 25000
+ Example:ProcessStationGetWaferResult
+ """
+ rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+ global ProcessStationGetWaferResult_Response
+ if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+ return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+ """
+ Returns information about the wafer that is currently on the probe station. It
+ will return an error when there is no wafer currently on the chuck.
+ API Status: published
+ Returns:
+ Size:int
+ Angle:Decimal
+ ID:str
+ LotID:str
+ ProductID:str
+ Command Timeout: 25000
+ Example:QueryWaferInfo
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+ global QueryWaferInfo_Response
+ if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+ return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Sets the process station to PAUSE mode
+ API Status: internal
+ Command Timeout: 25000
+ Example:ProcessStationPauseRecipe
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+ """
+ Retrieves the current status of the prober. If probing status is AtFirstDie the
+ tester can take control.
+ API Status: published
+ Returns:
+ Status:str
+ Command Timeout: 25000
+ Example:GetProbingStatus
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+ """
+ Tells the prober to proceed the recipe when current status is AtFirstDie.
+ API Status: published
+ Command Timeout: 25000
+ Example:ProceedProbing
+ """
+ MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette:int=""):
+ """
+ Provides all available wafer information. It returns a set of data for each
+ wafer in either cassette. The data contains the cassette and the slot number
+ where the wafer is located, the status of the wafer, and identification
+ information.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 25000
+ Example:GetCassetteStatus 0
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module:str="", Slot:int=""):
+ """
+ Queries the wafer ID of a given module and slot.
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryWaferID Cassette1 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module:str="", Slot:int="", ID:str=""):
+ """
+ Overrides the wafer ID of the given module and slot. If the wafer id is empty
+ and the module is a Loadport, the id will be read by the idreader if possible.
+ This process behaves as follows: - the current wafer id is reset - if the read-
+ wafer-process would be delayed (e.g. there is already a wafer on the idreader)
+ the process will be aborted and an error will be returned - if the id-
+ reading fails, the process behaves like a normal inventory triggered by the UI:
+ skip (returns success), abort (returns error) or "ask user". It is
+ recomended to use either skip or abort for remote id reading. If the
+ module is a Loadport and the slot is set to -1, a regular inventory will be
+ triggered. This behaves similar to an inventory triggered by the UI: The ID
+ won't be reset and already scanned wafers won't be reset. Setting an ID
+ explicitly with slot -1 is an error: - Okay, read id of wafer in slot 3 even if
+ it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+ to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+ UpdateWaferID Cassette1 -1 - Error: UpdateWaferID Cassette1 -1 XYZ123
+ API Status: published
+ Args:
+ Module:str = "Robot"
+ Slot:int = 0
+ ID:str = ""
+ Command Timeout: 1500000
+ Example:UpdateWaferID Cassette1 1 Wafer01
+ """
+ MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName:str=""):
+ """
+ Queries whether the given project/flow name is a valid project/flow at the probe
+ station. Using file and folder names without white spaces is recommended. For
+ folders and files whith white spaces use quotation marks for the path. Example
+ for using white spaces: ConfirmRecipe
+ "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+ API Status: published
+ Args:
+ ProjectFileName:str = ""
+ Returns:
+ Verified:int
+ ErrorDescription:str
+ Command Timeout: 25000
+ Example:ConfirmRecipe C:/Temp/Test.spp
+ """
+ rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+ global ConfirmRecipe_Response
+ if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+ return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName:str="", WaferIDs:str=""):
+ """
+ Creates and starts a new job by specifying the flow/spp file and the wafers to
+ be included in the job.
+ API Status: published
+ Args:
+ RecipeName:str = ""
+ WaferIDs:str = ""
+ Returns:
+ JobID:str
+ Command Timeout: 25000
+ Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+ """
+ rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID:str=""):
+ """
+ Get job information for a specific job ID including the flow file and the list
+ of wafers.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ RecipeName:str
+ WaferIDs:str
+ Command Timeout: 25000
+ Example:GetJobParams 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+ global GetJobParams_Response
+ if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+ return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID:str=""):
+ """
+ Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+ an error string is returned.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Returns:
+ Status:str
+ JobStatusInfo:str
+ Command Timeout: 25000
+ Example:JobStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+ global JobStatus_Response
+ if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+ return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID:str="", Unload:int=""):
+ """
+ Aborts the job given by the job ID. The status of the job will be set to
+ "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+ or not.
+ API Status: published
+ Args:
+ JobID:str = ""
+ Unload:int = 0
+ Command Timeout: 25000
+ Example:AbortJob 2 1
+ """
+ MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Closes the VeloxPro application.
+ API Status: internal
+ Args:
+ NoUserPrompt:int = 0
+ Command Timeout: 25000
+ Example:ProcessStationCloseApplication
+ """
+ MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+ """
+ Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+ free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+ API Status: published
+ Command Timeout: 600000
+ Example:UnloadWafer
+ """
+ MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType:str=""):
+ """
+ Returns a string for the relevant JobIDs.
+ API Status: published
+ Args:
+ JobType:str = "Probing"
+ Returns:
+ GetJobList:str
+ Command Timeout: 25000
+ Example:GetJobList
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob:str=""):
+ """
+ Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+ determines how the job continues.
+ API Status: published
+ Args:
+ ProceedJob:str = "AbortJob"
+ Command Timeout: 25000
+ Example:ProceedJob AbortJob
+ """
+ MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette:int=""):
+ """
+ Returns the ID of a cassette that is placed on the load port. The loadport and
+ the cassette must support RFID reading (additional hardware needed).
+ API Status: published
+ Args:
+ Cassette:int = 1
+ Returns:
+ ID:str
+ Command Timeout: 25000
+ Example:QueryCassetteID 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId:int="", DockUndock:int=""):
+ """
+ Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+ return an error if no cassette is placed: the LoadPort is not ready/available or
+ the docking failed. The command will do the docking/undocking and return when
+ this is done.
+ API Status: published
+ Args:
+ LoadPortId:int = 0
+ DockUndock:int = 0
+ Command Timeout: 60000
+ Example:DockCassette 1 1
+ """
+ MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID:int="", SlotID:int="", AlignmentAngle:Decimal=""):
+ """
+ Load a wafer from a given loadport onto the prober. If no slot id is defined,
+ the first available wafer with the lowest slot id will be loaded. If no loadport
+ is defined, it will try to use the first loadport. If there is no suitable
+ wafer, it will try the second. Returns an error if the loading process fails or
+ no suitable wafer is found. To define an alignment angle and still use the
+ "autoselect" behaviour, use -1 for loadport and slot.
+ API Status: published
+ Args:
+ LoadportID:int = -1
+ SlotID:int = -1
+ AlignmentAngle:Decimal = 0
+ Command Timeout: 600000
+ Example:LoadWafer 1 1
+ """
+ MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette:int=""):
+ """
+ Updates the cassette status with a simple scan.
+ API Status: published
+ Args:
+ Cassette:int = 0
+ Returns:
+ CassetteStatus:str
+ Command Timeout: 1200000
+ Example:UpdateCassetteStatus 1
+ """
+ rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation:str="", SourceSlot:int="", DestinationLocation:str="", DestinationSlot:int=""):
+ """
+ Transport a wafer from one location to another. This command behaves like the
+ wafer-transport inside the LoaderModule. The Slot must always be set.
+ API Status: published
+ Args:
+ SourceLocation:str = "Cassette1"
+ SourceSlot:int = 1
+ DestinationLocation:str = "Cassette1"
+ DestinationSlot:int = 1
+ Command Timeout: 600000
+ Example:TransportWafer Cassette1 1 PreAligner 1
+ """
+ MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module:str="", ProcessParam:str=""):
+ """
+ "Process" a wafer on a given location. What is done depends on the current
+ station: - IDReader: read ID - PreAligner: align wafer (alignment angle
+ mandatory) - Prober: Perform current recipe
+ API Status: published
+ Args:
+ Module:str = "Cassette1"
+ ProcessParam:str = ""
+ Command Timeout: 100000
+ Example:ProcessWafer PreAligner 90.0
+ """
+ MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Returns the current position of the IDReader
+ API Status: internal
+ Returns:
+ IDReaderPos:str
+ Command Timeout: 2000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the current position of the IDReader
+ API Status: internal
+ Args:
+ IDReaderPos:str = "Bottom"
+ Command Timeout: 10000
+ """
+ MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process:str=""):
+ """
+ CryoCommand controls automatic cooling and warm up.
+ API Status: published
+ Args:
+ Process:str = "CD"
+ Command Timeout: 60000
+ Example:CryoCommand CD
+ """
+ MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage:str=""):
+ """
+ Reads the current temperature from sensor chuck or shield.
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Returns:
+ Temp:Decimal
+ Command Timeout: 10000
+ Example:CryoReadTemperature C
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+ return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage:str="", Temp:Decimal=""):
+ """
+ Sets temperature value for TIC chuck or shield. (Only available in process state
+ 'Idle' or 'Cold'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Temp:Decimal = 320
+ Command Timeout: 10000
+ Example:CryoSetTemperature C 70.5
+ """
+ MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage:str=""):
+ """
+ Enables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStartRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage:str=""):
+ """
+ Disables refill. (Only available in process state 'Idle'.)
+ API Status: published
+ Args:
+ Stage:str = "C"
+ Command Timeout: 10000
+ Example:CryoStopRefill C
+ """
+ MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+ """
+ Reads current state.
+ API Status: published
+ Returns:
+ State:str
+ Command Timeout: 10000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+ """
+ Moves the black body to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition:int=""):
+ """
+ Moves the black body to working position.
+ API Status: published
+ Args:
+ NbrPosition:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveBBWork 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position:str="", Shutter:int=""):
+ """
+ Moves one of the two shutters.
+ API Status: published
+ Args:
+ Position:str = "C"
+ Shutter:int = 1
+ Command Timeout: 60000
+ Example:CryoMoveShutter F 1
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+ """
+ Moves the microscope to working position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+ """
+ Moves the microscope to parking position.
+ API Status: published
+ Command Timeout: 60000
+ """
+ MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+ """
+ Reads the current pressure of the vacuum chamber.
+ API Status: published
+ Returns:
+ Pressure:Decimal
+ Command Timeout: 60000
+ """
+ rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+ return Decimal(rsp[0])
+
+def MoveZCombined(Height:Decimal="", Percent:Decimal="", Async:int=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Move both Chuck and Scope to a new absolute z-Height. The position must be
+ within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+ maximum velocity for now
+ API Status: internal
+ Args:
+ Height:Decimal = 0
+ Percent:Decimal = 0
+ Async:int = 0
+ Command Timeout: 15000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+ """
+ Get the state of the software stop.
+ API Status: published
+ Returns:
+ StopState:int
+ Command Timeout: 1000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+ return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status:str="", Message:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Used to set the system either in off, on, error or locked state. For lock, a
+ key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+ SetStatus without message means enable/ recover from error, with message it
+ means unlock. If the system wasn't enabled or in error state before an unlock,
+ it will remain in this state after the unlock.
+ API Status: internal
+ Args:
+ Status:str = "Off"
+ Message:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+ """
+ Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+ should be the same as the currently active ScopeSilo
+ API Status: published
+ Returns:
+ ScopeWorkingStage:int
+ Command Timeout: 5000
+ Example:GetScopeWorkingStage
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+ return int(rsp[0])
+
+def SetPerformanceMode(Mode:str=""):
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Set the performance mode in use by remote command. If this feature is not
+ supported and the mode is anything but Standard, an error is returned.
+ API Status: internal
+ Args:
+ Mode:str = "Standard"
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage:int=""):
+ """
+ Move to the target working stage
+ API Status: published
+ Args:
+ ScopeWorkingStage:int = -1
+ Command Timeout: 30000
+ Example:SetScopeWorkingStage 1
+ """
+ MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the currently configured performance mode. If this feature is not supported
+ on a station, Standard will be returned
+ API Status: internal
+ Returns:
+ Mode:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+ return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+ """
+ ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+ Get the current status of the combined-z-move-system
+ API Status: internal
+ Returns:
+ Status:str
+ PlatenSafe:int
+ Height:Decimal
+ HeightMax:Decimal
+ HeightRelative:Decimal
+ SafeHeight:Decimal
+ Message:str
+ Command Timeout: 5000
+ """
+ rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+ global MoveZCombinedGetStatus_Response
+ if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+ return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable:int="", Path:str=""):
+ """
+ Load a previously saved Scope-Fence-configuration or remove the current
+ configuration
+ API Status: published
+ Args:
+ Enable:int = 0
+ Path:str = ""
+ Command Timeout: 5000
+ """
+ MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState:int=""):
+ """
+ Set the state of the software stop.
+ API Status: published
+ Args:
+ StopState:int = 0
+ Command Timeout: 1000
+ """
+ MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
diff --git a/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py b/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eb3e3f0872d5edf3bcbafc9b910822342739310
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py
@@ -0,0 +1,186 @@
+"""
+Velox Message Server Interface
+To simplify calls from the SCI commands, many of the class methods are
+defined as static. Some class variables are required to support a
+connection to the Message Server, but the individual SCI commands
+do not maintain a reference to the MessageServer object. Several
+class global variables are used to maintain state.
+Registration with the Message Server is handled in the __init__.
+"""
+import re
+import socket
+import sys
+from collections import namedtuple
+from os.path import basename
+
+REGISTRATION_MESSAGE_TEMPLATE = "FCN=1:RegisterProberApp:{0} {0} 0\n"
+GET_ALL_COMMANDS_MESSAGE = "FCN=1:GetCommands:\n"
+
+class SciException(Exception):
+ """ Contains fields for:
+ code : The Error Number as a string
+ description : The error description
+ __str__, __repr__ : A formatted description of the exception """
+ def __init__(self, cmd, code, description):
+ self.command = cmd
+ self.code = str(code)
+ self.description = description
+
+ def __repr__(self):
+ return 'Error # {0} "{1}"'.format(self.code, self.description)
+
+ def __str__(self):
+ return 'Error # {0} "{1}"'.format(self.code, self.description)
+
+
+class MessageServerInterface(object):
+
+ def __init__(self, ipaddr = 'localhost', targetSocket = 1412):
+ """ Initialize a socket and register with the velox message server.
+ Uses the python script name as the application name to register.
+ """
+ global mySocket, myBytesReceived, myResponse, myCurrentCommand
+
+ try:
+ appName = basename(sys.argv[0]) # get the script name being executed
+ appName = appName.replace(' ', '_') # make sure there are no spaces in the name
+ registrationMessage = REGISTRATION_MESSAGE_TEMPLATE.format(appName)
+
+ myCurrentCommand = 1
+ mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ mySocket.connect((ipaddr, targetSocket))
+
+ #register with message server
+ mySocket.send(registrationMessage.encode())
+ myBytesReceived = 0
+ myResponse = mySocket.recv(200)
+ except ConnectionRefusedError:
+ errormessage = ('Error: The connection to the Velox Message Server was refused.'
+ ' It probably is not running on IP ['
+ + str(ipaddr) + '] on Socket [' + str(targetSocket) + '].'
+ ' Start Velox or examine IP Address and Socket parameters.')
+
+ raise Exception(errormessage)
+ pass
+
+ def __enter__(self):
+ return self
+ pass
+
+ def __exit__(self, type, value, traceback):
+ """ Close the socket connected to the message server """
+ global mySocket
+ mySocket.close()
+ pass
+
+ def _getcommands(self):
+ ''' Return a list of all commands known to the Velox Message Server '''
+ global mySocket, myBytesReceived, myResponse
+ mySocket.send(GET_ALL_COMMANDS_MESSAGE.encode())
+ myBytesReceived = 0
+ myResponse = mySocket.recv(60000)
+ message = str(myResponse.decode('utf-8'))
+ # parse the list
+ commands = message.split(':')[2].split(';')
+
+ # split the list into parsed tuples
+ SimpleCommandTuple = namedtuple('SimpleCommandTuple', 'section, name, number, timeout')
+ scilist = []
+ for x in commands:
+ parts = x.split(' ')
+ scilist.append(SimpleCommandTuple(parts[0], parts[1], int(parts[2]),int(parts[3])))
+ return scilist
+ pass
+
+ @staticmethod
+ def __parseReturnValues(valueString):
+ """ The values come back from the SCI command as a string separated by spaces,
+ but with embedded strings as well. Separate the values. """
+
+ results = [] # the values parsed to be returned
+ remainingValues = valueString # holds all values still to be parsed
+ while remainingValues:
+ if remainingValues.startswith('"'): # we have a string
+ parts = remainingValues.split('"', 2)
+ parts.pop(0)
+ results.append(parts.pop(0).strip()) # get the string
+ parts.pop(0)
+ else: # get value separated by a space
+ parts = remainingValues.split(' ', 1)
+ results.append(parts.pop(0))
+
+ if len(parts) > 0:
+ remainingValues = parts[0].strip() # get the rest of the values
+ else:
+ remainingValues = None
+
+ return results
+ pass
+
+ @staticmethod
+ def __convertReturnValues(responses):
+ """ The responses are all strings. Use the hints from the SCI Command definition
+ to convert them to the proper types """
+ pass
+
+ @staticmethod
+ def __parseSciCommandResponse(response):
+ """ The response from Message Server has the form
+ Rsp=<ID>:<Return Code>:<Return Value>
+ Split the response on the : character, then split up the return values """
+
+ message = str(response.decode('utf-8')[:-2])
+
+ # we may have 0 or more values
+ partsCount = message.count(':')+1
+ if partsCount == 2:
+ command, code = re.split(":", message)
+ values = '';
+ else:
+ command, code, values = re.split(":", message)
+ values = values.strip()
+
+ if message.startswith('Rsp='):
+ values = MessageServerInterface.__parseReturnValues(values)
+
+ commandNumber = command.split('=')[1]
+ return int(commandNumber), int(code), values
+
+ @staticmethod
+ def __sendSynchronousCommand(commandName, message=''):
+ global mySocket, myBytesReceived, myResponse, myCurrentCommand
+
+ try:
+ myCurrentCommand += 1 # increment the commend number
+ if myCurrentCommand == 0 or myCurrentCommand > 999:
+ myCurrentCommand = 1
+ messageToSend = 'Cmd={}:{}:{}\n'.format(myCurrentCommand,commandName,message)
+ mySocket.send(messageToSend.encode())
+ myBytesReceived = 0
+ myResponse = mySocket.recv(500)
+
+ except Exception as e:
+ raise Exception('Unable to communicate with Velox Message Server. Start Velox. %s', e)
+
+ cmd, code, values = MessageServerInterface.__parseSciCommandResponse(myResponse)
+
+ # if the response code is not 0, raise an exception
+ if code:
+ parameters = ' '.join(values)
+ raise SciException(cmd, code, parameters)
+
+ return values
+ pass
+
+ @staticmethod
+ def sendSciCommand(commandName, *args, **kwargs):
+ """ If the parameter rparams is passed, it is the full command parameter string and should be used.
+ Otherwise, join the other arguments into a string separated by spaces and send that.
+ The rparams is used for legacy scripts converted from Pascal or Basic or other cases
+ where you want to send the command parameters as a single string. """
+
+ if 'rparams' in kwargs: # use the raw parameter string if provided
+ commandParameters = kwargs['rparams']
+ else: # use the positional arguments and build the parameter string
+ commandParameters = ' '.join(str(x) for x in args)
+ return MessageServerInterface.__sendSynchronousCommand(commandName, commandParameters)
diff --git a/src/FlexSensor/Prober/view/ProberControlWindow.py b/src/FlexSensor/Prober/view/ProberControlWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bb990de5bd0b25cafff5f0994a6e6196b01218d
--- /dev/null
+++ b/src/FlexSensor/Prober/view/ProberControlWindow.py
@@ -0,0 +1,66 @@
+import logging
+import sys
+
+from PySide6.QtGui import QWindow
+from PySide6.QtWidgets import QGridLayout, QApplication, QMainWindow, QWidget, QGroupBox, QVBoxLayout
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Prober.controller.MapFileParser import MapFileParser
+from Prober.controller.ProberController import ProberController
+from Prober.model.ProberModel import ProberModel
+from Prober.view.widgets.DieGridWidget import DieGridWidget
+from Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
+from Prober.view.widgets.ProberStatusWidget import ProberStatusWidget
+from generics.logger import setup_logging
+
+
+class ProberControlWindow(QMainWindow):
+
+ def __init__(self, model: ProberModel, controller: ProberController):
+ super().__init__()
+ self.controller = controller
+ self.model = model
+
+ #self.parsed_map = MapFileParser(self.controller.wafer_map)
+
+ # Add a GridLayout to the main window
+ self._widget = QWidget()
+ self._grid_layout = QGridLayout()
+ # Add the DieGridWidget to the main window
+ # Add the prober status widget to the a group box
+ groupbox_status_widget = QGroupBox("Prober Status")
+ groupbox_status_widget_layout = QVBoxLayout()
+ groupbox_status_widget_layout.addWidget(ProberStatusWidget(self.model))
+ groupbox_status_widget.setLayout(groupbox_status_widget_layout)
+
+
+ groupbox_position_widget = QGroupBox("Prober Status")
+ groupbox_position_widget_layout = QVBoxLayout()
+ groupbox_position_widget_layout.addWidget(ProberPositionWidget(self.model))
+ groupbox_position_widget.setLayout(groupbox_position_widget_layout)
+
+ self._grid_layout.addWidget(groupbox_status_widget, 0, 0, 1, 1)
+ self._grid_layout.addWidget(groupbox_position_widget, 1, 0, 1, 1)
+ self._grid_layout.addWidget(DieGridWidget(self.model), 0, 1, 2, 1)
+ # set the layout of the main window
+ self._widget.setLayout(self._grid_layout)
+ self.setCentralWidget(self._widget)
+
+
+
+
+if __name__ == "__main__":
+ setup_logging()
+ logging.warning("ProberControlWindow.py is not meant to be run as a script.")
+
+ app = QApplication()
+
+ vaut_config = VAutomatorConfig.load_config("../configs/init_config.yaml")
+
+ prober_model = ProberModel()
+ prober_controller = ProberController(prober_model, vaut_config)
+ main_window = ProberControlWindow(prober_controller, prober_model)
+ # test_win = StructureSelector()
+
+ main_window.show()
+ sys.exit(app.exec())
diff --git a/src/FlexSensor/Prober/view/__init__.py b/src/FlexSensor/Prober/view/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/Prober/view/widgets/DieGridWidget.py b/src/FlexSensor/Prober/view/widgets/DieGridWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1e365e4dbebf20a048955440605885261ef55c4
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/DieGridWidget.py
@@ -0,0 +1,225 @@
+import pandas as pd
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QColor, QPainter, QPen
+from PySide6.QtWidgets import QWidget, QGridLayout, QPushButton, QApplication, QLabel
+
+from Prober.controller.MapFileParser import MapFileParser
+from Prober.model.ProberModel import ProberModel
+
+
+class FlatButton(QPushButton):
+ def __init__(self, text, top_left="", top_right="", bottom_left="", bottom_right="", parent=None):
+ super().__init__(parent, text)
+
+ # Set flat appearance
+
+ self.setFlat(True)
+
+ self.color_default = QColor(192, 192, 192)#QColor(0, 58, 98) #
+ self.color_die_selected = QColor(49, 61, 102)
+ self.color_probe_active = QColor(62, 120, 52)
+ self.color_disabled = QColor(0, 0, 0)
+ self.border_color = self.color_default
+
+ self.setStyleSheet(self.get_stylesheet(self.color_default))
+
+ # Set quadratic aspect ratio
+ self.setMaximumSize(50, 50)
+ self.setMinimumSize(50, 50)
+ self.setFixedSize(50, 50)
+
+ self.setContentsMargins(0, 0, 0, 0) # Set margins to zero
+ # Create label widgets
+ #self.top_left_label = QLabel(top_left, parent=self)
+ self.top_right_label = QLabel(top_right, parent=self)
+ self.bottom_left_label = QLabel(bottom_left, parent=self)
+ self.bottom_right_label = QLabel(bottom_right, parent=self)
+
+ # Set label positions
+ #self.top_left_label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
+ self.top_right_label.setAlignment(Qt.AlignTop | Qt.AlignRight)
+ self.bottom_left_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft)
+ self.bottom_right_label.setAlignment(Qt.AlignBottom | Qt.AlignRight)
+
+ # Border colo
+
+
+ # Border flag
+ self.draw_border = False
+ # Border width
+ self.border_width = 3
+
+ def get_stylesheet(self, qcolor):
+ return f"background-color: rgb({qcolor.red()}, {qcolor.green()}, {qcolor.blue()});"
+ def setTopLeftLabel(self, text):
+ self.top_left_label.setText(text)
+
+ def setTopRightLabel(self, text):
+ self.top_right_label.setText(text)
+
+ def setBottomLeftLabel(self, text):
+ self.bottom_left_label.setText(text)
+
+ def setBottomRightLabel(self, text):
+ self.bottom_right_label.setText(text)
+
+ def setEnabled(self, arg__1: bool) -> None:
+ super().setEnabled(arg__1)
+ if not arg__1:
+ self.setStyleSheet(self.get_stylesheet(self.color_disabled))
+ self.border_color = self.color_disabled # Black
+ self.update()
+
+ def set_die_selected(self, checked: bool) -> None:
+ if not self.isEnabled():
+ return
+
+ if checked:
+ self.setStyleSheet(self.get_stylesheet(self.color_die_selected))
+ self.border_color = self.color_die_selected
+ else:
+ self.setStyleSheet(self.get_stylesheet(self.color_default))
+ self.border_color = self.color_default
+ self.update()
+
+ def set_probe_active(self, active: bool) -> None:
+ if not self.isEnabled():
+ return
+
+ if active:
+ #self.setStyleSheet(self.get_stylesheet(self.color_default))
+ self.border_color = self.color_probe_active
+ else:
+ #self.setStyleSheet(self.get_stylesheet(self.color_default))
+ self.border_color = self.color_default
+ self.update()
+
+ def paintEvent(self, event):
+ super().paintEvent(event)
+
+ #if self.draw_border:
+ painter = QPainter(self)
+ pen = QPen(self.border_color, self.border_width)
+ painter.setPen(pen)
+ painter.setBrush(Qt.NoBrush)
+ painter.drawRect(
+ self.border_width // 2,
+ self.border_width // 2,
+ self.width() - self.border_width,
+ self.height() - self.border_width
+ )
+
+ def resizeEvent(self, event):
+ super().resizeEvent(event)
+
+ # Calculate label sizes based on button size
+ button_size = self.size()
+ border_offset = self.border_width // 2
+ label_width = (button_size.width() - self.border_width)
+ label_height = (button_size.height()) // 2
+
+ # Set label sizes and positions
+
+
+ self.top_right_label.setGeometry(self.border_width, self.border_width,
+ label_width-self.border_width, label_height)
+
+ self.bottom_left_label.setGeometry(self.border_width, label_height - self.border_width,
+ label_width//2, label_height)
+
+ self.bottom_right_label.setGeometry(label_width//2, label_height - self.border_width,
+ label_width//2+1, label_height)
+
+
+
+class DieGridWidget(QWidget):
+ def __init__(self, model: ProberModel):
+ super(DieGridWidget, self).__init__()
+ self._model = model
+
+ parsed_map = MapFileParser(str(self._model.wafer_map))
+ self.setWindowTitle("Die Grid Widget")
+ self._dies = {}
+
+ self.grid_layout = QGridLayout()
+ self.grid_layout.setSpacing(0)
+ self.grid_layout.setHorizontalSpacing(0)
+ self.grid_layout.setVerticalSpacing(0)
+ #self.grid_layout.setContentsMargins(0, 0, 0, 0) # Set margins to zero
+
+ self.setLayout(self.grid_layout)
+
+ self._die = parsed_map.result['Die']
+
+ self._prof_dies = parsed_map.result['ProfDies']
+ self.create_die_grid()
+ self.setFixedSize(9*60, 9*60)
+
+
+ self._model.signals.die_changed.connect(self.update_die_grid)
+
+ self.update_die_grid(self._model.die)
+
+ def create_die_grid(self):
+ table = pd.DataFrame([[int(die), *self._die[die].split(",")] for die in self._die],
+ columns=['die_number', 'col', 'row', 'status'])
+ table['col'] = table['col'].astype(int)
+ table['row'] = table['row'].astype(int)
+ table['status'] = table['status'].astype(str)
+
+ table['col_os'] = table.apply([lambda row: row['col'] - table['col'].min()], axis=1)
+ table['row_os'] = table.apply([lambda row: row['row'] - table['row'].min()], axis=1)
+
+
+ #print(table)
+ # pd.DataFrame([die.split(",").strip for die in die_info], columns=['col', 'row', 'status'])
+ for entry in self._prof_dies:
+ col, row, value = self._prof_dies[entry].split(",")
+ df = table.loc[(table['col'] == int(col)) & (table['row'] == int(row))]
+ if df.empty:
+ continue
+ else:
+ table.loc[(table['col'] == int(col)) & (table['row'] == int(row)), 'prof_die_number'] = entry
+
+
+ for index, die in table.iterrows():
+ button = FlatButton("1", "2", f"{die['col']}, {die['row']}", str(die['die_number']), str(die['status']))#,
+ if die['status'] == "X":
+ button.setEnabled(False)
+ elif die['status'] == "V":
+ button.set_die_selected(False)
+ elif die['status'] == "P":
+ button.set_die_selected(True)
+ #button.setText(f"{die['col']}, {die['row']} - {die['die_number']}")
+ self._dies[f"{die['row']}, {die['col']}"] = button
+
+ button.clicked.connect(self.on_button_clicked)
+
+ self.grid_layout.addWidget(button, die['col_os'], die['row_os'])
+
+ #print(table)
+
+ def on_button_clicked(self):
+ button: FlatButton = self.sender()
+ button.set_probe_active(True)
+
+ def update_die_grid(self, die):
+ for die in self._dies:
+ self._dies[die].set_probe_active(False)
+
+ die_x = self._model.die_row
+ die_y = self._model.die_col
+ print(f"Die {die}: {die_x}, {die_y} was probed")
+ #print(self._dies)
+ self._dies[f"{die_x}, {die_y}"].set_probe_active(True)
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ parsed_map = MapFileParser("../Wafermapary1_48dies.map")
+
+ widget = DieGridWidget(parsed_map)
+ widget.show()
+
+ app.exec_()
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py b/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..9db1dfde64d455f62e7574d9407525a5099f26e9
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py
@@ -0,0 +1,105 @@
+from PySide6.QtWidgets import QWidget, QGroupBox, QGridLayout, QLabel, QProgressBar
+
+from Prober.model.ProberModel import ProberModel
+
+
+class ProberPositionWidget(QWidget):
+
+ def __init__(self, model: ProberModel, chuck_position="Vertical"):
+ super().__init__()
+ self.model = model
+ self.layout = QGridLayout()
+ self.chuck_position = chuck_position
+
+ self.lbl_chuck_x = QLabel()
+ self.lbl_chuck_y = QLabel()
+ self.lbl_chuck_z = QLabel()
+
+ self.lbl_die_no = QLabel()
+ self.lbl_structure = QLabel()
+ self.lbl_die_col = QLabel()
+ self.lbl_die_row = QLabel()
+
+ self.lbl_die_no.setText(str(self.model.die))
+ self.lbl_structure.setText("<b>Stopped</b>")
+ self.lbl_die_col.setText(str(self.model.die_col))
+ self.lbl_die_row.setText(str(self.model.die_row))
+ self.lbl_chuck_x.setText(str(self.model.chuck_x))
+ self.lbl_chuck_y.setText(str(self.model.chuck_y))
+ self.lbl_chuck_z.setText(str(self.model.chuck_z))
+
+ # self.progress = QProgressBar(self)
+ # self.progress.setStyleSheet(
+ # "#GreenProgressBar { min-height: 12px; max-height: 12px; border-radius: 6px;}")
+ # self.layout.addWidget(self.progress, 2, 0, 1, 4)
+ # self.progress.setFixedHeight(self.progress.sizeHint().height() / 2)
+
+ self._init_ui_wafer_position()
+ self._init_ui_chuck_position()
+ self.setLayout(self.layout)
+
+ self.model.signals.chuck_x_changed.connect(self._on_chuck_x_changed)
+ self.model.signals.chuck_y_changed.connect(self._on_chuck_y_changed)
+ self.model.signals.chuck_z_changed.connect(self._on_chuck_z_changed)
+ self.model.signals.die_changed.connect(self._on_die_no_changed)
+ #self.model.signals.st.connect(self._on_structure_changed)
+ self.model.signals.curr_die_col_changed.connect(self._on_die_col_changed)
+ self.model.signals.curr_die_row_changed.connect(self._on_die_row_changed)
+
+
+ def _init_ui_wafer_position(self):
+ self.layout.addWidget(QLabel("Die No:"), 0, 0)
+ self.layout.addWidget(self.lbl_die_no, 0, 1)
+
+ self.layout.addWidget(QLabel("Structure"), 0, 2)
+ self.layout.addWidget(self.lbl_structure, 0, 3)
+
+ self.layout.addWidget(QLabel("Die col:"), 1, 0)
+ self.layout.addWidget(self.lbl_die_col, 1, 1)
+
+ self.layout.addWidget(QLabel("Die row:"), 1, 2)
+ self.layout.addWidget(self.lbl_die_row, 1, 3)
+
+ def _init_ui_chuck_position(self):
+ if self.chuck_position == "Vertical":
+ self.layout.addWidget(QLabel("X"), 2, 0)
+ self.layout.addWidget(self.lbl_chuck_x, 2, 1)
+
+ self.layout.addWidget(QLabel("Y"), 3, 0)
+ self.layout.addWidget(self.lbl_chuck_y, 3, 1)
+
+ self.layout.addWidget(QLabel("Z"), 4, 0)
+ self.layout.addWidget(self.lbl_chuck_z, 4, 1)
+
+ elif self.chuck_position == "Horizontal":
+ self.layout.addWidget(QLabel("X"), 2, 0)
+ self.layout.addWidget(self.lbl_chuck_x, 2, 1)
+
+ self.layout.addWidget(QLabel("Y"), 2, 2)
+ self.layout.addWidget(self.lbl_chuck_y, 2, 3)
+
+ self.layout.addWidget(QLabel("Z"), 2, 4)
+ self.layout.addWidget(self.lbl_chuck_z, 2, 5)
+
+
+ def _on_chuck_x_changed(self, value: int):
+ self.lbl_chuck_x.setText(str(value))
+
+ def _on_chuck_y_changed(self, value: int):
+ self.lbl_chuck_y.setText(str(value))
+
+ def _on_chuck_z_changed(self, value: int):
+ self.lbl_chuck_z.setText(str(value))
+
+ def _on_die_no_changed(self, value: int):
+ self.lbl_die_no.setText(str(value))
+
+ def _on_structure_changed(self, value: int):
+ self.lbl_structure.setText(str(value))
+
+ def _on_die_col_changed(self, value: int):
+ self.lbl_die_col.setText(str(value))
+
+ def _on_die_row_changed(self, value: int):
+ self.lbl_die_row.setText(str(value))
+
diff --git a/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py b/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e2073375bd698281f6887da38514385df74376
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py
@@ -0,0 +1,74 @@
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QWidget, QLabel, QGridLayout, QStyle, QFrame, QProgressBar, QGroupBox
+
+from Prober.model.ProberModel import ProberModel
+
+
+class ProberStatusWidget(QWidget):
+
+ def __init__(self, model: ProberModel):
+ super().__init__()
+ self.setFixedSize(300, 200)
+ self.model = model
+ self._grid_layout = QGridLayout()
+ self.prober_status = self._add_status(self._get_std_icon("SP_ComputerIcon"), "", 0)
+ self.version_status = self._add_status(self._get_std_icon("SP_MessageBoxInformation"), str(self.model.version), 1)
+ self._add_line(2)
+ self.errors = self._add_status(self._get_std_icon("SP_MessageBoxCritical"), "0", 3)
+ self.warnings = self._add_status(self._get_std_icon("SP_MessageBoxWarning"), "0", 4)
+
+ self._on_connected_changed(self.model.connected)
+
+ self.model.signals.connected_changed.connect(self._on_connected_changed)
+ self.model.signals.version_changed.connect(self._on_version_changed)
+ self.model.signals.errors_changed.connect(self._on_errors_changed)
+ self.model.signals.warnings_changed.connect(self._on_warnings_changed)
+
+
+ self.setLayout(self._grid_layout)
+
+
+ def _get_std_icon(self, icon_name) -> QIcon:
+ return self.style().standardIcon(getattr(QStyle, icon_name))
+
+ def _add_status(self, icon, text, pos=0):
+ icon_label = QLabel()
+ icon_label.setPixmap(icon.pixmap(50, 50))
+ icon_label.setAlignment(Qt.AlignCenter)
+ icon_label.setContentsMargins(0, 0, 0, 0)
+ # icon_label.setStyleSheet("background-color: rgb(192, 192, 192);")
+ icon_label.setFixedSize(24, 24)
+ icon_label.setScaledContents(True)
+
+ text_label = QLabel(text)
+ #text_label.setAlignment(Qt.AlignCenter)
+ #text_label.setContentsMargins(0, 0, 0, 0)
+ # text_label.setStyleSheet("background-color: rgb(192, 192, 192);")
+ # text_label.setFixedSize(32, 50)
+ #text_label.setScaledContents(True)
+
+ self._grid_layout.addWidget(icon_label, pos, 0)
+ self._grid_layout.addWidget(text_label, pos, 1)
+ return text_label
+
+ def _add_line(self, pos=0):
+ line = QFrame()
+ line.setFrameShape(QFrame.HLine)
+ line.setFrameShadow(QFrame.Sunken)
+ self._grid_layout.addWidget(line, pos, 0, 1, 2)
+
+ def _on_connected_changed(self, connected):
+ if connected:
+ self.prober_status.setText("Connected")
+ else:
+ self.prober_status.setText("Disconnected")
+
+ def _on_version_changed(self, version):
+ self.version_status.setText(version)
+
+ def _on_errors_changed(self, errors):
+ self.errors.setText(str(len(errors)))
+
+ def _on_warnings_changed(self, warnings):
+ self.warnings.setText(str(len(warnings)))
\ No newline at end of file
diff --git a/src/FlexSensor/__init__.py b/src/FlexSensor/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..81dab0e1c8728d9d20fda311be5ccfd69e7324e7
--- /dev/null
+++ b/src/FlexSensor/__init__.py
@@ -0,0 +1,7 @@
+import os
+import pathlib
+import sys
+
+from flexsensorpy.__version__ import __version__
+
+__all__ = []
diff --git a/src/FlexSensor/__version__.py b/src/FlexSensor/__version__.py
new file mode 100644
index 0000000000000000000000000000000000000000..36b6d4f16487f4a4b4b68a1913dedc60d22080d3
--- /dev/null
+++ b/src/FlexSensor/__version__.py
@@ -0,0 +1,2 @@
+__version__ = "6.0.0 beta"
+__changelog__ = "New UI Version and better measurement routine implemented."
\ No newline at end of file
diff --git a/src/FlexSensor/constants/Enumerate.py b/src/FlexSensor/constants/Enumerate.py
new file mode 100644
index 0000000000000000000000000000000000000000..08721dce289f2ba27e2647add2dd9e3294e5ba57
--- /dev/null
+++ b/src/FlexSensor/constants/Enumerate.py
@@ -0,0 +1,119 @@
+"""
+ DWF Python Example
+ Author: Digilent, Inc.
+ Revision: 2019-07-24
+
+ Requires:
+ Python 2.7, 3
+ Description:
+ Device detection troubleshooting.
+"""
+
+from ctypes import *
+import sys
+import time
+
+if sys.platform.startswith("win"):
+ dwf = cdll.dwf
+ dmgr = cdll.dmgr
+ ftd = windll.ftd2xx
+elif sys.platform.startswith("darwin"):
+ dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
+ dmgr = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libdmgr.dylib")
+ ftd = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libftd2xx.dylib")
+ dftd = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libdftd2xx.dylib")
+else:
+ dwf = cdll.LoadLibrary("libdwf.so")
+ dmgr = cdll.LoadLibrary("libdmgr.so")
+ ftd = cdll.LoadLibrary("libftd2xx.so")
+
+version = create_string_buffer(32)
+cDev = c_int();
+dvc = (c_char*1024)()
+pdid = c_int()
+flags = c_int()
+locid = c_int()
+type = c_int()
+
+name = create_string_buffer(64)
+sn = create_string_buffer(64)
+
+if sys.platform.startswith("darwin"):
+ print("")
+ if dftd.DFT_Init() == 0 :
+ print("DFT_INIT failed")
+ quit()
+
+ print("Digilent FTDI Enumeration library loaded")
+
+ if dftd.DFT_CreateDeviceInfoList(byref(cDev)) != 0 :
+ print("DFT_CreateDeviceInfoList failed")
+ dftd.DFT_Term()
+ quit()
+
+ print("Devices: "+str(cDev.value))
+
+ for i in range(0, cDev.value):
+ if dftd.DFT_GetDeviceInfoDetail(c_int(i), byref(flags), byref(type), byref(pdid), byref(locid), sn, name, None) != 0 :
+ print("Failed DFT_GetDeviceInfoDetail")
+ dftd.DFT_Term()
+ quit()
+ print(" "+str(i+1)+". SN:"+str(sn.value)+" '"+str(name.value)+"'"+" flags: "+hex(flags.value)+" type: "+hex(type.value)+" id: "+hex(pdid.value)+" locid: "+hex(locid.value))
+
+
+print("")
+ftd.FT_GetLibraryVersion(byref(pdid))
+print("FTDI Version: "+hex(pdid.value))
+
+if ftd.FT_CreateDeviceInfoList(byref(cDev)) != 0 :
+ print("FT_CreateDeviceInfoList failed")
+ quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+ if ftd.FT_GetDeviceInfoDetail(c_int(i), byref(flags), byref(type), byref(pdid), byref(locid), sn, name, None) != 0 :
+ print("Failed FT_GetDeviceInfoDetail")
+ print(" "+str(i+1)+". SN:"+str(sn.value)+" "+str(name.value)+""+" flags: "+hex(flags.value)+" type: "+hex(type.value)+" id: "+hex(pdid.value)+" locid: "+hex(locid.value))
+
+
+print("")
+dmgr.DmgrGetVersion(version)
+print("DMGR Version: "+str(version.value))
+
+if dmgr.DmgrEnumDevices(byref(cDev)) == 0 :
+ print("DmgrEnumDevices failed")
+ quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+ dmgr.DmgrGetDvc(c_int(i), dvc);
+
+ if dmgr.DmgrGetInfo(dvc, 3, name) == 0 : #dinfoProdName
+ print("Failed DmgrGetInfo dinfoProdName")
+ if dmgr.DmgrGetInfo(dvc, 4, byref(pdid)) == 0 : #dinfoPDID
+ print("Failed DmgrGetInfo dinfoPDID")
+ if dmgr.DmgrGetInfo(dvc, 5, sn) == 0 : #dinfoSN
+ print("Failed DmgrGetInfo dinfoSN")
+ print(" "+str(i+1)+". "+str(sn.value)+" "+str(name.value)+""+" PDID: "+hex(pdid.value))
+
+
+print("")
+dwf.FDwfGetVersion(version)
+print("DWF Version: "+str(version.value))
+
+if dwf.FDwfEnum(c_int(0), byref(cDev)) == 0 :
+ print("DmgrEnumDevices failed")
+ quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+ dwf.FDwfEnumDeviceName(c_int(i), name)
+ dwf.FDwfEnumSN(c_int(i), sn)
+ print(" "+str(i+1)+". "+str(sn.value)+" "+str(name.value)+"")
+
+dmgr.DmgrFreeDvcEnum()
+if sys.platform.startswith("darwin"):
+ dftd.DFT_Term()
\ No newline at end of file
diff --git a/src/FlexSensor/constants/FlexsensorConstants.py b/src/FlexSensor/constants/FlexsensorConstants.py
new file mode 100644
index 0000000000000000000000000000000000000000..37913cb0695cc5479cd7e98967eb5386e46743e0
--- /dev/null
+++ b/src/FlexSensor/constants/FlexsensorConstants.py
@@ -0,0 +1,3 @@
+class Probe:
+ INPUT = 0
+ OUTPUT = 1
diff --git a/src/FlexSensor/constants/__init__.py b/src/FlexSensor/constants/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/constants/css_stylesheet.py b/src/FlexSensor/constants/css_stylesheet.py
new file mode 100644
index 0000000000000000000000000000000000000000..75924a64c8211e5cfb5d822bb65471ca8092c0ae
--- /dev/null
+++ b/src/FlexSensor/constants/css_stylesheet.py
@@ -0,0 +1,44 @@
+styleData="""
+QWidget
+{
+ color: #b1b1b1;
+ background-color: #323232;
+}
+QWidget:disabled
+{
+ border-color: #404040;
+ background-color: #323232;
+}
+QProgressBar
+{
+ border: 2px solid grey;
+ border-radius: 5px;
+ text-align: center;
+}
+QProgressBar::chunk
+{
+ background-color: #d7801a;
+ width: 2.15px;
+ margin: 0.5px;
+}
+QPushButton:pressed
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
+}
+QComboBox:hover,QPushButton:hover
+{
+ border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+QPushButton
+{
+ color: #b1b1b1;
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
+ border-width: 1px;
+ border-color: #1e1e1e;
+ border-style: solid;
+ border-radius: 6;
+ padding: 3px;
+ font-size: 12px;
+ padding-left: 5px;
+ padding-right: 5px;
+}"""
\ No newline at end of file
diff --git a/src/FlexSensor/constants/dwfconstants.py b/src/FlexSensor/constants/dwfconstants.py
new file mode 100644
index 0000000000000000000000000000000000000000..b7b445e1a4ae7056f6a09354164915c5def3572b
--- /dev/null
+++ b/src/FlexSensor/constants/dwfconstants.py
@@ -0,0 +1,252 @@
+"""
+ DWFConstants (definitions file for DWF library)
+ Author: Digilent, Inc.
+ Revision: 2019-10-15
+
+ Must install:
+ Python 2.7 or 3
+"""
+
+
+from ctypes import *
+
+# device handle
+#HDWF
+hdwfNone = c_int(0)
+
+# device enumeration filters
+enumfilterAll = c_int(0)
+
+enumfilterType = c_int(0x8000000)
+enumfilterUSB = c_int(0x0000001)
+enumfilterNetwork = c_int(0x0000002)
+enumfilterAXI = c_int(0x0000004)
+enumfilterRemote = c_int(0x1000000)
+enumfilterAudio = c_int(0x2000000)
+enumfilterDemo = c_int(0x4000000)
+
+# device ID
+devidEExplorer = c_int(1)
+devidDiscovery = c_int(2)
+devidDiscovery2 = c_int(3)
+devidDDiscovery = c_int(4)
+devidADP3X50 = c_int(6)
+
+# device version
+devverEExplorerC = c_int(2)
+devverEExplorerE = c_int(4)
+devverEExplorerF = c_int(5)
+devverDiscoveryA = c_int(1)
+devverDiscoveryB = c_int(2)
+devverDiscoveryC = c_int(3)
+
+# trigger source
+trigsrcNone = c_ubyte(0)
+trigsrcPC = c_ubyte(1)
+trigsrcDetectorAnalogIn = c_ubyte(2)
+trigsrcDetectorDigitalIn = c_ubyte(3)
+trigsrcAnalogIn = c_ubyte(4)
+trigsrcDigitalIn = c_ubyte(5)
+trigsrcDigitalOut = c_ubyte(6)
+trigsrcAnalogOut1 = c_ubyte(7)
+trigsrcAnalogOut2 = c_ubyte(8)
+trigsrcAnalogOut3 = c_ubyte(9)
+trigsrcAnalogOut4 = c_ubyte(10)
+trigsrcExternal1 = c_ubyte(11)
+trigsrcExternal2 = c_ubyte(12)
+trigsrcExternal3 = c_ubyte(13)
+trigsrcExternal4 = c_ubyte(14)
+trigsrcHigh = c_ubyte(15)
+trigsrcLow = c_ubyte(16)
+trigsrcClock = c_ubyte(17)
+
+# instrument states
+DwfStateReady = c_ubyte(0)
+DwfStateConfig = c_ubyte(4)
+DwfStatePrefill = c_ubyte(5)
+DwfStateArmed = c_ubyte(1)
+DwfStateWait = c_ubyte(7)
+DwfStateTriggered = c_ubyte(3)
+DwfStateRunning = c_ubyte(3)
+DwfStateDone = c_ubyte(2)
+
+# DwfEnumConfigInfo
+DECIAnalogInChannelCount = c_int(1)
+DECIAnalogOutChannelCount = c_int(2)
+DECIAnalogIOChannelCount = c_int(3)
+DECIDigitalInChannelCount = c_int(4)
+DECIDigitalOutChannelCount = c_int(5)
+DECIDigitalIOChannelCount = c_int(6)
+DECIAnalogInBufferSize = c_int(7)
+DECIAnalogOutBufferSize = c_int(8)
+DECIDigitalInBufferSize = c_int(9)
+DECIDigitalOutBufferSize = c_int(10)
+
+# acquisition modes:
+acqmodeSingle = c_int(0)
+acqmodeScanShift = c_int(1)
+acqmodeScanScreen = c_int(2)
+acqmodeRecord = c_int(3)
+acqmodeOvers = c_int(4)
+acqmodeSingle1 = c_int(5)
+
+# analog acquisition filter:
+filterDecimate = c_int(0)
+filterAverage = c_int(1)
+filterMinMax = c_int(2)
+
+# analog in trigger mode:
+trigtypeEdge = c_int(0)
+trigtypePulse = c_int(1)
+trigtypeTransition = c_int(2)
+trigtypeWindow = c_int(3)
+
+# trigger slope:
+DwfTriggerSlopeRise = c_int(0)
+DwfTriggerSlopeFall = c_int(1)
+DwfTriggerSlopeEither = c_int(2)
+
+# trigger length condition
+triglenLess = c_int(0)
+triglenTimeout = c_int(1)
+triglenMore = c_int(2)
+
+# error codes for the functions:
+dwfercNoErc = c_int(0) # No error occurred
+dwfercUnknownError = c_int(1) # API waiting on pending API timed out
+dwfercApiLockTimeout = c_int(2) # API waiting on pending API timed out
+dwfercAlreadyOpened = c_int(3) # Device already opened
+dwfercNotSupported = c_int(4) # Device not supported
+dwfercInvalidParameter0 = c_int(16) # Invalid parameter sent in API call
+dwfercInvalidParameter1 = c_int(17) # Invalid parameter sent in API call
+dwfercInvalidParameter2 = c_int(18) # Invalid parameter sent in API call
+dwfercInvalidParameter3 = c_int(19) # Invalid parameter sent in API call
+dwfercInvalidParameter4 = c_int(20) # Invalid parameter sent in API call
+
+# analog out signal types
+funcDC = c_ubyte(0)
+funcSine = c_ubyte(1)
+funcSquare = c_ubyte(2)
+funcTriangle = c_ubyte(3)
+funcRampUp = c_ubyte(4)
+funcRampDown = c_ubyte(5)
+funcNoise = c_ubyte(6)
+funcPulse = c_ubyte(7)
+funcTrapezium= c_ubyte(8)
+funcSinePower= c_ubyte(9)
+funcCustom = c_ubyte(30)
+funcPlay = c_ubyte(31)
+
+# analog io channel node types
+analogioEnable = c_ubyte(1)
+analogioVoltage = c_ubyte(2)
+analogioCurrent = c_ubyte(3)
+analogioPower = c_ubyte(4)
+analogioTemperature = c_ubyte(5)
+analogioDmm = c_ubyte(6)
+analogioRange = c_ubyte(7)
+analogioMeasure = c_ubyte(8)
+analogioTime = c_ubyte(9)
+analogioFrequency = c_ubyte(10)
+analogioResistance = c_ubyte(11)
+
+DwfDmmResistance = c_double(1)
+DwfDmmContinuity = c_double(2)
+DwfDmmDiode = c_double(3)
+DwfDmmDCVoltage = c_double(4)
+DwfDmmACVoltage = c_double(5)
+DwfDmmDCCurrent = c_double(6)
+DwfDmmACCurrent = c_double(7)
+DwfDmmDCLowCurrent = c_double(8)
+DwfDmmACLowCurrent = c_double(9)
+DwfDmmTemperature = c_double(10)
+
+AnalogOutNodeCarrier = c_int(0)
+AnalogOutNodeFM = c_int(1)
+AnalogOutNodeAM = c_int(2)
+
+DwfAnalogOutIdleDisable = c_int(0)
+DwfAnalogOutIdleOffset = c_int(1)
+DwfAnalogOutIdleInitial = c_int(2)
+
+DwfDigitalInClockSourceInternal = c_int(0)
+DwfDigitalInClockSourceExternal = c_int(1)
+
+DwfDigitalInSampleModeSimple = c_int(0)
+# alternate samples: noise|sample|noise|sample|...
+# where noise is more than 1 transition between 2 samples
+DwfDigitalInSampleModeNoise = c_int(1)
+
+DwfDigitalOutOutputPushPull = c_int(0)
+DwfDigitalOutOutputOpenDrain = c_int(1)
+DwfDigitalOutOutputOpenSource = c_int(2)
+DwfDigitalOutOutputThreeState = c_int(3)
+
+DwfDigitalOutTypePulse = c_int(0)
+DwfDigitalOutTypeCustom = c_int(1)
+DwfDigitalOutTypeRandom = c_int(2)
+DwfDigitalOutTypeROM = c_int(3)
+DwfDigitalOutTypeState = c_int(4)
+DwfDigitalOutTypePlay = c_int(5)
+
+DwfDigitalOutIdleInit = c_int(0)
+DwfDigitalOutIdleLow = c_int(1)
+DwfDigitalOutIdleHigh = c_int(2)
+DwfDigitalOutIdleZet = c_int(3)
+
+DwfAnalogImpedanceImpedance = c_int(0)
+DwfAnalogImpedanceImpedancePhase = c_int(1)
+DwfAnalogImpedanceResistance = c_int(2)
+DwfAnalogImpedanceReactance = c_int(3)
+DwfAnalogImpedanceAdmittance = c_int(4)
+DwfAnalogImpedanceAdmittancePhase = c_int(5)
+DwfAnalogImpedanceConductance = c_int(6)
+DwfAnalogImpedanceSusceptance = c_int(7)
+DwfAnalogImpedanceSeriesCapacitance = c_int(8)
+DwfAnalogImpedanceParallelCapacitance = c_int(9)
+DwfAnalogImpedanceSeriesInductance = c_int(10)
+DwfAnalogImpedanceParallelInductance = c_int(11)
+DwfAnalogImpedanceDissipation = c_int(12)
+DwfAnalogImpedanceQuality = c_int(13)
+DwfAnalogImpedanceVrms = c_int(14)
+DwfAnalogImpedanceVreal = c_int(15)
+DwfAnalogImpedanceVimag = c_int(16)
+DwfAnalogImpedanceIrms = c_int(17)
+DwfAnalogImpedanceIreal = c_int(18)
+DwfAnalogImpedanceIimag = c_int(19)
+
+DwfParamUsbPower = c_int(2) # 1 keep the USB power enabled even when AUX is connected, Analog Discovery 2
+DwfParamLedBrightness = c_int(3) # LED brightness 0 ... 100%, Digital Discovery
+DwfParamOnClose = c_int(4) # 0 continue, 1 stop, 2 shutdown
+DwfParamAudioOut = c_int(5) # 0 disable / 1 enable audio output, Analog Discovery 1, 2
+DwfParamUsbLimit = c_int(6) # 0..1000 mA USB power limit, -1 no limit, Analog Discovery 1, 2
+DwfParamAnalogOut = c_int(7) # 0 disable / 1 enable
+DwfParamFrequency = c_int(8) # Hz
+DwfParamExtFreq = c_int(9) # Hz
+DwfParamClockMode = c_int(10) # 0 internal, 1 output, 2 input, 3 IO
+
+# obsolate
+#STS
+stsRdy = c_ubyte(0)
+stsArm = c_ubyte(1)
+stsDone = c_ubyte(2)
+stsTrig = c_ubyte(3)
+stsCfg = c_ubyte(4)
+stsPrefill = c_ubyte(5)
+stsNotDone = c_ubyte(6)
+stsTrigDly = c_ubyte(7)
+stsError = c_ubyte(8)
+stsBusy = c_ubyte(9)
+stsStop = c_ubyte(10)
+
+#TRIGCOND
+trigcondRisingPositive = c_int(0)
+trigcondFallingNegative = c_int(1)
+
+#use deiceid
+enumfilterEExplorer = c_int(1)
+enumfilterDiscovery = c_int(2)
+enumfilterDiscovery2 = c_int(3)
+enumfilterDDiscovery = c_int(4)
+
+
diff --git a/src/FlexSensor/constants/qs_style_sheets.py b/src/FlexSensor/constants/qs_style_sheets.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd361c799927e8c976f0cec6c14dbc3562c54b25
--- /dev/null
+++ b/src/FlexSensor/constants/qs_style_sheets.py
@@ -0,0 +1,91 @@
+class CSSPlayPushButton:
+ @staticmethod
+ def style_play():
+ return """
+ QPushButton {
+ background-color: rgb(36, 209, 21);
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-radius: 0px;
+ border-left: 22px solid transparent;
+ text-align: left;
+ padding-left: 44px;
+ background-image: url(:/icons/images/icons/cil-media-play.png);
+ }
+
+ QPushButton:hover {
+ background-color: rgb(26, 153, 16);
+ }
+
+ QPushButton:pressed {
+ background-color: rgb(20, 120, 12);
+ color: rgb(255, 255, 255);
+ }
+
+ QPushButton:disabled {
+ background-color: rgb(153, 153, 153);
+ color: rgb(255, 255, 255);
+ }
+
+ """
+
+ @staticmethod
+ def style_pause():
+ return """
+ QPushButton {
+ background-color: rgb(255, 200,11);
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-radius: 0px;
+ border-left: 22px solid transparent;
+ text-align: left;
+ padding-left: 44px;
+ background-image: url(:/icons/images/icons/cil-media-pause.png)
+ }
+
+ QPushButton:hover {
+ background-color: rgb(255, 182, 44);
+ }
+
+ QPushButton:pressed {
+ background-color: rgb(255, 146, 12);
+ color: rgb(255, 255, 255);
+ }
+
+ QPushButton:disabled {
+ background-color: rgb(153, 153, 153);
+ color: rgb(255, 255, 255);
+ }
+ """
+
+ @staticmethod
+ def style_stop():
+ return """
+ QPushButton {
+ background-color: rgb(242, 41, 41);
+ background-position: left center;
+ background-repeat: no-repeat;
+ border: none;
+ border-radius: 0px;
+ border-left: 22px solid transparent;
+ text-align: left;
+ padding-left: 44px;
+ background-image: url(:/icons/images/icons/cil-media-stop.png)
+ }
+
+ QPushButton:hover {
+ background-color: rgb(235, 64, 52);
+ }
+
+ QPushButton:pressed {
+ background-color: rgb(201, 17, 4);
+ color: rgb(255, 255, 255);
+ }
+
+ QPushButton:disabled {
+ background-color: rgb(153, 153, 153);
+ color: rgb(255, 255, 255);
+ }
+ """
diff --git a/src/FlexSensor/generics/ConsoleWindow.py b/src/FlexSensor/generics/ConsoleWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..b60abbcddd6cd4ccb81ff3de6a3eac48c20e29ed
--- /dev/null
+++ b/src/FlexSensor/generics/ConsoleWindow.py
@@ -0,0 +1,201 @@
+import logging
+import random
+import time
+import os
+
+from PySide6.QtCore import QObject, QThread, Signal, Slot
+from PySide6.QtGui import QFont, Qt
+from PySide6.QtWidgets import QWidget, QPlainTextEdit, QPushButton, QVBoxLayout
+
+#Signal = Signal
+#Slot = Slot
+logger = logging.getLogger(__name__)
+
+
+#
+# Signals need to be contained in a QObject or subclass in order to be correctly
+# initialized.
+#
+class Signaller(QObject):
+ signal = Signal(str, logging.LogRecord)
+
+#
+# Output to a Qt GUI is only supposed to happen on the main thread. So, this
+# handler is designed to take a slot function which is set up to run in the main
+# thread. In this example, the function takes a string argument which is a
+# formatted log message, and the log record which generated it. The formatted
+# string is just a convenience - you could format a string for output any way
+# you like in the slot function itself.
+#
+# You specify the slot function to do whatever GUI updates you want. The handler
+# doesn't know or care about specific UI elements.
+#
+
+
+class QtHandler(logging.Handler):
+ def __init__(self, slotfunc, *args, **kwargs):
+ super(QtHandler, self).__init__(*args, **kwargs)
+ self.signaller = Signaller()
+ self.signaller.signal.connect(slotfunc)
+
+ def emit(self, record):
+ s = self.format(record)
+ self.signaller.signal.emit(s, record)
+
+#
+# This example uses QThreads, which means that the threads at the Python level
+# are named something like "Dummy-1". The function below gets the Qt name of the
+# current thread.
+#
+
+
+def ctname():
+ return ""
+ # QtCore.QThread.currentThread().objectName()
+
+
+#
+# Used to generate random levels for logging.
+#
+LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
+ logging.CRITICAL)
+
+#
+# This worker class represents work that is done in a thread separate to the
+# main thread. The way the thread is kicked off to do work is via a button press
+# that connects to a slot in the worker.
+#
+# Because the default threadName value in the LogRecord isn't much use, we add
+# a qThreadName which contains the QThread name as computed above, and pass that
+# value in an "extra" dictionary which is used to update the LogRecord with the
+# QThread name.
+#
+# This example worker just outputs messages sequentially, interspersed with
+# random delays of the order of a few seconds.
+#
+
+
+class Worker(QObject):
+ @Slot()
+ def start(self):
+ extra = {'qThreadName': ctname()}
+ logger.debug('Started work', extra=extra)
+ i = 1
+ # Let the thread run until interrupted. This allows reasonably clean
+ # thread termination.
+ while not QThread.currentThread().isInterruptionRequested():
+ delay = 0.5 + random.random() * 2
+ time.sleep(delay)
+ level = random.choice(LEVELS)
+ logger.log(level, 'Message after delay of %3.1f: %d',
+ delay, i, extra=extra)
+ i += 1
+
+#
+# Implement a simple UI for this cookbook example. This contains:
+#
+# * A read-only text edit window which holds formatted log messages
+# * A button to start work and log stuff in a separate thread
+# * A button to log something from the main thread
+# * A button to clear the log window
+#
+
+
+class ConsoleWindow(QWidget):
+
+ COLORS = {
+ logging.DEBUG: 'blue',
+ logging.INFO: 'black',
+ logging.WARNING: 'orange',
+ logging.ERROR: 'red',
+ logging.CRITICAL: 'purple',
+ }
+
+ def __init__(self, app):
+ super().__init__()
+ self.app = app
+ self.textedit = te = QPlainTextEdit(self)
+ # set the window, so it alwys stays in front
+ self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
+ # Set whatever the default monospace font is for the platform
+ #f = QFont('nosuchfont')
+ #f.setStyleHint(f.Monospace)
+ #te.setFont(f)
+ te.setReadOnly(True)
+ PB = QPushButton
+ #self.work_button = PB('Start background work', self)
+
+ self.clear_button = PB('Clear log window', self)
+ self.handler = h = QtHandler(self.update_status)
+ # Remember to use qThreadName rather than threadName in the format string.
+ fs = '%(asctime)s %(levelname)-8s %(message)s'
+ formatter = logging.Formatter(fs)
+ h.setFormatter(formatter)
+ logger.addHandler(h)
+ # Set up to terminate the QThread when we exit
+ app.aboutToQuit.connect(self.force_quit)
+
+ # Lay out all the widgets
+ layout = QVBoxLayout(self)
+ layout.addWidget(te)
+ # layout.addWidget(self.work_button)
+
+ layout.addWidget(self.clear_button)
+ self.setFixedSize(1200, 400)
+
+ # Connect the non-worker slots and signals
+
+ self.clear_button.clicked.connect(self.clear_display)
+
+ # Start a new worker thread and connect the slots for the worker
+ # self.start_thread()
+ # self.work_button.clicked.connect(self.worker.start)
+ # Once started, the button should be disabled
+ #self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False))
+
+ def start_thread(self):
+ self.worker = Worker()
+ self.worker_thread = QThread()
+ self.worker.setObjectName('Worker')
+ self.worker_thread.setObjectName('WorkerThread') # for qThreadName
+ self.worker.moveToThread(self.worker_thread)
+ # This will start an event loop in the worker thread
+ self.worker_thread.start()
+
+ def kill_thread(self):
+ # Just tell the worker to stop, then tell it to quit and wait for that
+ # to happen
+ self.worker_thread.requestInterruption()
+ if self.worker_thread.isRunning():
+ self.worker_thread.quit()
+ self.worker_thread.wait()
+ else:
+ print('worker has already exited.')
+
+ def force_quit(self):
+ pass
+ # For use when the window is closed
+ # if self.worker_thread.isRunning():
+ # self.kill_thread()
+
+ # The functions below update the UI and run in the main thread because
+ # that's where the slots are set up
+
+ @Slot(str, logging.LogRecord)
+ def update_status(self, status, record):
+ color = self.COLORS.get(record.levelno, 'black')
+ s = '<pre><font color="%s">%s</font></pre>' % (color, status)
+ self.textedit.appendHtml(s)
+
+ @Slot()
+ def manual_update(self):
+ # This function uses the formatted message passed in, but also uses
+ # information from the record to format the message in an appropriate
+ # color according to its severity (level).
+ level = random.choice(LEVELS)
+ extra = {'qThreadName': ctname()}
+ logger.log(level, 'Manually logged!', extra=extra)
+
+ @Slot()
+ def clear_display(self):
+ self.textedit.clear()
diff --git a/src/FlexSensor/generics/FolderHandler.py b/src/FlexSensor/generics/FolderHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce9dd9fd0e0a8a61a29ef053342df29bb3db6a57
--- /dev/null
+++ b/src/FlexSensor/generics/FolderHandler.py
@@ -0,0 +1,47 @@
+import logging
+import os
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.controller.VFSObject import VFSObject
+
+
+class FolderHandler(object):
+
+ @staticmethod
+ def create_output_folder():
+ VAutomatorConfig.output_dir = FolderHandler.create_folder(VAutomatorConfig.output_dir)
+
+ return VAutomatorConfig.output_dir
+
+ @staticmethod
+ def create_folder(vfs_obj: VFSObject):
+ '''
+ Check if the folder exists, if not create it
+ '''
+ # Check if the given argument is a file
+ if os.path.isfile(vfs_obj.absolute):
+ folder = os.path.dirname(vfs_obj.absolute)
+
+ # Try creating the output directory
+ if not os.path.exists(folder):
+ try:
+ os.makedirs(folder)
+ except Exception as exc:
+ logging.error("Could not create folder {folder}. Exception: {exc}")
+ raise exc
+ return folder
+
+ @staticmethod
+ def set_and_create_file(filename):
+ '''
+ Check if the folder for file exists, if not create it
+ '''
+ logging.info("Setting file: %s" % filename)
+ # Try creating the output directory
+ if not os.path.exists(os.path.dirname(filename)):
+ try:
+ os.makedirs(os.path.dirname(filename))
+ except OSError as exc:
+ raise Exception("Could not create folder %s/%s for path." % (os.path.dirname(filename), filename))
+ # create the file
+ return filename
\ No newline at end of file
diff --git a/src/FlexSensor/generics/GenericProperties.py b/src/FlexSensor/generics/GenericProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..eaa5bed4fc76759d4815d959976aa59fa6f90c3c
--- /dev/null
+++ b/src/FlexSensor/generics/GenericProperties.py
@@ -0,0 +1,34 @@
+from PySide6.QtCore import QObject
+from numpy import ndarray
+
+
+class GenericProperties(QObject):
+ def __init__(self):
+ super().__init__()
+
+ def to_str(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return str(value[0])
+ else:
+ return str(value)
+
+ def to_int(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return int(value[0])
+ else:
+ return int(value)
+
+ def to_float(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return float(value[0])
+ else:
+ return float(value)
+
+ def to_tuple(self, value):
+ if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+ return tuple(value[0])
+ else:
+ return tuple(value)
+
+ def fields(self) -> dict:
+ raise NotImplementedError
diff --git a/src/FlexSensor/generics/PandasTableModel.py b/src/FlexSensor/generics/PandasTableModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c199832356abb7b39b9e08cf59a4ab742535720
--- /dev/null
+++ b/src/FlexSensor/generics/PandasTableModel.py
@@ -0,0 +1,30 @@
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QMenu
+
+
+class PandasTableModel(QAbstractTableModel):
+ def __init__(self, df):
+ super().__init__()
+ self.df = df
+
+ def rowCount(self, parent=None):
+ return self.df.shape[0]
+
+ def columnCount(self, parent=None):
+
+ return self.df.shape[1]
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row()
+ col = index.column()
+ return str(self.df.iloc[row, col])
+ return None
+
+ def headerData(self, section, orientation, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ if orientation == Qt.Horizontal:
+ return str(self.df.columns[section])
+ elif orientation == Qt.Vertical:
+ return str(self.df.index[section])
+ return None
diff --git a/src/FlexSensor/generics/__init__.py b/src/FlexSensor/generics/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/generics/generics.py b/src/FlexSensor/generics/generics.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f2c679af1fbe343bb27995d794724e53ec17bf1
--- /dev/null
+++ b/src/FlexSensor/generics/generics.py
@@ -0,0 +1,4 @@
+def pch(c, num):
+ return ''.join([str(c) for i in range(0, num)])
+
+
diff --git a/src/FlexSensor/generics/logger.py b/src/FlexSensor/generics/logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..89c95c6eca27bb4d0b69a51b51e101f69dfe0cef
--- /dev/null
+++ b/src/FlexSensor/generics/logger.py
@@ -0,0 +1,145 @@
+import logging
+
+from PySide6 import QtCore, QtWidgets
+from PySide6.QtCore import Signal
+from rich.logging import RichHandler
+from scipy.signal import find_peaks#, find_peaks_cwt
+import os
+#from PySide6.QtNetwork import QAbstractSocket
+from os import mkdir
+from multiprocessing import Pool, Value
+import os.path
+from datetime import datetime
+# Needed for Digilent Analog Discovery 2 data acquisition
+from ctypes import *
+try:
+ from generics.ConsoleWindow import ConsoleWindow
+except:
+ pass
+
+
+class QTextEditLogger(logging.Handler, QtCore.QObject):
+ appendPlainText = Signal(str)
+
+ def __init__(self, parent):
+ super().__init__()
+ QtCore.QObject.__init__(self)
+ self.widget = QtWidgets.QPlainTextEdit(parent)
+ self.widget.setReadOnly(True)
+ self.appendPlainText.connect(self.widget.appendPlainText)
+
+ def emit(self, record):
+ msg = self.format(record)
+ self.appendPlainText.emit(msg)
+
+
+class Logger:
+
+ log_file_full = None
+ @staticmethod
+ def set_output_file(logfile):
+ Logger.log_file_full = logfile
+ print("%s" % Logger.log_file_full)
+
+ FORMAT="%Y-%m-%d %H-%M-%S.%f"
+
+ @staticmethod
+ def check_or_create_log_file():
+ if log_file_full is None:
+ raise ValueError("Log file can't be None")
+ if not os.path.exists(os.path.dirname(Logger.log_file_full)):
+ try:
+ os.makedirs(os.path.dirname(Logger.log_file_full))
+ except OSError as exc:
+ raise Exception("Could not create log file.")
+ Logger.info("Log file created: %s" % Logger.log_file_full)
+
+ @staticmethod
+ def debug(*args):
+ msg = datetime.now().strftime(Logger.FORMAT) + " [DEBUG] " + "".join(str(arg) for arg in args)
+ # check if folder exists
+ #logger.check_or_create_log_file()
+
+ with open(Logger.log_file_full, "a+") as f:
+ f.write(msg+ "\n")
+
+ #status_bar.showMessage("[DEBUG] " + "".join(str(arg) for arg in args))
+ #status_bar.setStyleSheet('border: 0; color: blue;')
+ print(msg)
+ return msg
+
+ @staticmethod
+ def info(*args):
+ msg = datetime.now().strftime(Logger.FORMAT) + " [INFO] " + "".join(str(arg) for arg in args)
+ # check if folder exists
+ #logger.check_or_create_log_file()
+
+ with open(Logger.log_file_full, "a+") as f:
+ f.write(msg + "\n")
+
+ #status_bar.showMessage("[INFO] " + "".join(str(arg) for arg in args))
+ #status_bar.setStyleSheet('border: 0; color: black;')
+ print(msg)
+ return msg
+
+ @staticmethod
+ def warning(*args):
+ msg = datetime.now().strftime(Logger.FORMAT) + " [WARN] " + "".join(str(arg) for arg in args)
+ # check if folder exists
+ #logger.check_or_create_log_file()
+
+ with open(Logger.log_file_full, "a+") as f:
+ f.write(msg+ "\n")
+
+ #status_bar.showMessage("[WARN] " + "".join(str(arg) for arg in args))
+ #status_bar.setStyleSheet('border: 0; color: orange;')
+ print(msg)
+ return msg
+
+ @staticmethod
+ def error(*args):
+ msg = datetime.now().strftime(Logger.FORMAT) + " [ERROR] " + "".join(str(arg) for arg in args)
+ # check if folder exists
+ #logger.check_or_create_log_file()
+
+ with open(Logger.log_file_full, "a+") as f:
+ f.write(msg + "\n")
+
+ #status_bar.showMessage("[ERROR] " + "".join(str(arg) for arg in args))
+ #status_bar.setStyleSheet('border: 0; color: red;')
+ print(msg)
+ return msg
+
+ @staticmethod
+ def fatal(*args):
+ msg = datetime.now().strftime(Logger.FORMAT) + " [FATAL] " + "".join(str(arg) for arg in args)
+ # check if folder exists
+ #logger.check_or_create_log_file()
+
+ with open(Logger.log_file_full, "a+") as f:
+ f.write(msg + "\n")
+
+ #status_bar.showMessage("[FATAL] " + "".join(str(arg) for arg in args))
+ #status_bar.setStyleSheet('border: 0; color: red;')
+ print(msg)
+ return msg
+
+
+def setup_logging(window: ConsoleWindow = None):
+ for log_name, log_obj in logging.Logger.manager.loggerDict.items():
+ if log_name != '<module name>':
+ log_obj.disabled = True
+ # Format the Rich logger
+ FORMAT = "%(message)s"
+ if window is not None:
+ logging.basicConfig(
+ level="DEBUG", format=FORMAT, datefmt="[%X]", handlers=[
+ RichHandler(rich_tracebacks=True), window.handler
+ ]
+ )
+ else:
+ logging.basicConfig(
+ level="DEBUG", format=FORMAT, datefmt="[%X]", handlers=[
+ RichHandler(rich_tracebacks=True)
+ ]
+ )
\ No newline at end of file
diff --git a/src/FlexSensor/generics/widgets.py b/src/FlexSensor/generics/widgets.py
new file mode 100644
index 0000000000000000000000000000000000000000..b61e4714c47be8efeba0e3b813d883a6db9fd96b
--- /dev/null
+++ b/src/FlexSensor/generics/widgets.py
@@ -0,0 +1,24 @@
+from PySide6.QtWidgets import QLabel
+
+
+class LEDIndicatorWidget(QLabel):
+ def __init__(self, color="yellow"):
+ super().__init__()
+ self.size = 8
+ self._create_led(color)
+
+ def _create_led(self, color):
+ self.set_color(color)
+
+ def set_color(self, color):
+ self.setStyleSheet(
+ "QLabel {background-color : " f"{color};"
+ "border-color : black; "
+ "border-width: 1px; "
+ "border-style: solid; "
+ f"border-radius: {int(self.size / 2)}px; "
+ f"min-height: {self.size}px; "
+ f"min-width: {self.size}px; "
+ f"max-height: {self.size}px; "
+ f"max-width: {self.size}px"
+ "}")