Interlock and controller for MerlinEM DMC.
The Merlin Motion Control app is used in conjunction with Quantum Detector's retractable Merlin detectors and the MotionPod interlock unit from MotionLink.
- Kivy 1.11.1
- Gclib for Python 3
In the main interface you have access to all the relevant status fields and buttons for safely controlling your retractable Merlin detector using the MotionPod from MotionLink.
The main window has control buttons for Standby, Move in, Move out and Stop commands; and fields displaying the current status of the MotionLink system. In the actionbar ther are buttons for Info and Settings.
Settings window with advanced settings that can be adjusted and saved for the current session. On exit these settings are disregarded, and the default ones are loaded on relaunching the application.
Info window with name of software, version and copyright notice.
Test window for running cycle tests. Delay specifies the time Merlin waits at the end positions in seconds('Retracted' and 'Inserted'); Cycles the number of insert and retract cycles it will do before stopping; Estimated time is calculated in two steps: 1. Before the cycle test has started, based on the speed specified to the controller of the stepper motor (See the Speed and Speed out parameters in the settings window.), the requested position and lastly the given Delay, 2. After the first cycle, by measuring the time to complete one cycle. The two estimates differ because of the overshoot when retracting the Merlin. This overshoot is necessary to allow the Merlin to recalibrate its position, so its position doesn't change over time. Time remaining counts down from the estimated time. After the correction by the secone time estimate, it corrects itself to count down from the time estimated for Cycles = Cycles - 1.
The button Cycle sets a running flag to True and enters a loop managing the insertions and retractions. The insert and retract commands are identical to those sent by pressing "Move in" and "Move out" in the main window. The abort button changes the running flag to False, and Request State is changed to "Cycle Test Aborted", after which the cycle test will abort and the countdown timer will stop upon completion of the current cycle.
The test window can be closed and reopened while the test is running.
- Standby: Moves the detector in to the standby position.
- Move in: Moves the detector in to the requested position.
- Move out: Moves the detector out. When it reaches position 0 a stop command is issued. The detector will temporarily be at a negative position, but adjust itself back to 0 before its current state is changed to retracted.
- Stop: Stops any ongoing movement of the detector and changes the current state to 'Stopped', upon which the detector can't be moved in. Move Out needs to be clicked before Move In can be used again.
- Requested State / Current State: *'Stopped' if the Stop button has recently been pressed. *'Moving' if a requested move in/move out or standby request has not been completed. *'Inserted' if no other command is issued after 'Move in', and Requested Position and Position are equal. *'Retracted' if no other command is issued after 'Move out' and Position equals 0.
- Gatan In: Value read from the MotionLink unit based on interlock set up. *'Yes': If the Gatan detector is inserted into the detector chamber. *'No': If the Gatan detector is out.
- Gatan Veto: *'Yes': If the interlock has been activated. * If Merlin is retracted and the Gatan detector is in: If the 'Move In' button is pressed the Merlin remains retracted. * If Merlin is moving and then the Gatan is inserted: The interlock overrides the insertion of the Gatan detector, moves the Merlin out until its current state is 'Retracted', then moves the Gatan detector in. * If Merlin is inserted and then the Gatan is inserted: Interlock override Gatan and keeps it out while retracting the Merlin. When Merlin is 'Retracted' the Gatan moves in.
- Requested Position: 3200 units equals 1 mm. This is the distance to which you want to insert the Merlin relative its retracted position. The default requested position can be set in the settings.json file. There is a hard limit to the maximum value you can set. If you try and assign a higher value than that of the maximum value the program will automatically override your input.
- Position: The current position relative the retracted position. 3200 units equals 1 mm.
Create a virtual environment (for compatibility reasons, if on MacOS install python3 using Homebrew, do not use /usr/bin/python3
).
python3 -m venv venv
Source the venv
source venv/bin/activate
If on Windows, depending on the shell, the sourcing is done using either .\venv\Scripts\activate.bat
or ./venv/Scripts/Activate.ps1
.
Install gclib and follow Python setupß instructions under Language Support > Python. Note you will have to carry out the setup instructions while in the virtual environment of merlin-motion-control. For example
Also note, that on MacOS, creating the environment variable DYLIB_LIBRARY_PATH
is not optional for this usage. See Galil's instructions on creating it.
With gclib set up for use as a package in Python, navigate to your merlin-motion-control
directory and install the last of the requirements (still in your virtual environment)
pip install -r requirements.txt
At this stage you can start the application by running
python Merlin_Motion_Control.py
On MacOS retina displays the GUI, as of now scales differently to that on Windows or an external monitor. The GUI is drawn on startup, so if it starts up on a non-retina monitor it will scale as it does on Windows.
- Merlin_Motion_Control.py - Run the application.
- .env - Contain the minimal environment settings to run the application. if settings.json is missing it is recreated from the environment.
- settings.json - Configs the user can change
- views/init.py - Load .env into environment
- views/interface.py - Load views and build GUI upon running application.
- views/modals - Contains directories for each modal window in the app (Info, Settings and Test).
- views/modals/info/infowindow.py - Define the logic for the .kv view. Values declared with self in the class can be accessed on the object created in .kv using root. E.g. self.software_title in .py is accessed with root.software_title in .kv.
- views/modals/info/infowindow.kv - Define the view of the info modal.
- views/screens - Contains directories for each screen (currently only main) used in the GUI.
- views/screens/main/mainscreen.py - Define the logic for the main screen. The main screen only interacts with other views and models/rw_galil.
- views/screens/main/mainscreen.kv - Define the view of the mainscreen.
- views/screens/main/statusfields.py - Define class for status fields on the main screen as a gridlayout.
- views/screens/main/actionbuttons.py - Define class for buttons on the main screen as a gridlayout.
- views/static/styles.kv - Define static reusable components that are loaded by interface.py and can be used in other .kv files.
- models/rw_galil.py - Update the model for the view layer to read off. Interact with the dmc through models/galil.py for keeping model in sync.
- models/galil.py - Update the model for the dmc. The model propagates as dmc->galil.py->rw_galil.py->mainscreen.py.
Please refer to each project's style and contribution guidelines for submitting patches and additions. In general, we follow the "fork-and-pull" Git workflow.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a Pull request so that we can review your changes
NOTE: Be sure to merge the latest from "upstream" before making a pull request!