Welcome to CustomXepr’s documentation¶
This documentation provides both a tutorial-like introduction to CustomXepr and a detailed reference of the API (currently only non-GUI classes):
Warning: Version 2.3.3 is the last release that supports Python 2.7. All newer releases only support Python 3.6 and higher.
CustomXepr¶
A Python instrument controller and GUI for Bruker E500 EPR spectrometers, MercuryiTC temperature controllers and Keithley 2600 series source measurement units. CustomXepr relies on the python drivers keithley2600 and mercuryitc and the respective user interfaces keithleygui and mercurygui for functionality regarding the Keithley 2600 and MercuryiTC instruments.

Overview¶
CustomXepr for Linux and macOS enables the interaction with all instruments involved in field induced electron spin resonance (FI-EPR) measurements: the Bruker E500 spectrometer, through Bruker’s Xepr Python API, the Oxford Instruments MercuryiTC temperature controller, and the Keithley 2600 series of source measurement units (SMUs). The program suite is structured into drivers and user interfaces for individual instruments (external packages), CustomXepr’s main class which provides higher level functions that often combine functionality from multiple instruments, and a manager which handles the scheduling of experiments.
The aim of CustomXepr is twofold: First and foremost, it enables the user to automate and schedule full measurement plans which may run for weeks without user input. Second, it complements the functionality of Bruker’s Xepr control software. This includes for instance powerful logging capabilities, a more accurate determination of the cavity’s Q-value from its frequency response, more reliable tuning of the cavity, the ability to re-tune the cavity during long-running measurements, logging of the cryostat temperature during measurements, and many more. Low level functionality and communication with the spectrometer remains with Xepr.

Finally, CustomXepr fully supports Bruker BES3T data files (DSC, DTA, etc). The
customxepr.experiment.XeprData
class enables loading, plotting, modifying and saving such
data files from regular, 2D or pulsed experiements. It also supports reading and plotting
the pulse sequences used to acquire the data, as saved in the DSC file. More information
is provided in the API documentation for the
XeprData
class.
Installation¶
Make sure that you have PyQt or PySide installed on your system (all other dependencies will be installed automatically). Then install CustomXepr by running in a terminal:
$ pip install git+https://github.com/OE-FET/customxepr
Instrument communication¶
CustomXepr communicates with with the Keithley and MercuryiTC through NI-VISA or pyvisa-py and is therefore independent of the actual interface, e.g., Ethernet, USB, or GPIB. Connections to the EPR spectrometer are handled through Bruker’s Xepr Python API.
Usage¶
CustomXepr can be run interactively from a Jupyter console, or as a standalone program. In the latter case, it will create its own internal Jupyter console for the user to run commands.
You can start CustomXepr from a Python command prompt as follows:
>>> from customxepr import run_gui
>>> run_gui()
To start the CustomXepr GUI from a console / terminal, run customxepr
.
CustomXepr has a user interface which displays all jobs waiting in the queue, all results returned from previous jobs, and all logging messages. Common tasks such as pausing, aborting and clearing jobs, plotting and saving returned data, and setting temperature stability tolerances can be performed through the interface itself. However, apart from tuning the cavity and reading a Q-factor, all jobs must be scheduled programmatically through the provided Jupyter console.
Job-scheduling¶
CustomXepr’s core consists of functions for preconfigured tasks, such as changing the
cryostat temperature, recording a transfer curve, performing a preconfigured EPR
measurement. For instance, customXepr.setTemperature(110)
tells the MercuryiTC to change
its temperature set-point to 110 K and waits until the latter is reached and maintained
with the desired stability (default: ±0.1 K for 120 sec). It also adjusts the helium flow
if necessary and warns the user if the target temperature cannot be reached within the
expected time. customXepr.runExperiment(powersat)
will run the preconfigured EPR
measurement “powersat” while tuning the cavity between scans and monitoring the
temperature stability during the measurement.
Such built in jobs are not performed immediately but are queued and run after the
successful completion of the previous jobs. Any data returned by a job, such as a transfer
curve or a cavity mode picture, will be kept in a result queue and saved to a specified
file if requested. If the returned object has save
and plot
methods implemented, one
can right-click on its entry in the GUI to plot the data or save it to the hard drive.
CustomXepr functions that are expected to run for longer than 1 sec can gracefully abort upon user request without leaving the setup in an inconsistent state.

In addition, the queuing system can be used to manually schedule any user-specified jobs,
related or unrelated to the EPR setup and its ancillary equipment. This can be done with
the queued_exec
decorator from customxepr.manager
:
>>> import time
>>> from customxepr.manager import Manager
>>> manager = Manager()
>>> # create test function
>>> @manager.queued_exec
... def test_func(*args):
... # do something
... for i in range(0, 10):
... time.sleep(1)
... # check for requested aborts
... if manager.abort.is_set():
... break
... return args # return input arguments
>>> # run the function: this will return immediately
>>> test_func('test succeeded')
The result returned by test_func
can be retrieved from the result queue as follows:
>>> result = manager.result_queue.get() # blocks until result is available
>>> print(result)
test succeeded
More information regarding the manual scheduling of experiments can be found here.
Logging and error handling¶
The detection and escalation of possible problems is key to enabling unattended measurements. Otherwise the user may come back after two days expecting a completed measurement cycle, only to see that the helium dewar was emptied a day ago or that the program got stuck asking the user if it should really override a data file. CustomXepr therefore includes logging capabilities to track the progress of jobs and notify the user of potential problems.
All CustomXepr methods release logging messages during their execution which may have the levels “status”, “info”, “warning”, and “error”. Status notifications will only be shown in the user interface and typically contain information about the progress of a job (number of completed scans in an EPR measurement, countdown until the temperature is stable, etc). Info notifications typically contain information about the beginning or completion of a job (e.g., “Waiting for temperature to stabilize.”, “All scans complete.”), and potentially useful information about how the job was completed (e.g., “Temperature stable at 120.01±0.02 K during scans.”).
Warning notifications are logged when CustomXepr believes that there may be a problem which requires user intervention, for instance if a job is taking significantly longer than expected, or if the gas flow required to maintain a certain temperature is unusually high. Finally, error messages are released if CustomXepr is unable to proceed with a job, in which case it will abort and pause all pending jobs. Such errors may include loss of communication with an instrument, repeated strong temperature fluctuations during an EPR measurement, etc.
By default, all messages of level “info” and higher are saved to a log file in the user’s home directory and messages of level “warning” and higher are sent as an email to the user’s address. In addition, temperature readings are saved to a log file every 5 min, allowing the user to retrospectively confirm the temperature stability during measurements.

Mercury controls¶
CustomXepr includes a higher-level worker thread which regularly queries the MercuryiTC for its sensor readings and provides a live stream of this data to other parts of the software. This prevents individual functions from querying the MercuryiTC directly and causing unnecessary overhead.
The user interface for the cryostat plots historic temperature readings going back up to 24 h and provides access to relevant temperature control settings such as gas flow, heater power, and ramping speed while lower-level configurations such as calibration tables must be changed programmatically through the provided Jupyter console.
The MercuryiTC user interface and driver have been split off as separate packages mercuryitc and mercurygui.

Keithley controls¶
As with the cryostat, CustomXepr includes a high-level user interface for Keithley 2600 series instruments which allows the user to configure, record and save voltage sweeps such as transfer and output measurements. Since there typically is no need to provide a live stream of readings from the Keithley, the data from an IV-curve is buffered locally on the instrument and only transferred to CustomXepr after completion of a measurement.
The Keithley 2600 user interface and driver have been split off as separate packages keithley2600 and keithleygui.

Example code¶
A measurement script is given below which uses CustomXepr to cycles through different
temperatures and records EPR spectra and transfer curves at each step. When run from an
interactive Python console, it is possible to then uses the created customxepr
instance
to pause or resume and even abort running measurements.
from XeprAPI import Xepr
from keithley2600 import Keithley2600
from mercuryitc import MercuryITC
from customxepr import CustomXepr
# Connect to individual instruments.
xepr = Xepr()
mercury = MercuryITC("MERCURY_VISA_ADDRESS")
keithley = Keithley2600("KEITHLEY_VISA_ADDRESS")
# Create a new instance of CustomXepr to coordinate measurements.
customxepr = CustomXepr(xepr, mercury, keithley)
# Get a preconfigured experiment from Xepr.
exp = xepr.XeprExperiment('Experiment')
# Set up different modulation amplitudes in Gauss for different temperatures.
modAmp = {5: 3, 50: 2, 100: 1, 150: 1, 200: 1, 250: 1.5, 300: 2}
# Specify folder to save data.
folder = '/path/to/folder'
title = 'my_sample'
for T in [5, 50, 100, 150, 200, 250, 300]:
# =================================================================
# Prepare temperature
# =================================================================
customxepr.setTemperature(T) # set desired temperature
customxepr.customtune() # tune the cavity
customxepr.getQValueCalc(folder, T) # measure and save the Q factor
# =================================================================
# Perform FET measurements
# =================================================================
# Generate file name for transfer curve.
transfer_file = '{}/{}_{}K_transfer.txt'.format(folder, title, T)
# Record default transfer curve and save to file.
customxepr.transferMeasurement(path=transfer_file)
# =================================================================
# Perform EPR measurements at Vg = -70V and Vg = 0V
# =================================================================
for Vg in [0, -70]:
customxepr.setVoltage(Vg, smu='smua') # bias gate
# Perform preconfigured EPR measurement, save to file.
esr_file = '{}/{}_{}K_Vg_{}V.txt'.format(folder, title, T, Vg)
customxepr.runXeprExperiment(exp, path=esr_file, ModAmp=modAmp[T])
customxepr.setVoltage(0, smu='smua') # set gate voltage to zero
customxepr.setStandby() # Ramp down field and set MW bridge to standby.
In this code, all functions belonging to CustomXepr will be added to the job queue and will be carried out successively such that, for instance, EPR measurements will not start while the temperature is still being ramped. Note that this example script will not load a graphical user interface.
Email notifications¶
By default, email notifications are sent from ‘customxepr@outlook.com’. CustomXepr at the moment provides no way to modify the email settings via the user interface, but you can set them manually in the config file in your home directory: ‘~/.CustomXepr/CustomXepr.ini’. Changes will be applied when restarting CustomXper.
By default, the relevant section in the config file reads:
[SMTP]
mailhost = localhost
port = 0
fromaddr = ss2151@cam.ac.uk
credentials =
secure =
Authentication credentials can be specified as a tuple (username, password)
. To specify the use
of a secure protocol (TLS), pass in a tuple for the secure
argument. This will only be used when
authentication credentials are supplied. The tuple will be either an empty tuple, or a single-value
tuple with the name of a keyfile, or a 2-value tuple with the names of the keyfile and certificate
file.
Requirements¶
System requirements:
Linux or macOS
Python 2.7 or 3.6 and higher
Recommended:
Bruker Xepr software with Python XeprAPI (required for EPR related functions), a Python 3 version of the API is available here
Postfix - mail transfer agent (required for email notifications from localhost)
Required python modules:
PyQt5 >= 5.9
Recommended python modules:
pyusb (only when using pyvisa-py backend)
pyserial (only when using pyvisa-py backend)
Acknowledgements¶
Modules¶
This section gives an overview of CustmoXepr’s modules:
CustomXepr¶
@author: Sam Schott (ss2151@cam.ac.uk)
(c) Sam Schott; This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales License.
- class main.CustomXepr(xepr=None, mercury=None, keithley=None)[source]¶
CustomXepr defines routines to control Bruker’s Xepr software and to run full ESR measurement cycles. When creating an instance of CustomXepr, you can pass instances of
XeprAPI.XeprAPI
,mercurygui.MercuryFeed
andkeithley2600.Keithley2600
to handle interactions with the respective instruments.All CustomXepr methods that do not end with ‘_sync’ are executed in a worker thread in the order of their calls. Scheduling of jobs and retrieval of results is handled by
manager.Manager
. For instructions on how to schedule your own experiments, please refer to the documentation ofmanager
.Every asynchronous method has an equivalent method ending with ‘_sync’ which will be called immediately and block until it is done. Those synchronous equivalents are generated at runtime and not documented here.
You can use
CustomXepr
on its own, but it is recommended to start it with the functionstartup.run()
in thestartup
module. This will automatically connect to available instruments and start CustomXepr’s graphical user interfaces.- Parameters
xepr – Xepr instance from the Bruker Python XeprAPI. Defaults to None if not provided.
mercuryfeed –
mercurygui.MercuryFeed
instance for live feed from MercuryiTC temperature controller. Defaults to None if not provided.keithley –
keithley2600.Keithley2600
instance from keithley2600 driver. Defaults to None if not provided.
- property notify_address¶
List with email addresses for status notifications.
- property temp_wait_time¶
Wait time until temperature is considered stable. Defaults to 120 sec.
- property temperature_tolerance¶
Temperature fluctuation tolerance. Defaults to 0.1 Kelvin.
- static getExpDuration(exp)[source]¶
Estimates the time required to run the given experiment. The returned value is given in seconds and is a lower limit, the actual run time may be longer due to fine-tuning between scans, waiting times for stabilization and flybacks.
- Parameters
exp – Xepr experiment object to run.
- Returns
Estimated experiment duration in seconds.
- Return type
Job scheduling¶
- class manager.Manager[source]¶
Manager
provides a high level interface for the scheduling and executing experiments. All queued experiments will be run in a background thread andManager
provides methods to pause, resume and abort the execution of experiments. All results will be kept in the result_queue for later retrieval.Function calls can be queued as experiments by decorating the function with the
Manager.queued_exec
decorator:>>> import time >>> from customxepr.manager import Manager >>> manager = Manager()
>>> # create test function >>> @manager.queued_exec ... def decorated_test_func(*args): ... # do something ... for i in range(0, 10): ... time.sleep(1) ... # check for requested aborts ... if manager.abort.is_set() ... break ... return args # return input arguments
>>> # run the function: this will return immediately >>> exp = decorated_test_func('test succeeded')
The result returned by test_func can be retrieved from the result queue or the returned Experiment instance:
>>> res1 = manager.result_queue.get() # blocks until result is available >>> res2 = exp.result() # blocks until result is available >>> print(res1) test succeeded >>> print(res1 is res2) True
Alternatively, it is possible to manually create an experiment from a function call and queue it for processing as follows:
>>> import time >>> from customxepr.manager import Manager, Experiment >>> manager = Manager()
>>> # create test function >>> def stand_alone_test_func(*args): ... # do something ... for i in range(0, 10): ... time.sleep(1) ... # check for requested aborts ... if manager.abort.is_set() ... break ... return args # return input arguments
>>> # create an experiment from function >>> exp = Experiment(stand_alone_test_func, args=['test succeeded',], kwargs={}) >>> # queue the experiment >>> manager.job_queue.put(exp)
This class provides an event abort which can queried periodically by any function to see if it should abort prematurely. Alternatively, functions and methods can provide their own abort events and register them with the manager as follows:
>>> from threading import Event >>> abort_event = Event() >>> # register the event with the manager instance >>> manager.abort_events = [abort_event]
The manager will automatically set the status of an experiment to ABORTED if it finishes while an abort event is set and clear all abort events afterwards.
- Variables
job_queue – An instance of
ExperimentQueue
holding all queued and finished experiments.result_queue – A queue holding all results.
running – Event that causes the worker to pause between jobs if set.
abort – A generic event which can be used in long-running experiments to check if they should be aborted.
- queued_exec(func)[source]¶
Decorator that puts a call to a wrapped function into the job_queue queue instead of executing it. Returns the queued
Experiment
which is similar to a Python’sconcurrent.futures.Future
.
- property notify_address¶
List of addresses for email notifications.
- property log_file_dir¶
Directory for log files. Defaults to ‘~/.CustomXepr’.
- property email_handler_level¶
Logging level for email notifications. Defaults to
logging.WARNING
.
- class manager.Experiment(func, args, kwargs)[source]¶
Class to hold a scheduled job / experiment and keep track of its status and result. It is similar in functionality to
concurrent.futures.Future
.- Parameters
func – Function or method to call when running experiment.
args – Arguments for function call.
kwargs – Keyword arguments for function call.
- result(timeout=None)[source]¶
Returns the result of the experiment. If the experiment hasn’t yet completed then this method will wait up to timeout seconds. If the experiment hasn’t completed in timeout seconds, then a TimeoutError will be raised. If timeout is not specified or None, there is no limit to the wait time.
If the experiment is cancelled before completing then CancelledError will be raised.
If the call raised, this method will raise the same exception.
- Parameters
timeout (int) – Time in seconds to wait for a result.
- Raises
TimeoutError if no result becomes available within
timeout
, CancelledError if the experiment has been cancelled or Exception if an exception occurred during execution.
- property status¶
Property that holds the status of the job.
- class manager.ExperimentQueue[source]¶
Queue to hold all jobs: Pending, running and already completed. Items in this queue should be of type
Experiment
.- Variables
added_signal – Emitted when a new job is added to the queue.
removed_signal – Emitted when a job is removed from the queue. Carriers the index of the job in
ExperimentQueue
.status_changed_signal – Emitted when a job status changes, e.g., from
ExpStatus.QUEUED
toExpStatus.RUNNING
. Carries a tuple holding the job index and status.
- property queue¶
Returns list of all items in queue (queued, running, and in history).
- put(exp)[source]¶
Adds item exp to the end of the queue. Its status must be
ExpStatus.QUEUED
. Emits theadded_signal
signal.
- get_next_job()[source]¶
Returns the next queued item and flags it as running. If there are no queued items,
queue.Empty
is raised. Emits thestatus_changed_signal
with the item’s index and its new status.
- job_done(exit_status, result=None)[source]¶
Call to inform the Experiment queue that a task is completed. Changes the corresponding item’s status to exit_status and its result to result. Emits the status_changed_signal with the item’s index and its new status.
- Parameters
exit_status – Status of the completed job, i.e.,
ExpStatus.ABORTED
.result – Return value of job, if available.
- remove_item(i)[source]¶
Removes the item with index i from the queue. Raises a
ValueError
if the item belongs to a running or already completed job. Emits theremoved_signal
carrying the index.- Parameters
i (int) – Index of item to remove.
- remove_items(i_start, i_end=None)[source]¶
Removes the items from index i_start to i_end inclusive from the queue. Raises a
ValueError
if the item belongs to a running or already completed job. Emits theremoved_signal
for every removed item.This call has O(n) performance with regards to the queue length and number of items to be removed.
- class manager.Worker(job_q, result_q, abort_events)[source]¶
Worker that gets all method calls with args from
job_q
and executes them. Results are then stored in theresult_q
.- Parameters
job_q – Queue with jobs to be performed.
result_q – Queue with results from completed jobs.
- Variables
running – Event that causes the worker to pause between jobs if set.
Experiment¶
This section gives an overview of modules to handle and plot experimental EPR data.
It contains two modules: experiment.xepr_dataset
defines classes to read, write,
manipulate and plot Xepr datasets from Bruker’s BES3T file format.
mode_picture_dataset.xepr_dataset
defines classes to read, write and plot cavity mode
pictures.
This page documents the main classes available from experiment
. The full API is
documented in the pages for the respective submodules:
Xepr data module¶
@author: Sam Schott (ss2151@cam.ac.uk)
(c) Sam Schott; This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales License.
- class experiment.xepr_dataset.XeprParam(name: str, value: Optional[Union[float, bool, str, numpy.ndarray]] = None, unit: str = '', comment: str = '')[source]¶
Bases:
object
Holds a Bruker measurement parameter in the BES3T file format.
- Parameters
value – The parameter value.
unit – String containing the unit. Defaults to an empty string.
comment – Defaults to an empty string.
- class experiment.xepr_dataset.ParamGroup(name: str = '', pars: Optional[List[experiment.xepr_dataset.XeprParam]] = None)[source]¶
Bases:
object
Class to hold an Xepr experiment parameter group, which is part of a layer.
- Variables
HEADER_FMT – Format of parameter group header.
CELL_LENGTH – Length of cell containing the parameter name.
DELIM – Delimiter between parameter name and value.
- Parameters
name – The parameter group’s name.
pars – Dictionary containing all
XeprParam
instances belonging to the group.
- class experiment.xepr_dataset.ParamGroupDESC(name: str = '', pars: Optional[List[experiment.xepr_dataset.XeprParam]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamGroup
Class to hold an Xepr experiment parameter group which forms a section of the Descriptor Layer (DESC).
- class experiment.xepr_dataset.ParamGroupSPL(name: str = '', pars: Optional[List[experiment.xepr_dataset.XeprParam]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamGroup
Class to hold an Xepr experiment parameter group associated with a functional unit, part of the Standard Parameter Layer (SPL).
- HEADER_FMT = None¶
- class experiment.xepr_dataset.ParamGroupDSL(name: str = '', pars: Optional[List[experiment.xepr_dataset.XeprParam]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamGroup
Class to hold an Xepr experiment parameter group associated with a functional unit, part of the Device Specific Layer (DSL).
- class experiment.xepr_dataset.ParamGroupMHL(name: str = '', pars: Optional[List[experiment.xepr_dataset.XeprParam]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamGroup
Class to hold an Xepr experiment parameter group which forms a section of the Manipulation History Layer (MHL).
- class experiment.xepr_dataset.ParamLayer(groups: Optional[List[experiment.xepr_dataset.ParamGroup]] = None)[source]¶
Bases:
object
Parameter layer object. Contains a top level parameter section of a Bruker BES3T file. This should be subclassed, depending on the actual parameter layer type.
- Variables
TYPE – Parameter layer type. Can be ‘DESC’ for a Descriptor Layer, ‘SPL’ for a Standard Parameter Layer, ‘DSL’ for a Device Specific Layer or ‘MHL’ for a Manipulation History Layer.
NAME – Parameter layer name.
VERSION – Parameter layer version. This identifies the implemented BES3T file format specification used when parsing the information.
HEADER_FMT – Header format for the parameter layer.
END – Characters to indicate the end of layer in ‘.DSC’ file.
- GROUP_CLASS¶
alias of
experiment.xepr_dataset.ParamGroup
- class experiment.xepr_dataset.DescriptorLayer(groups: Optional[List[experiment.xepr_dataset.ParamGroup]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamLayer
Descriptor Layer class.
- GROUP_CLASS¶
- class experiment.xepr_dataset.StandardParameterLayer(groups: Optional[List[experiment.xepr_dataset.ParamGroup]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamLayer
Standard Parameter Layer class.
- GROUP_CLASS¶
- class experiment.xepr_dataset.DeviceSpecificLayer(groups: Optional[List[experiment.xepr_dataset.ParamGroup]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamLayer
Device Specific Parameter Layer class.
- GROUP_CLASS¶
- class experiment.xepr_dataset.ManipulationHistoryLayer(groups: Optional[List[experiment.xepr_dataset.ParamGroup]] = None)[source]¶
Bases:
experiment.xepr_dataset.ParamLayer
Manipulation History Parameter Layer class.
- GROUP_CLASS¶
- class experiment.xepr_dataset.Pulse(position: int, length: int, position_increment: int = 0, length_increment: int = 0)[source]¶
Bases:
object
Object representing a single pulse.
- Parameters
position – Pulse position in ns.
length – Pulse length in ns.
position_increment – Increment in pulse position between subsequent measurements in ns.
length_increment – Increment in pulse length between subsequent measurements in ns.
- class experiment.xepr_dataset.PulseChannel(par: experiment.xepr_dataset.XeprParam)[source]¶
Bases:
object
On object representing a pulse channel in a pulsed ESR experiment. Pulse channels can be for microwave pulses and acquisition (e.g., “+x”, “+y”, “AWG Trigger”, “Acquisition trigger”) which are manually set by the user or for instrument control pulses which are automatically determined (e.g., “TWT”, “”Receiver Protection”).
Every pulse channel can hold up to 1024 pulses, represented by
Pulse
instances.- Variables
N_PULSES_DEFAULT – Default number of programmable pulses: 400.
N_PULSES_MAX – Maximum number of programmable pulses 1024.
channel_descriptions – Verbose descriptions of pulse channels in a data file (otherwise designated by numbers Psd1 to Psd34 only).
- Parameters
par – XeprParam holding the pulse channel table.
- property pulses: List[experiment.xepr_dataset.Pulse]¶
List of pulses in this channel.
- class experiment.xepr_dataset.PulseSequence(dset: experiment.xepr_dataset.XeprData)[source]¶
Bases:
object
Object which hold information about the pulse sequence used to acquire the dataset (in case of pulsed experiments). This object is constructed from the pulse channel tables “Psd1”, “Psd2”, etc, in the descriptor layer.
- property pulse_channels: List[experiment.xepr_dataset.PulseChannel]¶
Returns a list of pulse channels present in the instrument.
- plot() None [source]¶
Plots the pulse sequence used to acquire the data.
- Raises
RuntimeError
if the experiment is not pulsed.- Raises
ImportError
if matplotlib is not installed.
- class experiment.xepr_dataset.ParamDict(layers: Dict[str, experiment.xepr_dataset.ParamLayer])[source]¶
Bases:
collections.abc.MutableMapping
Object to allow attribute access to all measurement parameters.
- class experiment.xepr_dataset.XeprData(path: Optional[str] = None)[source]¶
Bases:
object
Holds a Bruker EPR measurement result, including all measurement parameters. Supports importing and exporting to the Bruker BES3T file format (‘.DSC’, ‘.DTA’ and possible associated ‘.XGF’, ‘.YGF’ and ‘.ZGF’ files) in the 1.2 specification currently used by Xepr. Parameters are stored in the following attributes and are grouped after the associated functional unit (e.g., ‘mwBridge’, ‘fieldCtrl’) or type (e.g., ‘Documentational Text’).
- Variables
desc –
DescriptorLayer
instance holding the parameters from the ‘.DSC’ file that describe content and parsing of corresponding data files (‘.DTA’ etc).spl –
StandardParameterLayer
instance holding all mandatory EPR parameters, such as the microwave power.dsl –
DeviceSpecificLayer
instance holding the EPR measurement parameters specific to the instrument and type of measurement, i.e., the measurement temperature, sample angles, integration time, etc.mhl –
ManipulationHistoryLayer
instance holding all parameters that describe manipulations performed on the data set (e.g., baseline correction, scaling, …).pars – Dictionary-like object giving direct access to all measurement parameters. Allows for quickly reading and setting parameter values.
pulse_sequence –
PulseSequence
instance which describes the pulse sequence used to acquire the data (in case of pulsed experiments). This object is constructed from the pulse channel tables “Psd1”, “Psd2”, etc, in the descriptor layer.
Setting the value of an existing parameter will automatically update it in the appropriate parameter layer. Setting a new parameter value will add it to a ‘customXepr’ device group in the
DeviceSpecificLayer
.The actual data is accessible as numpy arrays
x
,y
,z
ando
. Only the the ordinate data may be changed and the new data must have the same size and format aso
. It is not currently possible to change the x/y/z-axis data.Warning
Changing the parameters in the Descriptor Layer may result in inconsistencies between the parameter file (DSC) and the actual data files (DTA, XGF, YGF, ZGF) and therefore may result in corrupted files.
- Examples
Read a data file and get some information about the device specific parameters:
>>> from customxepr import XeprData, XeprParam >>> dset = XeprData("/path/to/file.DSC") >>> dset.dsl.groups {"fieldCtrl": <ParamGroupDSL(fieldCtrl)>, "fieldSweep": <ParamGroupDSL(fieldSweep)>, "freqCounter": <ParamGroupDSL(freqCounter)>, "mwBridge": <ParamGroupDSL(mwBridge)>, "recorder": <ParamGroupDSL(recorder)>, "signalChannel": <ParamGroupDSL(signalChannel)>} >>> dset.dsl.groups["mwBridge"].pars {"AcqFineTuning": <XeprParam(Never)>, "AcqScanFTuning": <XeprParam(Off)>, "AcqSliceFTuning": <XeprParam(Off)>, "BridgeCalib": <XeprParam(50.5)>, "Power": <XeprParam(0.002 mW)>, "PowerAtten": <XeprParam(50.0 dB)>, "QValue": <XeprParam(5900)>}
Change the value of an existing parameter:
>>> dset.pars["ModAmp"].value = 2
Add a new parameter without an associated group (it will be added to a “CustomXepr” group in the DSL layer):
>>> dset.pars["NewParam"] = XeprParam("NewParam", 1234)
Add a new parameter to the microwave bridge device group:
>>> dset.dsl.groups["mwBridge"].add_param(XeprParam("QValue", 6789))
Add a new parameter group for a temperature controller, with two parameters:
>>> pars = [ ... XeprParam("Temperature", 290, "K"), ... XeprParam("AcqWaitTime", 120, "s") ... ] >>> new_group = ParamGroupDSL("tempCtrl", pars) >>> dset.dsl.groups["tempCtrl"] = new_group
Save the modified data set:
>>> dset.save("/path/to/file.DSC")
- property x: numpy.ndarray¶
Returns x-axis data as numpy array.
- property y: numpy.ndarray¶
Returns y-axis data as numpy array.
- property z: numpy.ndarray¶
Returns z-axis data as numpy array.
- property o: numpy.ndarray¶
Returns ordinate data as numpy array or as a tuple of arrays containing all ordinate data sets. If real and imaginary parts are present, they will be combined to a complex numpy array.
- load(path: str) None [source]¶
Loads data and parameters from a ‘.DSC’ file and accompanying data files.
- Parameters
path (str) – Path to ‘.DSC’ file or accompanying data files to load. Any of those file paths can be given, the other files belonging to the same data set will be found automatically if in the same directory.
- save(path: str) None [source]¶
Saves data and parameters to a ‘.DSC’ file and accompanying data files.
- Parameters
path (str) – Path to ‘.DSC’ file or accompanying data files to save. Any of those file paths can be given, the other file names will be generated as necessary.
Mode picture module¶
@author: Sam Schott (ss2151@cam.ac.uk)
(c) Sam Schott; This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales License.
- experiment.mode_picture_dataset.lorentz_peak(x, x0, w, a)[source]¶
Lorentzian with area a, full-width-at-half-maximum w, and center x0.
- class experiment.mode_picture_dataset.ModePicture(input_path_or_data, freq=9.385, metadata=None)[source]¶
Class to store mode pictures. It provides methods to calculate Q-values, and save and load mode picture data from and to .txt files.
If several mode pictures with different zoom factors are given,
ModePicture
will rescale and combine the data into a single mode picture.- Parameters
- Variables
x_data_mhz – Numpy array with x-axis data of mode picture in MHz.
x_data_points – Numpy array with x-axis data of mode picture in pts.
y_data – Mode picture y-axis data (absorption of cavity).
freq0 – Center frequency of cavity resonance.
qvalue – Fitted Q-Value.
qvalue_stderr – Standard error of Q-Value from fitting.
- combine_data(mode_pic_data)[source]¶
Rescales mode pictures from different zoom factors and combines them to one.
- Parameters
mode_pic_data (dict) – Dict with zoom factors as keys and respective mode picture curves as values.
- Returns
(x_axis_mhz_comb, x_axis_points_comb, mode_pic_comb) where x_axis_mhz_comb and x_axis_points_comb are the combined x-axis values of all mode pictures in mhz and points, respectively, and mode_pic_comb is the combines y-axis data in a.u..
- fit_qvalue(x_data, y_data, zoom_factor=1)[source]¶
Least square fit of Lorentzian and polynomial background to mode picture.
- Parameters
x_data – Iterable containing x-data of mode picture in points.
y_data – Iterable containing y-data of mode picture in a.u..
zoom_factor – Zoom factor (scaling factor of x-axis).
- Returns
(q_value, fit_result) where fit_result is a
- get_qvalue_stderr()[source]¶
Determines 1 sigma confidence bounds for Q-value.
- Returns
Standard error of Q-value from fitting.
- Return type
- plot()[source]¶
Plots mode picture and the least squares fit used to determine the Q-value. Requires matplotlib.
- class experiment.XeprData(path: Optional[str] = None)[source]¶
Holds a Bruker EPR measurement result, including all measurement parameters. Supports importing and exporting to the Bruker BES3T file format (‘.DSC’, ‘.DTA’ and possible associated ‘.XGF’, ‘.YGF’ and ‘.ZGF’ files) in the 1.2 specification currently used by Xepr. Parameters are stored in the following attributes and are grouped after the associated functional unit (e.g., ‘mwBridge’, ‘fieldCtrl’) or type (e.g., ‘Documentational Text’).
- Variables
desc –
DescriptorLayer
instance holding the parameters from the ‘.DSC’ file that describe content and parsing of corresponding data files (‘.DTA’ etc).spl –
StandardParameterLayer
instance holding all mandatory EPR parameters, such as the microwave power.dsl –
DeviceSpecificLayer
instance holding the EPR measurement parameters specific to the instrument and type of measurement, i.e., the measurement temperature, sample angles, integration time, etc.mhl –
ManipulationHistoryLayer
instance holding all parameters that describe manipulations performed on the data set (e.g., baseline correction, scaling, …).pars – Dictionary-like object giving direct access to all measurement parameters. Allows for quickly reading and setting parameter values.
pulse_sequence –
PulseSequence
instance which describes the pulse sequence used to acquire the data (in case of pulsed experiments). This object is constructed from the pulse channel tables “Psd1”, “Psd2”, etc, in the descriptor layer.
Setting the value of an existing parameter will automatically update it in the appropriate parameter layer. Setting a new parameter value will add it to a ‘customXepr’ device group in the
DeviceSpecificLayer
.The actual data is accessible as numpy arrays
x
,y
,z
ando
. Only the the ordinate data may be changed and the new data must have the same size and format aso
. It is not currently possible to change the x/y/z-axis data.Warning
Changing the parameters in the Descriptor Layer may result in inconsistencies between the parameter file (DSC) and the actual data files (DTA, XGF, YGF, ZGF) and therefore may result in corrupted files.
- Examples
Read a data file and get some information about the device specific parameters:
>>> from customxepr import XeprData, XeprParam >>> dset = XeprData("/path/to/file.DSC") >>> dset.dsl.groups {"fieldCtrl": <ParamGroupDSL(fieldCtrl)>, "fieldSweep": <ParamGroupDSL(fieldSweep)>, "freqCounter": <ParamGroupDSL(freqCounter)>, "mwBridge": <ParamGroupDSL(mwBridge)>, "recorder": <ParamGroupDSL(recorder)>, "signalChannel": <ParamGroupDSL(signalChannel)>} >>> dset.dsl.groups["mwBridge"].pars {"AcqFineTuning": <XeprParam(Never)>, "AcqScanFTuning": <XeprParam(Off)>, "AcqSliceFTuning": <XeprParam(Off)>, "BridgeCalib": <XeprParam(50.5)>, "Power": <XeprParam(0.002 mW)>, "PowerAtten": <XeprParam(50.0 dB)>, "QValue": <XeprParam(5900)>}
Change the value of an existing parameter:
>>> dset.pars["ModAmp"].value = 2
Add a new parameter without an associated group (it will be added to a “CustomXepr” group in the DSL layer):
>>> dset.pars["NewParam"] = XeprParam("NewParam", 1234)
Add a new parameter to the microwave bridge device group:
>>> dset.dsl.groups["mwBridge"].add_param(XeprParam("QValue", 6789))
Add a new parameter group for a temperature controller, with two parameters:
>>> pars = [ ... XeprParam("Temperature", 290, "K"), ... XeprParam("AcqWaitTime", 120, "s") ... ] >>> new_group = ParamGroupDSL("tempCtrl", pars) >>> dset.dsl.groups["tempCtrl"] = new_group
Save the modified data set:
>>> dset.save("/path/to/file.DSC")
- property x: numpy.ndarray¶
Returns x-axis data as numpy array.
- property y: numpy.ndarray¶
Returns y-axis data as numpy array.
- property z: numpy.ndarray¶
Returns z-axis data as numpy array.
- property o: numpy.ndarray¶
Returns ordinate data as numpy array or as a tuple of arrays containing all ordinate data sets. If real and imaginary parts are present, they will be combined to a complex numpy array.
- load(path: str) None [source]¶
Loads data and parameters from a ‘.DSC’ file and accompanying data files.
- Parameters
path (str) – Path to ‘.DSC’ file or accompanying data files to load. Any of those file paths can be given, the other files belonging to the same data set will be found automatically if in the same directory.
- save(path: str) None [source]¶
Saves data and parameters to a ‘.DSC’ file and accompanying data files.
- Parameters
path (str) – Path to ‘.DSC’ file or accompanying data files to save. Any of those file paths can be given, the other file names will be generated as necessary.
- class experiment.XeprParam(name: str, value: Optional[Union[float, bool, str, numpy.ndarray]] = None, unit: str = '', comment: str = '')[source]¶
Holds a Bruker measurement parameter in the BES3T file format.
- Parameters
value – The parameter value.
unit – String containing the unit. Defaults to an empty string.
comment – Defaults to an empty string.
- class experiment.ModePicture(input_path_or_data, freq=9.385, metadata=None)[source]¶
Class to store mode pictures. It provides methods to calculate Q-values, and save and load mode picture data from and to .txt files.
If several mode pictures with different zoom factors are given,
ModePicture
will rescale and combine the data into a single mode picture.- Parameters
- Variables
x_data_mhz – Numpy array with x-axis data of mode picture in MHz.
x_data_points – Numpy array with x-axis data of mode picture in pts.
y_data – Mode picture y-axis data (absorption of cavity).
freq0 – Center frequency of cavity resonance.
qvalue – Fitted Q-Value.
qvalue_stderr – Standard error of Q-Value from fitting.
- combine_data(mode_pic_data)[source]¶
Rescales mode pictures from different zoom factors and combines them to one.
- Parameters
mode_pic_data (dict) – Dict with zoom factors as keys and respective mode picture curves as values.
- Returns
(x_axis_mhz_comb, x_axis_points_comb, mode_pic_comb) where x_axis_mhz_comb and x_axis_points_comb are the combined x-axis values of all mode pictures in mhz and points, respectively, and mode_pic_comb is the combines y-axis data in a.u..
- fit_qvalue(x_data, y_data, zoom_factor=1)[source]¶
Least square fit of Lorentzian and polynomial background to mode picture.
- Parameters
x_data – Iterable containing x-data of mode picture in points.
y_data – Iterable containing y-data of mode picture in a.u..
zoom_factor – Zoom factor (scaling factor of x-axis).
- Returns
(q_value, fit_result) where fit_result is a
- get_qvalue_stderr()[source]¶
Determines 1 sigma confidence bounds for Q-value.
- Returns
Standard error of Q-value from fitting.
- Return type
- plot()[source]¶
Plots mode picture and the least squares fit used to determine the Q-value. Requires matplotlib.
Startup¶
Created on Tue Aug 23 11:03:57 2016
@author: Sam Schott (ss2151@cam.ac.uk)
(c) Sam Schott; This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales License.
- startup.show_splash_screen()[source]¶
Shows the CustomXepr splash screen.
- Returns
PyQt5.QtWidgets.QSplashScreen
.
- startup.connect_to_instruments()[source]¶
Tries to connect to Keithley, Mercury and Xepr. Uses the visa addresses saved in the respective configuration files.
- Returns
Tuple containing instrument instances.
- Return type
- startup.start_gui(customXepr, mercury, keithley)[source]¶
Starts GUIs for Keithley, Mercury and CustomXepr.
- Returns
Tuple containing GUI instances.
- Return type
- startup.run_cli()[source]¶
This is the main interactive shell entry point. Calling
run_cli
will connect to all instruments and return instantiated control classes.- Returns
Tuple containing instrument instances.
- Return type
Changelog¶
v3.1.3¶
Fixed:¶
Fixed spurious notifications from log messages emitted outside of customxepr.
v3.1.2¶
Added:¶
Added support to parse and plot the pulse sequence information stored in the Bruker DSC file in the tables Psd1 to Psd36:
>>> from customxepr.experiment import XeprData >>> dset = XeprData("path") >>> dset.pulse_sequence.plot() >>> print(dset.pulse_sequence.pulse_channels[5]) <PulseChannel(Psd6: +x)> >>> print(dset.pulse_sequence.pulse_channels[5].pulses) [<Pulse(position=276, length=4)>, <Pulse(position=676, length=44)>]
Added a keyword argument
settling_time
torunXeprExperiment
to wait between individual scans. This can be useful in case of temperature fluctuations between scans.
Changed:¶
Remove custom
exit_customxepr()
function. Instead, close the console to exit CustomXepr or runexit
when started from an IPython or Jupyter shell.Increase default maximum cooling temperature to 20°C.
Remember the location of the console window between restarts.
Set current directory of Xepr to directory of last-saved data.
The Qt event loop is no longer started on every import but just when actually starting the GUI or plotting a figure.
getValueXepr
no longer accepts a path argument.getQValueCalc
no longer saves two files but the mode picture only. The given path must now be the full file path. The temperature data will now be saved together with the mode picture.getQValueCalc
no longer accepts a temperature argument. Instead, the temperature will be read from the Mercury if available.The
ModePicture
class now accepts arbitrary metadata in dictionary form. This data will be saved as tab-delimited metadata in the mode picture file.
Fixed:¶
Fixed an issue when saving a dateset through Xepr when the path contains whitespace or backslashes. The path is now quoted with
shlex.quote
before being passed to Xepr.
v3.1.1¶
Changed:¶
Only show single-line previews of results in GUI.
Improve warnings for too high gasflow.
Allow overriding default tolerance and wait time in
waitTemperatureStable
.
Added:¶
Monitor cooling water temperature during measurements and interrupt ESR measurements if too high.
Added config file entries for the maximum cooling temperature and the temperature sensor names for the ESR and cooling water.
Fixed:¶
Fixes an issue in
customxepr.experiment.xepr_dataset.XeprParam
where theunit
attribute would return the value instead of the unit.
v3.1.0¶
Added:¶
Added API similar to
concurrent.futures.Future
tocustomxepr.manager.Experiment
.Return an experiment instance from all async customxepr method calls. This instance can be used to get the result directly, instead of getting it from the result queue. Usage:
future = customXepr.runXeprExperiment(...) result = future.result() # will block until result is available
Changed:¶
CustomXepr.tune
andCustomXepr.finetune
can now be aborted.ModePicture.load(...)
no longer returns the raw data but rather populates the class attributes ofModePicture
with the loaded data.XeprData
now shows the experiment title in its string representation.Changed the default email address for notifications to physics-oe-esr-owner@lists.cam.ac.uk.
Improvements to documentation.
Require PyQt5 instead of qtpy / PySide2.
Fixed:¶
Fixes an issue where
CustomXepr.tune
andCustomXepr.finetune
would return immediately, even if tuning was not complete.
v3.0.0¶
This release drops support for Python 2.7. Only Python 3.6 and higher are supported.
Added:¶
Method
CustomXepr.getExpDuration
to estimate the duration of an Xepr experiment.Added synchonous functions for all of CustomXepr’s asynchronous functions (which will be queued). These are automatically generated and end with the suffix “_sync”.
Added
shape
attribute toXeprData
class.
Changed:¶
Changed the abort behaviour of a measurement: Instead of finishing the current scan and pausing afterwards, the scan is aborted immediately.
Renamed
setDrainCurrent
tosetCurrent
andsetGateVoltage
tosetVoltage
.setVoltage
no longer turns the other SMUs off.Optimized the truncation of long items in the list of running expriements.
- Changed the priority of locations to search for the XeprAPI:
path from the environment variable
XEPR_API_PATH
(if set)installed python packages
pre-installed version from Xepr
Renamed
applyCurrent
tosetCurrent
.The
queued_exec
decorator is now an attribute ofcustomXepr.manager.Manager
and no longer requires the job queue as an argument. Instead, the manager’sjob_queue
will be used automatically.The
queued_exec
decorator now is re-entrant: decorated functions which are called from within the worker thread won’t be queued themselves.Moved
CustomXepr._wait_stable
to a public methodCustomXepr.waitTemperatureStable
.Enforce usage of
exit_customxepr()
to exit.Set the default address for email notifications to ‘physics-oe-esr-owner@lists.cam.ac.uk’.
Increased the default timeout for PyVisa communication from 2 sec to 5 sec.
Fixed:¶
Fixed a bug when plotting aquired results: This was related to the IPython kernel or the interactive console using the wrong GUI backend. It now uses the Qt backend.
Fixed a bug which would cause
XeprData.plot
to fail in case of multiple datasets per scan, e.g., for simultanious detection of the in-phase and out-of-phase signals.Fixed several Python 3 compatibility issues.
Removed:¶
Support for Python 2.7. Only Python 3.6 and higher will be supported. Please migrate.
v2.3.4 (2019-10-09)¶
Main changes are:
Possible file names for Xepr data are no longer limited by Xepr’s file name restrictions.
Added a function
exit_customxepr
which gracefully disconnects all instruments before quitting the Python console. This avoids errors on the next startup.Bug fixes.
In more detail:
Added:¶
Added a function
exit_customxepr
which gracefully disconnects all instruments and then exits the Python console. This avoids errors on the next startup.Added a help button to the main UI, replacing the copyright notice.
Added support for dark interface themes, such as dark mode in macOS Mojave. This requires a version of PyQt / Qt which supports system themes, e.q. PyQt 5.12+ for macOS.
Changed:¶
Changed how Xepr data is saved: CustomXepr will now always save to a temporary file first which is guaranteed to comply with Xepr’s file name restrictions. This temporary file will then be reloaded to add custom parameters and will be saved through Python to any path which the file system accepts.
If CustomXepr is not started from an IPython console, use an in-process IPython kernel and Jupyter console widget for user interactions. This gives us better control over the appearance of the console widget.
Removed pyqrgraph dependency.
Fixed:¶
Fixed a bug which could cause
customXepr.setGateVoltage()
and subsequent Keithley commands to fail due to an invalid command sent to the Keithley.Fixed a bug which would cause queued function calls without any arguments not to show in the job queue window.
Fixed a bug which would prevent the phase from being cycled by 360 deg when hitting the upper or lower limit during a tuning routine.
v2.3.3 (2019-07-15)¶
This release focuses on minor UI improvements. The most notable change is a better handling of Bruker data files: the order of entries in DSC files is preserved when saving through CustomXepr.
Changed:¶
Small tweaks to dialog windows (update info, about window, etc.).
Preserve order of entries in DSC files in Python 2. Previously, the order of sections and parameter would be randomized when loading and saving a Bruker DSC files with CustomXepr in Python 2.7.
Moved some custom widgets which are shared between
customxepr
,keithleygui
andmercurygui
to a common submodulepyqt_labutils
.
v2.3.2 (2019-05-25)¶
Improves compatibility of XeprData
with Bruker’s Xepr BES3T file format: support
complex data and more exotic data formats.
Added:¶
Expanded support for Xepr data files: introduced support for complex data sets, 32-bit floats and 32-bit signed integers as well as multiple ordinate data sets per data file.
Introduced support for different byte-orders, as specified in ‘.DSC’ file.
Save the standard error from fitting the Q-Value as a new parameter ‘QValueErr’ in the DSC file, if available.
Allow configuration of a custom SMTP server for email notifications in the config file ‘~/.CustomXepr/CustomXepr.ini’.
Changed:¶
Improved the usefulness of some log messages.
Keep measurement logs for 356 days instead of 7 days.
Improved formatting of DSC files saved through CustomXepr vs Xepr. Number formatting, e.g., the number of significant digits, will be preserved unless the parameter value has changes
Fixed:¶
Fixed a bug in
XeprData
which would save y-axis and z-axis data files with the wrong byte-order. Ordinate data and x-axis data were not affected. Xepr expects data files to be saved with the byte-order specified in the DSC file (typically big-endian).Fixed a bug in
XeprData
when saving the ‘PolyCof’ parameter or other array data to DSC files: The array shape would be incorrectly saved in the header (with row and column numbers swapped).Fixed a deadlock when removing an item from the result queue.
Fixed an issue where the job status icons might not update until the user clicks on the CustomXepr window.
v2.3.1 (2019-04-23)¶
This release adds several options (keyword arguments) to CustomXepr functions. It also fully separates UI from non-UI modules.
Added:¶
Double click on a result in the GUI to plot it.
Enable editing of ordinate data in
XeprData
instance.Added a keyword argument
low_q
tocustomtune
to enable tuning with low Q-values (default:low_q=False
).Added a keyword argument
auto_gf
tosetTemperature
to disable or enable automatic gas flow control (default:auto_gf=True
).Added a keyword argument
htt_file
toheater_target
to select a file with a custom heater target table.
Changed:¶
Simplified access and modification of
XeprData
parameters. Parameter values can now be updated directly by assigning a value to their dictionary entry.Updated default heater target table for MercuryITC.
Log files older than 7 days are deleted automatically on startup.
Removed all Qt related dependencies from non-GUI modules. This makes it easier to run CustomXepr in headless mode from the command line.
Removed:¶
Deprecated
set_param
andget_param
methods ofXeprData
. Use thepars
attribute with dictionary type access instead.
v2.3.0 (2019-03-20)¶
This release focuses on under-the-hood improvements and provides significant speedups to the user interface (plotting data, deleting a large number of queued jobs, etc).
Changed:¶
Reduced the startup time when no instruments can be found.
Added info messages to the splash screen.
Switched plotting library for Mercury ITC and Keithley 2600 from Matplotlib to pyqtgraph. This allows for smoother user interactions with plots.
Performance improvements when deleting a large number of results or pending jobs: previously O(n^2), now O(n) performance.
Better organization of code into submodules.
Fixed:¶
Bug fixes for PyQt 5.12.
v2.2.2 (2019-02-19)¶
This release adds support for reading and writing Bruker Xepr data files in the BES3T format.
Added:¶
Added
XeprData
class to hold, read and save Xepr measurement data files.XeprData
provides methods to access and modify measurement parameters and to plot the data. It is compatible with all Xepr experiment types, saved in the Bruker BES3T file format up to version 1.2 (currently used by Xepr).
Changed:¶
runXeprExperiment
now accepts a path parameter. If given, the resulting data will be saved to the specified path, together with the last-measured Q-value and temperature set point.Tweaked icons in user interface.
Removed:¶
Removed the option to specify a title when saving an ESR data file. The file name is now always used as title.
saveCurrentData
will be removed in a future version of CustomXepr. Use thepath
keyword ofrunXeprExperiment
to save the measurement data instead.
v2.2.1 (2019-01-25)¶
This release introduces online documentation for CustomXepr and user includes interface improvements.
Added:¶
Job history now remains visible together with icons indicating the job status.
Documentation is now available at https://customxepr.readthedocs.io.
Changed:¶
Switched from custom TslSMTPHandler to python-bundled SMTPHandler for email notifications.
Improved docstrings.
v2.2.0 (2019-01-09)¶
Added:¶
Added terminal / command line script “CustomXepr”.
Added confidence interval for Q-value calculation in ModePicture class.
Window positions and sizes are saved and restored between sessions.
Show errors during job execution in GUI in addition to email notifications.
Nicely colored trace backs for error messages.
Changed:¶
CustomXepr is now distributed as a python package and can be installed with pip.
Fixed:¶
Fixed a bug that could result in values inside spin-boxes to be displayed without their decimal marker on some systems.
Fixed a bug that could result in crashes after closing the keithley or mercury control windows.
Removed:¶
Removed all ETA estimates for experiments.
v2.1.1¶
Added:¶
Included revamped keithleygui with IV sweep functionality.
Compatibility with Python 3.6 and higher.
Changed:¶
Proper disconnection from instruments when closing windows or shutting down the console with “exit” command.
Fixed:¶
Fixed a bug that would prevent Xepr experiments to run if the measurement time cannot be estimated. Applies for instance to rapid scan and time domain measurements where proper ETA estimates have not yet been implemented.
v2.1.0¶
Added:¶
Warnings when invalid file paths are handed to Xepr.
Changed:¶
Split off mercury_gui and keithley_gui as separate packages.
Removed:¶
Removed dark theme: code is easier to maintain. System level dark themes, such as macOS Mojave’s dark mode, may be supported in the future when Qt support is added.
v2.0.1¶
Changed:¶
Moved default driver backends from NI-VISA to pyvisa-py. It is no longer necessary to install NI-VISA from National Instruments on your system.
Moved drivers to external packages. Install with pip before first use.
Improved data plotting in Mercury user interface:
heater output and gas flow are plotted alongside the temperature
major speedups in plotting frame rate by relying on numpy for updating the data and redrawing only changed elements of plot widget
allow real-time panning and zooming of plots
Started working on Python 3 compatibility.