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,3 +1,15 @@
# -*- coding: utf-8 -*-
"""
sequence_fileformat
______________________
Version: 1.0
Authors: Davis Garrad (Paul Scherrer Institute, CH)
______________________
A basic system to generate Tecmag Sequence (.tps) files for reading by TNMR and sequence generation.
"""
# HEADER SYNTAX
# TODO: See if I can't get my name into this...
# PSEQ1.001.18 BIN
@@ -87,7 +99,7 @@
Z = '\x00' # for my sanity
event_codes = {
event_codes = { # These hold codes that TNMR uses to identify different events. I'm not sure as to what the black magic is governing them, but I took them from files TNMR generated.
'F1_Ampl': ('\x1f', 'P', 'E', '3', 'R', '\x08'), # F1
'F1_Ph': ('\x05', 'M', 'E', 'H', 'P', '\x02'),
'F1_PhMod': ('\x17', 'P', 'E', '3', 'P', '\x08'),
@@ -107,7 +119,8 @@ event_codes = {
}
event_types = list(event_codes.keys())
event_defaults = { 'F1_Ampl': 0, # F1
event_defaults = { # default values of each of the events, if nothing else is set.
'F1_Ampl': 0, # F1
'F1_PhMod': -1,
'F1_Ph': -1,
'F1_UnBlank': 0,
@@ -132,6 +145,18 @@ def fm(s, spacing=3):
return a
def get_info_header(filename, author, col_names, tuning_number, binary_name='PSEQ1.001.18 BIN'):
'''Creates a string which should be written (in binary format) to the top of a TNMR sequence file (.tps)
Parameters
----------
filename: str, the filename of the sequence file which will be written to (doesn't need to exist, just for TNMR to read)
author: str, the author of the sequence
col_names: list(str), a list of all the column names that will be in use in the sequence
tuning_number: str, the number of columns+1, in UTF-8 (i.e., it should be a single character. For 2 columns, tuning_number = '\x02')
binary_name: str, a code specifying which version of TNMR Sequence Editor generated this sequence. Best kept its default, PSEQ1.001.18 BIN
'''
headerstr = ''
headerstr += 'PSEQ1.001.18 BIN'
headerstr += fm(filename)
@@ -150,6 +175,13 @@ def get_info_header(filename, author, col_names, tuning_number, binary_name='PSE
return headerstr
def get_delay_header(col_delays, tuning_number):
'''Creates a string which should be written (in binary format) after the info header (see get_info_header()) of a TNMR sequence file (.tps). Specifies the delays of each column.
Parameters
----------
col_delays: list(float), a list of all the column delays that will be in use in the sequence. Ordered. In microseconds.
tuning_number: str, the number of columns+1, in UTF-8 (i.e., it should be a single character. For 2 columns, tuning_number = '\x02')
'''
headerstr = ''
headerstr += f'{tuning_number}{Z*3}\x01{Z*7}\x01{Z*3}\x01'
headerstr += Z*11
@@ -163,15 +195,15 @@ def get_delay_header(col_delays, tuning_number):
return headerstr
def get_event_header(event_type, vals, tables, table_reg, tuning_number, col_delays):
'''Generates the file information for the events section.
'''Generates the file information for the events section. This should come after the delay header (see get_delay_header())
Params
------
event_type: str describing the event
event_type: str describing the event (an element of event_types)
vals: an array of strs to be written.
tables: an array of dictionaries of table names to be written in format [ { '1D': None/str } (for col0), { '1D': None/str } (for col1) ... ]
table_reg: a dictionary of the table registry
tuning_number: the number of columns, minus 1
tuning_number: str, the number of columns+1, in UTF-8 (i.e., it should be a single character. For 2 columns, tuning_number = '\x02')
col_delays: the array of column delays
'''
codes = event_codes[event_type]
@@ -208,9 +240,6 @@ def get_event_header(event_type, vals, tables, table_reg, tuning_number, col_del
sweep = f'{freq}Hz'
filtr = f'{freq}Hz'
#sweep = '2500000.0Hz'
#filtr = '2500000.0Hz'
#dwell = '400.0n' # hard limit apparently...
headerstr += Z*52
headerstr += f'\x01{Z*3}' + fm(str(acq_points))
@@ -218,7 +247,7 @@ def get_event_header(event_type, vals, tables, table_reg, tuning_number, col_del
headerstr += fm(str(filtr))
headerstr += fm(str(dwell))
headerstr += fm(str(col_delays[i]))
headerstr += f'\x00{Z*5}' # I believe this is to link to dashboard... (set to zero or else it will just go to default)
headerstr += f'\x00{Z*5}' # This is to link to dashboard... (set to zero or else it will just go to dashboard default)
else:
if not(tables[i] in list(table_reg.keys())):
headerstr += Z*56
@@ -229,11 +258,11 @@ def get_event_header(event_type, vals, tables, table_reg, tuning_number, col_del
return headerstr
def get_table_spec(tables):
'''Generates the file information for a set of tables.
'''Generates the file information for a set of tables. This should go after the event section (see get_event_header())
Parameters
----------
tables: a dictionary of form { [table_name]: { 'values': '1 2 3', 'typestr': 'HP', 'start': 1 } }
tables: a dictionary of form { [table_name]: { 'values': '1 2 3', 'typestr': 'HP', 'start': 1 } }. typestr should be HP for phase, and you'll have to figure out what the other codes are. Start should almost always be 1.
'''
specstr = ''
specstr += Z*56
@@ -257,8 +286,8 @@ def generate_default_sequence(col_names, col_delays):
Parameters
----------
col_names: an iterable of each of the column titles
col_delays: an iterable of each of the column delay values.
col_names: an iterable of each of the column titles.
col_delays: an iterable of each of the column delay values. Should match the ordering of col_names
Returns
-------
@@ -274,12 +303,12 @@ def generate_default_sequence(col_names, col_delays):
return full_dict
def create_sequence_file(filename, data, author='NA'):
'''Generates a Tecmag sequence file for use in Tecmag NMR (TNMR).
'''Generates a Tecmag sequence file (.tps) for use in Tecmag NMR (TNMR). Combines header, delay, event, and table information to create a fully-readable file for TNMR.
Parameters
----------
filename: str
data: a dictionary in the form { 'columns': { [column_name_0]: { 'F1_Ampl': [value], ..., 'Rx_Blank': [value], 'Delay': [value] }, ... }, 'tables': { 'table_1': {...}, ... } }. If any sub-entries are empty, they will be given default values (requires that all event_types are present). See event_types and event_defaults.
filename: str, where to write this.
data: a dictionary in the form { 'columns': { [column_name_0]: { 'F1_Ampl': [value], ..., 'Rx_Blank': [value], 'Delay': [value] }, ... }, 'tables': { 'table_1': {...}, ... } }. If any sub-entries are empty, they will be given default values (requires that all event_types are present). See event_types and event_defaults. This is best generated using generate_default_sequence and then modifying the given sequence.
author [optional]: str to describe the file creator.
'''
content = ''