140 lines
6.5 KiB
Python
140 lines
6.5 KiB
Python
import os
|
|
from glob import glob
|
|
from pathlib import Path
|
|
from configparser import ConfigParser
|
|
from frappy.errors import ConfigError
|
|
|
|
|
|
class Rack:
|
|
configbase = Path('/home/l_samenv/.config/frappy_instruments')
|
|
|
|
def __init__(self, modfactory, **kwds):
|
|
self.modfactory = modfactory
|
|
instpath = self.configbase / os.environ['Instrument']
|
|
sections = {}
|
|
self.config = {}
|
|
files = glob(str(instpath / '*.ini'))
|
|
for filename in files:
|
|
parser = ConfigParser()
|
|
parser.optionxform = str
|
|
parser.read([filename])
|
|
for section in parser.sections():
|
|
prev = sections.get(section)
|
|
if prev:
|
|
raise ConfigError(f'duplicate {section} section in {filename} and {prev}')
|
|
sections[section] = filename
|
|
self.config.update(parser.items(section))
|
|
if 'rack' not in sections:
|
|
raise ConfigError(f'no rack found in {instpath}')
|
|
self.props = {} # dict (<property>, <method>) of value
|
|
self.mods = {} # dict (<property>, <method>) of list of <cfg>
|
|
|
|
def set_props(self, mod, **kwds):
|
|
for prop, method in kwds.items():
|
|
value = self.props.get((prop, method))
|
|
if value is None:
|
|
# add mod to the list of cfgs to be fixed
|
|
self.mods.setdefault((prop, method), []).append(mod)
|
|
else:
|
|
# set prop in current module
|
|
if not mod.get(prop): # do not override given and not empty property
|
|
mod[prop] = value
|
|
|
|
def fix_props(self, method, **kwds):
|
|
for prop, value in kwds.items():
|
|
if (prop, method) in self.props:
|
|
raise ConfigError(f'duplicate call to {method}()')
|
|
self.props[prop, method] = value
|
|
# set property in modules to be fixed
|
|
for mod in self.mods.get((prop, method), ()):
|
|
mod[prop] = value
|
|
|
|
def lakeshore(self, ls_uri=None, io='ls_io', dev='ls', model='336', **kwds):
|
|
Mod = self.modfactory
|
|
self.fix_props('lakeshore', io=io, device=dev)
|
|
self.ls_model = model
|
|
self.ls_dev = dev
|
|
ls_uri = ls_uri or self.config.get('ls_uri')
|
|
Mod(io, cls=f'frappy_psi.lakeshore.IO{self.ls_model}',
|
|
description='comm. to lakeshore in cc rack', uri=ls_uri)
|
|
self.dev = Mod(dev, cls=f'frappy_psi.lakeshore.Device{self.ls_model}',
|
|
description='lakeshore in cc rack', io=io, curve_handling=True)
|
|
|
|
def sensor(self, name, channel, calcurve, **kwds):
|
|
Mod = self.modfactory
|
|
kwds.setdefault('cls', f'frappy_psi.lakeshore.Sensor{self.ls_model}')
|
|
kwds.setdefault('description', f'T sensor {name}')
|
|
mod = Mod(name, channel=channel, calcurve=calcurve,
|
|
device=self.ls_dev, **kwds)
|
|
self.set_props(mod, io='lakeshore', dev='lakeshore')
|
|
|
|
def loop(self, name, channel, calcurve, output_module, **kwds):
|
|
Mod = self.modfactory
|
|
kwds.setdefault('cls', f'frappy_psi.lakeshore.Loop{self.ls_model}')
|
|
kwds.setdefault('description', f'T loop {name}')
|
|
Mod(name, channel=channel, calcurve=calcurve, output_module=output_module,
|
|
device=self.ls_dev, **kwds)
|
|
self.fix_props(f'heater({output_module})', description=f'heater for {name}')
|
|
|
|
def heater(self, name, output_no, max_heater, resistance, **kwds):
|
|
Mod = self.modfactory
|
|
if output_no == 1:
|
|
kwds.setdefault('cls', f'frappy_psi.lakeshore.MainOutput{self.ls_model}')
|
|
elif output_no == 2:
|
|
kwds.setdefault('cls', f'frappy_psi.lakeshore.SecondaryOutput{self.ls_model}')
|
|
else:
|
|
return
|
|
kwds.setdefault('description', '')
|
|
mod = Mod(name, max_heater=max_heater, resistance=resistance, **kwds)
|
|
self.set_props(mod, io='lakeshore', device='lakeshore', description=f'heater({name})')
|
|
|
|
def ccu(self, ccu_uri=None, ccu_io='ccu_io', he=None, n2=None, **kwds):
|
|
Mod = self.modfactory
|
|
self.ccu_io = ccu_io
|
|
ccu_uri = ccu_uri or self.config.get('ccu_uri')
|
|
# self.devname = ccu_devname
|
|
Mod(ccu_io, 'frappy_psi.ccu4.IO',
|
|
'comm. to CCU4', uri=ccu_uri)
|
|
if he:
|
|
if not isinstance(he, str): # e.g. True
|
|
he = 'He_lev'
|
|
Mod(he, cls='frappy_psi.ccu4.HeLevel',
|
|
description='the He Level', io=self.ccu_io)
|
|
if n2:
|
|
if isinstance(n2, str):
|
|
n2 = n2.split(',')
|
|
else: # e.g. True
|
|
n2 = []
|
|
n2, valve, upper, lower = n2 + ['N2_lev', 'N2_valve', 'N2_upper', 'N2_lower'][len(n2):]
|
|
print(n2, valve, upper, lower)
|
|
Mod(n2, cls='frappy_psi.ccu4.N2Level',
|
|
description='the N2 Level', io=ccu_io,
|
|
valve=valve, upper=upper, lower=lower)
|
|
Mod(valve, cls='frappy_psi.ccu4.N2FillValve',
|
|
description='LN2 fill valve', io=ccu_io)
|
|
Mod(upper, cls='frappy_psi.ccu4.N2TempSensor',
|
|
description='upper LN2 sensor')
|
|
Mod(lower, cls='frappy_psi.ccu4.N2TempSensor',
|
|
description='lower LN2 sensor')
|
|
|
|
def hepump(self, hepump_uri=None, hepump_type=None, hepump_io='hepump_io',
|
|
hepump='hepump', hepump_mot='hepump_mot', hepump_valve='hepump_valve',
|
|
flow_sensor='flow_sensor', pump_pressure='pump_pressure', nv='nv',
|
|
ccu_io='ccu_io', **kwds):
|
|
Mod = self.modfactory
|
|
hepump_type = hepump_type or self.config.get('hepump_type', 'no')
|
|
Mod(nv, 'frappy_psi.ccu4.NeedleValveFlow', 'flow from flow sensor or pump pressure',
|
|
flow_sensor=flow_sensor, pressure=pump_pressure, io=ccu_io)
|
|
Mod(pump_pressure, 'frappy_psi.ccu4.Pressure', 'He pump pressure', io=ccu_io)
|
|
if hepump_type == 'no':
|
|
print('no pump, no flow meter - using flow from pressure alone')
|
|
return
|
|
hepump_uri = hepump_uri or self.config['hepump_uri']
|
|
Mod(hepump_io, 'frappy.io.BytesIO', 'He pump connection', uri=hepump_uri)
|
|
Mod(hepump, 'frappy_psi.hepump.HePump', 'He pump', pump_type=hepump_type,
|
|
valvemotor=hepump_mot, valve=hepump_valve, flow=nv)
|
|
Mod(hepump_mot, 'frappy_psi.hepump.Motor', 'He pump valve motor', io=hepump_io, maxcurrent=2.8)
|
|
Mod(hepump_valve, 'frappy_psi.butterflyvalve.Valve', 'He pump valve', motor=hepump_mot)
|
|
Mod(flow_sensor, 'frappy_psi.sensirion.FlowSensor', 'Flow Sensor', io=hepump_io, nsamples=160)
|
|
|