Fixed hardware issue?

This commit is contained in:
2025-06-24 11:35:32 +02:00
parent 2fce39c381
commit 388748c995
4 changed files with 216 additions and 157 deletions

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
TNMR_DG_Extension
tnmr_interface
______________________
Version: 1.0
@@ -30,12 +30,17 @@ class TNMR:
Instance Attributes
-------------------
NMTNR: win32com object
ACTIVEFILE: str
path to active TNMR file
ACTIVEPATH: str
path to active TNMR file's parent directory.
Methods
-------
get_instance():
Gets an instance of the NTNMR "API". Best to use this rather than keep an object, as threads can mess with the usefulness of an object.
execute_cmd(cmd):
Sends an arbitrary command to the TNMR software. Best for debugging.
openfile(filepath: str, active: bool):
opens the tnt file specified by filepath
if active is true, the newly opened file will be set to ACTIVEFILE
@@ -47,8 +52,28 @@ class TNMR:
the acqusition endswith
acquisition_running():
returns the acquisition status of TNMR
get_data():
Pulls the currently loaded data from TNMR and returns it.
save_file(filepath=''):
Saves the experiment to a file
set_nmrparameter(param_name: str, value: str):
If it exists, sets an NMR parameter
get_nmrparameter(param_name: str):
If it exists, returns the value of an NMR parameter
is_nmrparameter(param_name: str):
Checks if an NMR parameter exists.
get_all_nmrparameters():
Returns all possible NMR parameters in the dashboard.
get_page_parameters(page):
Returns all possible NMR parameters on a page of the dashboard.
load_sequence(filename):
WARNING: POSSIBLY DESTRUCTIVE. ENSURE DATA IS SAVED BEFORE CALLING.
Loads a sequence (and reloads the template dashboard) into the TNMR software.
load_dashboard(dashboard_fn):
Loads a dashboard (resetting parameters) into TNMR.
"""
def __init__(self, filepath = "", NTNMR_inst=None):
def __init__(self, filepath = ""):
""" Creates an instance of the NTNMR class, which is used to communicate with TNMR,
Tecmags control software. Basically a wrapper for TNMRs api
@@ -57,27 +82,18 @@ class TNMR:
filepath: specifies a path to the file tnt you want to use
"""
#first we check if an instance of TNMR is running an get it or create it
if(NTNMR_inst is None):
print('Opening new TNMR connection')
self.reset_NTNMR_instance()
else:
self.NTNMR = NTNMR_inst
print('Opening new TNMR connection')
ntnmr = self.get_instance()
# next we open a specified file. If none is specified, then we use the active file
if filepath != "":
print(f'Loading file {filepath}')
self.NTNMR.OpenFile(filepath)
self.ACTIVEFILE = self.NTNMR.GetActiveDocPath
ntnmr.OpenFile(filepath)
self.ACTIVEFILE = ntnmr.GetActiveDocPath
self.ACTIVEPATH = os.path.dirname(self.ACTIVEFILE)
print(f'Active file: {self.ACTIVEFILE} in path {self.ACTIVEPATH}')
def reset_NTNMR_instance(self):
try:
pythoncom.CoInitialize()
self.NTNMR = win32com.client.GetActiveObject("NTNMR.Application")
except pythoncom.com_error:
raise TNMRNotRunnningError
def get_instance(self):
'''Tries to open up a Windows COM connection to the TNMR program, and returns an instance if able'''
try:
pythoncom.CoInitialize()
return win32com.client.GetActiveObject("NTNMR.Application")
@@ -85,9 +101,10 @@ class TNMR:
raise TNMRNotRunnningError
def execute_cmd(self, cmd):
print('W: Executing arbitrary command: ' + f'out = self.NTNMR.{cmd}')
'''Sends an arbitrary command through to TNMR'''
print('W: Executing arbitrary command: ' + f'out = self.get_instance().{cmd}')
out = 0
exec(f'out = self.NTNMR.{cmd}\nprint("W: OUTPUT: " + str(out))')
exec(f'out = self.get_instance().{cmd}\nprint("W: OUTPUT: " + str(out))')
return out
def openfile(self, filepath, active = True):
@@ -102,15 +119,16 @@ class TNMR:
active: bool
"""
print(f'Opening file {filepath}')
self.NTNMR.OpenFile(filepath)
ntnmr = self.get_instance()
ntnmr.OpenFile(filepath)
if active:
self.ACTIVEFILE = self.NTNMR.GetActiveDocPath
self.ACTIVEFILE = ntnmr.GetActiveDocPath
print(f'Active file: {self.ACTIVEFILE} in path {self.ACTIVEPATH}')
def set_activefile(self):
""" Sets TNMR active doc path to ACTIVEFILE
"""
self.ACTIVEFILE = self.NTNMR.GetActiveDocPath
self.ACTIVEFILE = self.get_instance().GetActiveDocPath
self.ACTIVEPATH = os.path.dirname(self.ACTIVEFILE)
print(f'Active file: {self.ACTIVEFILE} in path {self.ACTIVEPATH}')
@@ -129,6 +147,7 @@ class TNMR:
print('Zero-going...')
ntnmr = self.get_instance()
if not(self.acquisition_running()):
ntnmr.Reset # to avoid hardware issues?
ntnmr.ZG
else:
print('An Acquisition is already running')
@@ -137,6 +156,7 @@ class TNMR:
print("Application locked during acquisition\n...waiting...")
while self.acquisition_running():
time.sleep(interval)
# TODO: https://stackoverflow.com/questions/27586411/how-do-i-close-window-with-handle-using-win32gui-in-python to close any tecmag dialogues that show up. Need to determine proper search string, so next time it pops up, run some tests.
print("Acquisition done")
def acquisition_running(self):
@@ -147,34 +167,22 @@ class TNMR:
True: if running
False: if not running
"""
#try:
ntnmr = self.get_instance()
res = not(ntnmr.CheckAcquisition)
#except AttributeError as e:
# if(e
# res = False
return res
def get_data(self):
'''Pulls data from TNMR
Returns
-------
a tuple of ([real_array], [imaginary_array])
'''
raw_data = self.get_instance().GetData
reals = raw_data[::2]
imags = raw_data[1::2]
return (reals, imags)
def get_data_times(self):
#acq_n = int(self.NTNMR.GetNMRParameter('Acq. Points')) # TODO: These do NOT return the actual used values!
#acq_t = self.NTNMR.GetNMRParameter('Acq. Time')
#acq_t = acq_t.strip()
#if(acq_t[-1] == 'm'):
# acq_t = float(acq_t[:-1]) * 1000
#elif(acq_t[-1] == 'u'):
# acq_t = float(acq_t[:-1])
#elif(acq_t[-1] == 'n'):
# acq_t = float(acq_t[:-1]) / 1000
acq_t = 204.8 # us
acq_n = 1024
return [ i * (acq_t / (acq_n - 1)) for i in range(0, acq_n+1) ]
def save_file(self, filepath=''):
""" Save file to filepath. if no filepath specified, save current active file
@@ -244,9 +252,6 @@ class TNMR:
try:
self.get_instance().GetNMRParameter(param_name)
return True
except AttributeError:
self.reset_NTNMR_instance()
return self.is_nmrparameter(param_name)
except:
return False
@@ -341,6 +346,16 @@ class TNMR:
return True
def load_dashboard(self, dashboard_fn):
'''Loads a dashboard into TNMR. Resets the parameters to those in the dashboard file, despite what the TNMR documentation says.
Parameters
----------
filename: str, designates the dashboard to load
Returns
-------
A success flag - beware; sometimes, this can fail and still provide a false positive. False negatives, as far as I'm aware, never happen, though, so feel free to rely on that.
'''
print(f'I: Loading dashboard setup from {dashboard_fn}')
success = self.get_instance().LoadParameterSetupFromFile(dashboard_fn)