-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtopspin_api.py
More file actions
284 lines (216 loc) · 9.2 KB
/
topspin_api.py
File metadata and controls
284 lines (216 loc) · 9.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
"""
TopSpin Python API Wrapper
This module provides a Python interface to control TopSpin NMR software,
specifically for opening and manipulating pulse sequence files.
Author: TopSpin Python API Wrapper
License: See TopSpin license
"""
import os
import sys
from pathlib import Path
from typing import Optional, Union
# Add TopSpin Python directory to path for importing the API
TOPSPIN_DEFAULT_PATH = "D:/topspin"
class TopSpinAPI:
"""
Wrapper class for TopSpin NMR software Python API.
This class provides methods to interact with TopSpin, including
opening pulse sequence files and executing TopSpin commands.
"""
def __init__(self, topspin_path: Optional[Union[str, Path]] = None):
"""
Initialize the TopSpin API wrapper.
Args:
topspin_path: Path to TopSpin installation directory.
Defaults to D:/topspin.
"""
self._topspin_path = Path(topspin_path) if topspin_path else Path(TOPSPIN_DEFAULT_PATH)
if not self._topspin_path.exists():
raise FileNotFoundError(
f"TopSpin installation not found at: {self._topspin_path}\n"
f"Please provide the correct TopSpin installation path."
)
# Add TopSpin Python to sys.path for importing the API
python_path = self._topspin_path / "python"
if python_path.exists():
if str(python_path) not in sys.path:
sys.path.insert(0, str(python_path))
# Import TopSpin API
try:
from bruker.api.topspin import Topspin
self._topspin = Topspin()
except ImportError as e:
raise ImportError(
f"Failed to import TopSpin API. Error: {e}\n"
f"Please ensure bruker_nmr_api is installed. "
f"Install with: uv pip install {self._topspin_path}/python/examples/bruker_nmr_api-*.whl"
)
self._data_provider = self._topspin.getDataProvider()
def get_version(self) -> str:
"""Get TopSpin version."""
return self._topspin.getVersion()
def get_installation_directory(self) -> str:
"""Get TopSpin installation directory."""
return self._topspin.getInstallationDirectory()
def open_pulse_sequence(self, pulse_sequence_path: Union[str, Path]) -> bool:
"""
Open a pulse sequence file in TopSpin.
This method opens a pulse sequence file in TopSpin using the 'edpul' command.
The pulse sequence file can be specified as an absolute or relative path.
Args:
pulse_sequence_path: Path to the pulse sequence file (.pulse extension).
Returns:
True if successful, False otherwise.
Raises:
FileNotFoundError: If the pulse sequence file does not exist.
Example:
>>> api = TopSpinAPI()
>>> api.open_pulse_sequence("D:/topspin/exp/stu/expnam/pulseprogram")
"""
pulse_path = Path(pulse_sequence_path)
if not pulse_path.exists():
raise FileNotFoundError(f"Pulse sequence file not found: {pulse_path}")
# Try to open the pulse sequence using TopSpin's edpul command
try:
# Get current dataset (if any)
current_dataset = self._data_provider.getCurrentDataset()
if current_dataset is None:
# If no dataset is open, we can't open a pulse sequence in context
# Try to open the pulse sequence file directly using TopSpin's file opening
print(f"No dataset open. Pulse sequence file: {pulse_path}")
print("To edit a pulse sequence, open a dataset first or use the full path.")
return False
# Open pulse sequence using the edpul command
# This opens the pulse sequence editor for the current experiment
result = current_dataset.launch(f"edpul {pulse_path}")
print(f"Pulse sequence opened: {pulse_path}")
return True
except Exception as e:
print(f"Error opening pulse sequence: {e}")
return False
def open_pulse_sequence_in_experiment(
self,
experiment_path: Union[str, Path],
pulse_sequence_name: str = "pulseprogram"
) -> bool:
"""
Open a pulse sequence for a specific experiment.
This method opens a pulse sequence file associated with an experiment.
The pulse sequence is typically named 'pulseprogram' in the experiment directory.
Args:
experiment_path: Path to the experiment directory.
pulse_sequence_name: Name of the pulse sequence file (default: "pulseprogram").
Returns:
True if successful, False otherwise.
Raises:
FileNotFoundError: If the experiment or pulse sequence file does not exist.
Example:
>>> api = TopSpinAPI()
>>> api.open_pulse_sequence_in_experiment("D:/topspin/exp/stu/expnam")
"""
exp_path = Path(experiment_path)
if not exp_path.exists():
raise FileNotFoundError(f"Experiment directory not found: {exp_path}")
# Construct path to pulse sequence file
pulse_path = exp_path / pulse_sequence_name
if not pulse_path.exists():
raise FileNotFoundError(f"Pulse sequence file not found: {pulse_path}")
# Load the experiment data
try:
experiment = self._data_provider.getNMRData(str(exp_path))
# Open pulse sequence using edpul command
experiment.launch(f"edpul {pulse_path}")
print(f"Pulse sequence opened for experiment: {exp_path}")
print(f"Pulse sequence file: {pulse_path}")
return True
except Exception as e:
print(f"Error opening pulse sequence for experiment: {e}")
return False
def execute_topspin_command(self, command: str) -> bool:
"""
Execute a TopSpin command.
Args:
command: TopSpin command string to execute.
Returns:
True if successful, False otherwise.
Example:
>>> api = TopSpinAPI()
>>> api.execute_topspin_command("wrp 2 y")
"""
try:
current_dataset = self._data_provider.getCurrentDataset()
if current_dataset is None:
print("No dataset open. Cannot execute command.")
return False
result = current_dataset.launch(command)
print(f"Command executed: {command}")
return True
except Exception as e:
print(f"Error executing command: {e}")
return False
def get_current_dataset_info(self) -> Optional[dict]:
"""
Get information about the current dataset.
Returns:
Dictionary with dataset information or None if no dataset is open.
"""
try:
current_dataset = self._data_provider.getCurrentDataset()
if current_dataset is None:
return None
identifier = current_dataset.getIdentifier()
return {
"identifier": identifier,
"path": str(identifier),
}
except Exception as e:
print(f"Error getting current dataset info: {e}")
return None
def open_experiment(self, experiment_path: Union[str, Path]) -> bool:
"""
Open an experiment in TopSpin.
Args:
experiment_path: Path to the experiment directory.
Returns:
True if successful, False otherwise.
Example:
>>> api = TopSpinAPI()
>>> api.open_experiment("D:/topspin/examdata/Cyclosporine/1")
"""
try:
experiment = self._data_provider.getNMRData(str(experiment_path))
# Show the dataset in TopSpin display
self._topspin.getDisplay().show(experiment)
print(f"Experiment opened: {experiment_path}")
return True
except Exception as e:
print(f"Error opening experiment: {e}")
return False
def main():
"""Example usage of TopSpinAPI."""
# Initialize TopSpin API
print("Initializing TopSpin API...")
api = TopSpinAPI(topspin_path="D:/topspin")
try:
print(f"TopSpin version: {api.get_version()}")
print(f"TopSpin installation: {api.get_installation_directory()}")
except Exception as e:
print(f"Note: Could not connect to running TopSpin instance.")
print(f"Error: {e}")
print("\nIMPORTANT: TopSpin must be RUNNING to use the Python API.")
print("Please start TopSpin first, then run this script.")
return
# Get current dataset info
dataset_info = api.get_current_dataset_info()
if dataset_info:
print(f"Current dataset: {dataset_info}")
else:
print("No dataset currently open.")
# Example: Open a pulse sequence
# Uncomment and modify to use:
# api.open_pulse_sequence("D:/topspin/exp/stu/expnam/pulseprogram")
# Example: Open pulse sequence for an experiment
# Uncomment and modify to use:
# api.open_pulse_sequence_in_experiment("D:/topspin/examdata/Cyclosporine/1")
if __name__ == "__main__":
main()