Source code for qcodes_contrib_drivers.drivers.OxfordInstruments.Triton

# This Python file uses the following encoding: utf-8
# Etienne Dumur <etienne.dumur@gmail.com>, october 2020
import os
from typing import Optional
import pandas as pd
import subprocess
import time


from qcodes.instrument.base import Instrument


[docs] class Triton(Instrument): """ This is the QCoDeS python driver to extract the temperature and pressure from a Oxford Triton fridge. """
[docs] def __init__(self, name: str, file_path: str, converter_path: str, threshold_temperature: float = 4, conversion_timer: float = 30, magnet: bool = False, **kwargs) -> None: """ QCoDeS driver for Oxford Triton fridges. ! This driver get parameters from the fridge log files. ! It does not interact with the fridge electronics. Since Oxford fridges use binary format for their log file "vcl", this driver convert vcl log files into csv files before returning fridge parameters. The conversion is done by using a binary file named "VCL_2_ASCII_CONVERTER.exe" that is provided by Oxford Instrument along with other binaries to handle the fridge log files. You must provide a valid path toward the VCL converter and consequently we advice users to make sure the converter is always reachable by the driver. Args: name: Name of the instrument. file_path: Path of the vcl log file. converter_path: Path of the vcl converter file. threshold_temperature: Threshold temperature of the mixing chamber thermometers. Defaults to 4K. Below, the temperature is read from the RuO2. Above, the temperature is read from the cernox. conversion_timer: Time between two vcl conversions. Defaults to 30s. magnet: Is there a magnet in the fridge. Default True. """ if not os.path.isfile(converter_path): raise ValueError('converter_path is not a valid file path.') if not os.path.isfile(file_path): raise ValueError('file_path is not a valid file path.') super().__init__(name=name, **kwargs) self.file_path = os.path.abspath(file_path) self.threshold_temperature = threshold_temperature self.converter_path = os.path.abspath(converter_path) self.conversion_timer = conversion_timer self._timer = time.time() self.add_parameter(name='pressure_condensation_line', unit='Bar', get_parser=float, get_cmd=lambda: self.get_pressure('condensation'), docstring='Pressure of the condensation line',) self.add_parameter(name='pressure_mixture_tank', unit='Bar', get_parser=float, get_cmd=lambda: self.get_pressure('tank'), docstring='Pressure of the mixture tank',) self.add_parameter(name='pressure_forepump_back', unit='Bar', get_parser=float, get_cmd=lambda: self.get_pressure('forepump'), docstring='Pressure of the forepump back',) self.add_parameter(name='temperature_50k_plate', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('50k'), docstring='Temperature of the 50K plate',) self.add_parameter(name='temperature_4k_plate', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('4k'), docstring='Temperature of the 4K plate',) if magnet: self.add_parameter(name='temperature_magnet', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('magnet'), docstring='Temperature of the magnet',) self.add_parameter(name='temperature_still', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('still'), docstring='Temperature of the still',) self.add_parameter(name='temperature_100mk', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('100mk'), docstring='Temperature of the 100mk plate',) self.add_parameter(name='temperature_mixing_chamber', unit='K', get_parser=float, get_cmd=lambda: self.get_temperature('mc'), docstring='Temperature of the mixing chamber',) self.connect_message()
[docs] def vcl2csv(self) -> Optional[str]: """ Convert vcl file into csv file using proprietary binary exe. The executable is called through the python subprocess library. To avoid to frequent file conversion, a timer of self.conversion_timer second is used. Returns: str: The output of the bash command """ conversion = False if self._timer+self.conversion_timer <= time.time(): conversion = True elif not os.path.isfile(self.file_path[:-3]+'txt'): conversion = True if conversion: self._timer = time.time() # Run a bash command to convert vcl into csv cp = subprocess.run([self.converter_path, self.file_path], stdout=subprocess.PIPE, universal_newlines=True, shell=True) return cp.stdout else: return None
[docs] def get_temperature(self, channel: str) -> float: """ Return the last registered temperature of the channel. Args: channel: Channel from which the temperature is extracted. Returns: temperature: Temperature of the channel in Kelvin. """ # Convert the vcl file into csv file self.vcl2csv() df = pd.read_csv(self.file_path[:-3]+'txt', delimiter="\t") if channel == '50k': return df.iloc[-1]['PT1 Plate T(K)'] elif channel == '4k': return df.iloc[-1]['PT2 Plate T(K)'] elif channel == 'magnet': return df.iloc[-1]['Magnet T(K)'] elif channel == 'still': return df.iloc[-1]['Still T(K)'] elif channel == '100mk': return df.iloc[-1]['100mK Plate T(K)'] elif channel == 'mc': # There are two thermometers for the mixing chamber. # Depending of the threshold temperature we return one or the other temp = df.iloc[-1]['MC cernox T(K)'] if temp > self.threshold_temperature: return temp else: return df.iloc[-1]['MC RuO2 T(K)'] else: raise ValueError('Unknown channel: '+channel)
[docs] def get_pressure(self, channel: str) -> float: """ Return the last registered pressure of the channel. Args: channel: Channel from which the pressure is extracted. Returns: pressure: Pressure of the channel in Bar. """ # Convert the vcl file into csv file self.vcl2csv() df = pd.read_csv(self.file_path[:-3]+'txt', delimiter="\t") if channel == 'condensation': return df.iloc[-1]['P2 Condense (Bar)'] elif channel == 'tank': return df.iloc[-1]['P1 Tank (Bar)'] elif channel == 'forepump': return df.iloc[-1]['P5 ForepumpBack (Bar)'] else: raise ValueError('Unknown channel: '+channel)