TNMR updates: workaround for the hardware module error. Added more dashboard support. Added class definition auto-generated by pycom (NTNMR.py)

This commit is contained in:
2025-06-30 13:55:21 +02:00
parent 388748c995
commit 10acd4a188
5 changed files with 1687 additions and 17 deletions

View File

@@ -15,8 +15,12 @@ TEMPLATE_FILE_PATH = os.path.dirname(os.path.realpath(__file__)) + '/templates/'
import win32com.client
import pythoncom
import frappy_psi.tnmr.NTNMR as NTNMR
import time
import json
import traceback
import threading
class TNMRNotRunnningError(Exception):
def __init__(self, msg=None):
@@ -88,7 +92,7 @@ class TNMR:
if filepath != "":
print(f'Loading file {filepath}')
ntnmr.OpenFile(filepath)
self.ACTIVEFILE = ntnmr.GetActiveDocPath
self.ACTIVEFILE = ntnmr.GetActiveDocPath()
self.ACTIVEPATH = os.path.dirname(self.ACTIVEFILE)
print(f'Active file: {self.ACTIVEFILE} in path {self.ACTIVEPATH}')
@@ -122,17 +126,17 @@ class TNMR:
ntnmr = self.get_instance()
ntnmr.OpenFile(filepath)
if active:
self.ACTIVEFILE = 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.get_instance().GetActiveDocPath
self.ACTIVEFILE = self.get_instance().GetActiveDocPath()
self.ACTIVEPATH = os.path.dirname(self.ACTIVEFILE)
print(f'Active file: {self.ACTIVEFILE} in path {self.ACTIVEPATH}')
def ZeroGo(self, lock = True, interval = 0.5):
def ZeroGo(self, lock = True, interval = 0.5, check_time=10):
""" If possible, zeros and starts acquisition
Parameters
@@ -141,19 +145,79 @@ class TNMR:
if true, program waits until acquisition is done
interval: float
how often to check if acquisition done
check_time: float
how many seconds until not recieving new data is considered grounds for another Zero-Go attempt. Recommended to set as at least the length of 2-3 pulse sequences.
"""
# for some reason CheckAcquisition is False while an experiment is
# running but true otherwise
CHECK_MODE = 'thread' # thread OR data
print('Zero-going...')
ntnmr = self.get_instance()
if not(self.acquisition_running()):
ntnmr.Reset # to avoid hardware issues?
ntnmr.ZG
print('Reset')
ntnmr.Reset() # to avoid hardware issues? EDIT: Doesn't seem to do much...
if(CHECK_MODE == 'data'):
print('Artificially setting the zeroth point to NULL for error detection.')
ntnmr.SetDataPoint(1, [0,0])
print('ZG')
try:
def t(s):
print('\nStart ZG lambda')
try:
s.get_instance().ZeroAndGo()
except:
print('\nException in ZG lambda')
pass
print('\nCompletion of ZG lambda')
return
thread = threading.Thread(target=t, args=(self,))
thread.start()
except:
traceback.print_exc()
print('ZG completed')
else:
print('An Acquisition is already running')
print('An acquisition is already running')
if(CHECK_MODE == 'data'):
elapsed = 0
print('Waiting to recieve real data')
while(True):
try:
d = ntnmr.GetData()
if not(d is None):
if(d[0] != 0):
break
except:
traceback.print_exc()
time.sleep(0.1)
elapsed += 0.1
print(f'\rElapsed: {elapsed:.1f}s/{check_time:.1f}s', end='')
if(elapsed > check_time): # broken
print('\nTimeout! No data!')
ntnmr.Abort()
self.ZeroGo(lock=lock, interval=interval, check_time=check_time)
break
print('\n')
elif(CHECK_MODE == 'thread'):
print('Giving ZeroGo command a grace period to terminate...')
elapsed = 0.0
while(elapsed < 2.0):
if not(thread.is_alive()):
print('\nZeroGo terminated in time. Continuing...', end='')
break
time.sleep(0.1)
elapsed += 0.1
print(f'\rElapsed: {elapsed:.1f}s/2.0s', end='')
print('\n')
if(thread.is_alive()): # technically possible that it dies at the verrrry last moment, so may as well add an if-condition. What can I say? I'm merciful.
print('ZeroGo did not terminate. This is a sign of an error. Retrying...')
# the thread still hasn't died - this is a sign that the ZeroGo got caught up with some sort of error. Abandon, and retry.
ntnmr.Abort()
self.ZeroGo(lock=lock, interval=interval, check_time=check_time)
if lock:
print("Application locked during acquisition\n...waiting...")
print("Application locked during acquisition. 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.
@@ -168,7 +232,7 @@ class TNMR:
False: if not running
"""
ntnmr = self.get_instance()
res = not(ntnmr.CheckAcquisition)
res = not(ntnmr.CheckAcquisition())
return res
def get_data(self):
@@ -178,7 +242,7 @@ class TNMR:
-------
a tuple of ([real_array], [imaginary_array])
'''
raw_data = self.get_instance().GetData
raw_data = self.get_instance().GetData()
reals = raw_data[::2]
imags = raw_data[1::2]
@@ -314,7 +378,7 @@ class TNMR:
ntnmr = self.get_instance()
print(f'Loading sequence at {filename}')
ntnmr.CloseActiveFile
ntnmr.CloseActiveFile()
success = ntnmr.OpenFile(TEMPLATE_FILE_PATH + 'tmp.tnt')
if(success):
print('Template file reloaded')