I’ve recently been developing some new NMR experiments in TopSpin. I’ve generated many datasets that require tedious processing. In this post, I’ll discuss how Python can be used to automate such tasks in TopSpin.
The older way to automate was to write AU programs, which are based on C. From a programming standpoint, this is cumbersome. Fortunately, we can use Python instead. TopSpin implements Python 2.7 using Jython. This implementation includes standard libraries (e.g.
random). The manual explains that you can also install third-party libraries, but there is no package manager, and hopefully this won’t be necessary for the kinds of basic scripts that I have in mind here.
To get started, use the
edpy command to open the Python editor. You can define new programs here or modify old ones, in a manner analogous to how you typically define pulse sequences. When you run a Python program, a separate thread launches. To terminate a running thread, use the
kill command and find the appropriate Python process.
Syntax and Commands
In addition to the usual Python 2.7 commands, which are all valid, a number of special TopSpin-specific commands have been defined. These new reserved words are always in capital case. Here are some of the most useful ones:
MSG(message, title): create a dialog box (user will have to click OK)
SHOW_STATUS(message): write a string to the TopSpin console
EXIT(): terminate the script
SLEEP(seconds): pause for the specified number of seconds
XCMD(cmd, wait=WAIT_TILL_DONE or NO_WAIT_TILL_DONE): run an arbitrary TopSpin command and wait (or don’t wait) until the command is finished
RE(dataset, show): Switch to the specified dataset.
datasetis a list of the form
[experiment_name, expno, procno, directory_name]. This command seems to work better than simpler calls like
XCMD(1)which can fail to work for some starting states.
value=GETPAR2(name): retrieve the value of the specified parameter from the current dataset
The Bruker PDF that describes Python automation in TopSpin contains a more comprehensive list of commands.
This script takes a series of pseudo-2D experiments, extracts the first spectrum from each one, computes the automatic phase correction, and applies this phase correction to the corresponding dataset.
experiment_name="my_experiment_name" directory_name="/opt/topspin4.0.5/data/kwaneu/nmr" procno="1" # switch to the specified experiment def recall(expno): RE([experiment_name, str(expno), procno, directory_name], show="yes") # keep track of which zero- and first-order phases got used phase0list= phase1list= # apply these processing commands to experiments 300-340 for exp in range(300,341): # switch to experiment and apply preliminary processing recall(exp) XCMD("1 SI 8") XCMD("2 BC_mod no") XCMD("PHC0 0") XCMD("PHC1 0") XCMD("xf2") # extract first row into a temporary dataset # and apply autophasing XCMD("rser 1") XCMD("apk") # this delay is necessary to allow autophasing # to complete; otherwise, errors occur SLEEP(1) # retrieve and store the optimized phases phase0 = float(GETPAR2("PHC0")) phase1 = float(GETPAR2("PHC1")) phase0list.append("%.0f" % phase0) phase1list.append("%.0f" % phase1) # close the temporary dataset XCMD("close") # open the original dataset again recall(exp) # apply the optimized phases XCMD("PHC0 %s" % phase0) XCMD("PHC1 %s" % phase1) XCMD("xf2") # tell the user we are done and print out the phases that got used MSG("%s\n\n%s" % (str(phase0list),str(phase1list)), "phasing complete")
Troubleshooting and Tips
- If you make a mistake in your script, the runtime errors will be reflected in a Java stack trace. This is pretty tedious to read, so if you want to be doing any complicated pure Python, I suggest testing that in a more typical Python environment first.
- Some TopSpin commands seem to ignore the
XCMDoption to wait until finished. For example, calling
XCMD("lock cdcl3")followed by
CMD("atma")can cause tuning to run at the same time. To avoid this, preface your commands with the
noqucommand. For example, use
XCMD("noqu lock cdcl3")and
XCMD("noqu atma")instead. You may also need to add some delays with the
- For complex scripts, I suggest logging to a file using the usual Python commands for writing strings to disk.
- After processing, I suggest further data analysis within a more modern Python environment via nmrglue, which can read processed data via