Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions src/simpyson/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def hz2ppm(hz, b0, nucleus, isotope_file=None):
isotope_file = os.path.join(dir, 'isotope_data.json')

isotope = int(''.join(filter(str.isdigit, nucleus)))
element = ''.join(filter(str.isalpha, nucleus)).upper()
element = ''.join(filter(str.isalpha, nucleus)).capitalize()
b0_unit = ''.join(filter(str.isalpha, b0)).lower()

with open(isotope_file) as f:
Expand All @@ -132,12 +132,16 @@ def hz2ppm(hz, b0, nucleus, isotope_file=None):
raise ValueError(f'Nucleus {nucleus} not found in isotope data.')

if b0_unit == 't':
b0_value = float(''.join(filter(str.isdigit, b0)))
ppm = hz / (b0_value * gamma)
b0_value = float(''.join(filter(lambda x: x.isdigit() or x == '.', b0)))
larm_freq = gamma * 1e7 * b0_value / (2 * np.pi * 1e6)
ppm = hz / np.abs(larm_freq)
elif b0_unit == 'mhz':
b0_value = float(''.join(filter(str.isdigit, b0)))
b0_value = float(''.join(filter(lambda x: x.isdigit() or x == '.', b0)))
gamma_h = data['H']['1']['Gamma']
ppm = hz / (b0_value/(gamma_h/gamma))
b0_value_T = 2 * np.pi * b0_value * 1e6 / (gamma_h * 1e7)
larm_freq = gamma * 1e7 * b0_value_T / (2 * np.pi * 1e6)
# ppm conversion requires absolute value of larm_freq
ppm = hz / np.abs(larm_freq)
else:
raise ValueError('B0 unit must be T or MHz.')

Expand Down Expand Up @@ -165,7 +169,7 @@ def ppm2hz(ppm, b0, nucleus, isotope_file=None):
isotope_file = os.path.join(dir, 'isotope_data.json')

isotope = int(''.join(filter(str.isdigit, nucleus)))
element = ''.join(filter(str.isalpha, nucleus)).upper()
element = ''.join(filter(str.isalpha, nucleus)).capitalize()
b0_unit = ''.join(filter(str.isalpha, b0)).lower()

with open(isotope_file) as f:
Expand All @@ -176,13 +180,16 @@ def ppm2hz(ppm, b0, nucleus, isotope_file=None):
raise ValueError(f'Nucleus {nucleus} not found in isotope data.')

if b0_unit == 't':
b0_value = float(''.join(filter(str.isdigit, b0)))
hz = ppm * (b0_value * gamma)
b0_value = float(''.join(filter(lambda x: x.isdigit() or x == '.', b0)))
larm_freq = gamma * 1e7 * b0_value / (2 * np.pi * 1e6)
elif b0_unit == 'mhz':
b0_value = float(''.join(filter(str.isdigit, b0)))
b0_value = float(''.join(filter(lambda x: x.isdigit() or x == '.', b0)))
gamma_h = data['H']['1']['Gamma']
hz = ppm * (b0_value/(gamma_h/gamma))
b0_value_T = 2 * np.pi * b0_value * 1e6 / (gamma_h * 1e7)
larm_freq = gamma * 1e7 * b0_value_T / (2 * np.pi * 1e6)
else:
raise ValueError('B0 unit must be T or MHz.')

hz = ppm * np.abs(larm_freq)

return hz
50 changes: 49 additions & 1 deletion src/simpyson/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ def create_menu(self):
convert_hz_to_ppm.triggered.connect(self.convert_hz_to_ppm)
process_menu.addAction(convert_hz_to_ppm)

convert_ppm_to_hz = QAction('Convert ppm to Hz', self)
convert_ppm_to_hz.triggered.connect(self.convert_ppm_to_hz)
process_menu.addAction(convert_ppm_to_hz)

convert_fid_to_spe = QAction('Convert FID to SPE', self)
convert_fid_to_spe.triggered.connect(self.convert_fid_to_spe)
process_menu.addAction(convert_fid_to_spe)
Expand Down Expand Up @@ -270,7 +274,7 @@ def convert_hz_to_ppm(self):
file_name = item.text()
file_data = self.files_data[file_name]['data']

if file_data and 'hz' in file_data.data: # Remove the format check
if file_data and 'hz' in file_data.data:
try:
new_data = copy.deepcopy(file_data)
new_data.b0 = b0
Expand All @@ -289,6 +293,50 @@ def convert_hz_to_ppm(self):

self.plot_data(selected_items)

def convert_ppm_to_hz(self):
selected_items = self.file_list.selectedItems()

if not selected_items:
QMessageBox.warning(self, 'Convert ppm to Hz', 'No file selected!')
return

b0, ok_b0 = QInputDialog.getText(self, 'Input', 'Enter B0 (e.g., 400MHz or 9.4T):')
if not (ok_b0 and b0):
return

nucleus, ok_nucleus = QInputDialog.getText(self, 'Input', 'Enter nucleus (e.g., 1H or 13C):')
if not (ok_nucleus and nucleus):
return

for item in selected_items:
file_name = item.text()
file_data = self.files_data[file_name]['data']

if file_data and 'ppm' in file_data.data:
try:
new_data = copy.deepcopy(file_data)
new_data.b0 = b0
new_data.nucleus = nucleus

ppm = new_data.data['ppm']
new_data.data['hz'] = ppm2hz(ppm, b0, nucleus)

# This is just an initial implementation
# Maybe one should implement a way to select on the GUI
# which range to show on the plot
if 'ppm' in new_data.data:
del new_data.data['ppm']

self.files_data[file_name]['data'] = new_data
if file_name == self.current_file:
self.data = new_data

except ValueError as e:
QMessageBox.warning(self, 'Convert ppm to Hz',
f"Error converting {file_name}: {str(e)}")

self.plot_data(selected_items)

def convert_fid_to_spe(self):
selected_items = self.file_list.selectedItems()

Expand Down
25 changes: 5 additions & 20 deletions src/simpyson/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ def _read_spe(self):
raise ValueError('Both B0 and nucleus must be specified.')
else:
dir = os.path.dirname(os.path.realpath(__file__))
isotope_file = os.path.join(dir, 'isotope_data.json')
with open(self.filename) as f:
data_sec = False
real = []
Expand All @@ -95,25 +94,11 @@ def _read_spe(self):
imag = np.array(imag)
hz = np.array(hz)

isotope = int(''.join(filter(str.isdigit, self.nucleus)))
element = ''.join(filter(str.isalpha, self.nucleus)).capitalize()

b0_unit = ''.join(filter(str.isalpha, self.b0)).lower()

with open(isotope_file) as f:
data = json.load(f)
gamma = data[element][str(isotope)]['Gamma']

if b0_unit == 't':
b0 = int(''.join(filter(str.isdigit, self.b0)))
ppm = hz / (b0 * gamma)
elif b0_unit == 'mhz':
b0 = int(''.join(filter(str.isdigit, self.b0)))
gamma_h = data['H']['1']['Gamma']
ppm = hz / (b0/(gamma_h/gamma))
else:
raise ValueError('B0 unit must be T or MHz.')
self.data = {'real': real, 'imag': imag, 'np': np_value, 'sw': sw, 'hz': hz, 'ppm': ppm}
try:
ppm = hz2ppm(hz, self.b0, self.nucleus)
self.data = {'real': real, 'imag': imag, 'np': np_value, 'sw': sw, 'hz': hz, 'ppm': ppm}
except ValueError as e:
print(f"Error converting to ppm: {e}")

def _read_fid(self):
"""
Expand Down
Loading