i like this post (click again to cancel)
i dont like this post (click again to cancel) remove favorite mark from this question (click again to restore mark)


I am a German chemistry Bachelor student (beginning my Master studies in October) and as a spare-time hobby I would like to write an NMR processing program. I would like to release it as free open source software (GPL) written in C++ with a Qt frontend, so that it is platform independent.

As a starting point for writing the libraries to read and transform the vendor data (currently only Bruker) I used the SpinWorks libraries released by Dr Marat (many thanks to him):


I ported and modified this code to C++/Qt. Reading and transforming Bruker data works so far, but unfortunately the produced spectra suffer from severe distortions (extreme "noise"). I uploaded a graph of the data output that I plotted using Origin:


Here is a screenshot of the spectrum processed with SpinWorks (how it should look like):


I've been looking through the code for days now but I just can't find my mistake. I also uploaded the code:


All files for compiling the program are included. It runs on the console and is not very user friendly because I first wanted to "prove" that it can produce a useful spectrum before I go on coding any further. The path to the acqus and fid files are hard coded in the main.cpp, but I commented the code as best as I could so it should be easy to make it run. The sample data I used for the above pictures are also included (acqus and fid).

I would be very happy if someone could tell what my mistake is. Maybe the experts already see it by just looking at the spectrum. If you have any question concerning the code or the compilation, feel free to ask.

Since I really don't know how to go on, I'm desperate for any help.

Thank you very much in advance.

asked Aug 03 '10 at 06:55

Pascal%20Fricke's gravatar image

Pascal Fricke

updated Aug 03 '10 at 09:33

Hi Pascal, I would adjust the title to reflect that you are trying to write code. People often decide to read something or not just based on the title. - Evgeny Fadeev (Aug 03 '10 at 09:05)

Thank you for the advice. I hope the new title is better :) - Pascal Fricke (Aug 03 '10 at 09:35)

I want to host the project on GitHub or similar, but actually I wanted to wait until at least *something* can successfully be done with the program. It even doesn't have a name yet. But if it makes things easier to solve my "distortion problem" I will try to upload it to a source hoster. - Pascal Fricke (Aug 03 '10 at 13:51)

well, at least you will gain a ton just by using revision control and regular backups. - Evgeny Fadeev (Aug 03 '10 at 14:30)

3 Answers:
i like this answer (click again to cancel)
i dont like this answer (click again to cancel)

Just guessing here - since data looks largely like noise - you might be reading starting incorrect byte or your reading of numbers may be shifted with respect to the data point boundaries or you might have incorrect byte order (little-endian vs. big-endian).

Maybe you can take a step back and look at the FID after reading it from the source and compare it to what you see in spinworks or other software.

edit maybe you can try creating a synthetic fid where all points have the same non-zero value. Then read the data and see what numbers you get. That may give you some hints. You can also compare the real data offset as you read with the expected offset - based on what you know from the data format.

by offset I mean "byte distance" from the beginning of the file up to the point from where you read. basically that you are getting wrong numbers means that either you are reading them from wrong locations within file, or you have reversed byte order or you might be mis-interpreting format of storage of the numerical data (float/double/long, etc.) - I have not worked with programming like that in a long time though. Of course you might have more than one issue at once.

Take a look at previous posts tagged "data-format", maybe they will give you some hints.


answered Aug 03 '10 at 09:03

Evgeny%20Fadeev's gravatar image

Evgeny Fadeev

updated Aug 03 '10 at 19:47

Thank you very much for your answer. I already tried both byte orders, but using little endian results in a spectrum of pure noise ;) Furthermore I think a wrong byte order would always result in a completely useless spectrum. But my posted spectrum is the rough/noisy outline of the correct one. - Pascal Fricke (Aug 03 '10 at 12:51)

I tried many different ways to read the raw bytes from the fid - without success. If I compare my code to the libraries released by Dr. Marat I don't see any (substantial) difference. That's why the result is so confusing. - Pascal Fricke (Aug 03 '10 at 13:24)

Concerning your advice to look at the fid: It looks awful. Not comparable to the fid I see in SpinWorks. Not even a decay... But I'm not sure if I sperarate the real and imaginary fid correctly: I extract the even fid array index numbers to the real array, and the odd numbers to the imaginary. - Pascal Fricke (Aug 03 '10 at 13:35)

Unfortunately I don't know how to create a synthetic fid. Of course I could just reverse the method I use for reading the fid, but this would imply that this method is correct, and this is what we want to find out. What do you mean by "real data offset"? - Pascal Fricke (Aug 03 '10 at 13:45)

not sure what is going wrong, but it certainly isn't the group delay issue, nor is it likely the byte order issue. Are you sure that you are reading the data as 32 bit signed integers? BTW all digital filters have group delay. It's just where you adjust for them that is the issue. - Kirk Marat (Aug 03 '10 at 18:23)

see 2 more comments
i like this answer (click again to cancel)
i dont like this answer (click again to cancel)

I think that Evgeny is right. Bruker FIDs are time shifted, and if you do not proccess them properly you will get spectra like that as you can see in the following link: http://nmr-analysis.blogspot.com/2008/02/why-arent-bruker-fids-time-corrected.html

I have the impression that you already knew this, because in your source code you are phasing the spectrum taking this into account, but I have not seen the bit to remove the initial points and zero fill the data. This is the simplest procedure to deal with the problem and it is described here: http://www.boc.chem.uu.nl/static/local/prospectnd/dmx_digital_filters.html


answered Aug 03 '10 at 11:48

Adolfo%20Botana's gravatar image

Adolfo Botana

updated Aug 03 '10 at 12:01

Evgeny%20Fadeev's gravatar image

Evgeny Fadeev

Thank you very much for your answer. You are right that I am aware of the fact that, because of the group delay, DSP Bruker data need a special phase correction *or* a circular left shift, as described in the article you referred to. - Pascal Fricke (Aug 03 '10 at 12:42)

Since the space for comments is very limited I'll go on in another one: I have already implemented and tried both methods, without success. Additionally, my spectrum looks much more distorted than the one in your first link. That makes me think that another reason is causing the problem. - Pascal Fricke (Aug 03 '10 at 12:43)

i like this answer (click again to cancel)
i dont like this answer (click again to cancel)

Many thanks to all answers given. I finally could solve the problem. Something went wrong with reading the binary fid data into the fid array. I only had to change the bruker_read.cpp, the new version can be found here:


To see what is changed, begin reading at line 176. Actually I now just write the inputstream into the 32 bit signed integer variables of the fid array using the ">>" operator.

Now the spectrum looks correct:


Despite the fact that it works now, it is strange nonetheless. I could not find an error in the previous version. It should have worked.

Eventually I will have to find the problem, since the current method will be difficult to use for Varian data because now I don't have access to each byte of the inputstream any more. So selective byte-reversal (as needed for the Varian fid headers) becomes somewhat difficult, but I will have a look at this later.

A (hopefully) final question: Does anybody know why it is necessary to convert the Fourier transformed data (which are floating point numbers) to integer values before doing the post processing stuff? At least that is the way it is done in the libraries by Dr. Marat (using a scaling factor to better fit the whole integer range). I implemented this conversion in my code as well because he is the expert, but I still wonder why the floating point numbers cannot be used for further processing.


answered Aug 04 '10 at 00:16

Pascal%20Fricke's gravatar image

Pascal Fricke

Pascal, It is absolutely NOT necessary to convert to integer. This was a hold-over from early SpinWorks versions for speed of display. After all, screen addresses are integer. If you look at the more recent source that I sent you, you will see that everything is now double or float. - Kirk Marat (Aug 04 '10 at 06:48)

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a good answer, for discussions, please use comments and please do remember to vote (login to vote)
toggle preview

powered by CNPROG