Vincent Fourmond: Solution for QSoas quiz #1: averaging spectra
This post describes the solution to the Quiz #1, based on the files found there. The point is to produce both the average and the standard deviation of a series of spectra. Below is how the final averaged spectra shoud look like:
I will present here two different solutions.
Solution 1: using the definition of standard deviation
There is a simple solution using the definition of the standard deviation:
$$\sigma_y = \sqrt <y^2> - <y> ^2 $$
in which \(<y^2>\) is the average of \(y^2\) (and so on). So the simplest solution is to construct datasets with an additional column that would contain \(y^2\), average these columns, and replace the average with the above formula. For that, we need first a companion script that loads a single data file and adds a column with \(y^2\). Let's call this script
Solution 2: use QSoas's knowledge of standard deviation The other method is a little more involved but it demonstrates a good approach to problem solving with QSoas. The starting point is that, in
load-one.cmds:
load $ 1 apply-formula y2=y**2 /extra-columns=1 flag /flags=processedWhen this script is run with the name of a spectrum file as argument, it loads it (replaces
$ 1 by the first argument, the file name), adds a column y2 containing the square of the y column, and flag it with the processed flag. This is not absolutely necessary, but it makes it much easier to refer to all the spectra when they are processed. Then to process all the spectra, one just has to run the following commands:
run-for-each load-one.cmds Spectrum-1.dat Spectrum-2.dat Spectrum-3.dat average flagged:processed apply-formula y2=(y2-y**2)**0.5 dataset-options /yerrors=y2The
run-for-each command runs the load-one.cmds script for all the spectra (one could also have used Spectra-*.dat to not have to give all the file names). Then, the average averages the values of the columns over all the datasets. To be clear, it finds all the values that have the same X (or very close X values) and average them, column by column. The result of this command is therefore a dataset with the average of the original \(y\) data as y column and the average of the original \(y^2\) data as y2 column. So now, the only thing left to do is to use the above equation, which is done by the apply-formula code. The last command, dataset-options, is not absolutely necessary but it signals to QSoas that the standard error of the y column should be found in the y2 column. This is now available as script method-one.cmds in the git repository.
Solution 2: use QSoas's knowledge of standard deviation The other method is a little more involved but it demonstrates a good approach to problem solving with QSoas. The starting point is that, in
apply-formula, the value $stats.y_stddev corresponds to the standard deviation of the whole y column... Loading the spectra yields just a series of x,y datasets. We can contract them into a single dataset with one x column and several y columns:
load Spectrum-*.dat /flags=spectra contract flagged:spectraAfter these commands, the current dataset contains data in the form of:
lambda1 a1_1 a1_2 a1_3 lambda2 a2_1 a2_2 a2_3 ...in which the
ai_1 come from the first file, ai_2 the second and so on. We need to use transpose to transform that dataset into:
0 a1_1 a2_1 ... 1 a1_2 a2_2 ... 2 a1_3 a2_3 ...In this dataset, values of the absorbance for the same wavelength for each dataset is now stored in columns. The next step is just to use
expand to obtain a series of datasets with the same x column and a single y column (each corresponding to a different wavelength in the original data). The game is now to replace these datasets with something that looks like:
0 a_average 1 a_stddevFor that, one takes advantage of the
$stats.y_average and $stats.y_stddev values in apply-formula, together with the i special variable that represents the index of the point:
apply-formula "if i == 0; then y=$stats.y_average; end; if i == 1; then y=$stats.y_stddev; end" strip-if i>1Then, all that is left is to apply this to all the datasets created by
expand, which can be just made using run-for-datasets, and then, we reverse the splitting by using contract and transpose ! In summary, this looks like this. We need two files. The first, process-one.cmds contains the following code:
apply-formula "if i == 0; then y=$stats.y_average; end; if i == 1; then y=$stats.y_stddev; end" strip-if i>1 flag /flags=processedThe main file,
method-two.cmds looks like this:
load Spectrum-*.dat /flags=spectra contract flagged:spectra transpose expand /flags=tmp run-for-datasets process-one.cmds flagged:tmp contract flagged:processed transpose dataset-options /yerrors=y2Note some of the code above can be greatly simplified using new features present in the upcoming 3.0 version, but that is the topic for another post. About QSoasQSoas is a powerful open source data analysis program that focuses on flexibility and powerful fitting capacities. It is released under the GNU General Public License. It is described in Fourmond, Anal. Chem., 2016, 88 (10), pp 5050 5052. Current version is 2.2. You can download its source code and compile it yourself or buy precompiled versions for MacOS and Windows there.



This month, the Reproducible Builds project restarted our IRC meetings, managing to convene twice: the first time on October 12th (




Over the summer I decided to migrate my backups from rdiff-backup to borg,
which offers some significant advantages, in particular de-duplication, but
comes at a cost of complexity, and a corresponding sense of unease about how
sound my backup strategy might be. I've now hit the Point Of No Return: my
second external backup drive is overdue being synced with my NAS, which will
delete the last copy of the older rdiff-backup backups.
Whilst I hesitate over this last action to commit to borg, something else
happened. My wife wanted to put a copy of her iTunes music library on her
new phone, and I couldn't find it: not only could I not find it on any of
our computers, I also couldn't find a copy on the NAS, or in backups, or even
in old DVD-Rs. This has further knocked my confidence in our family data
management, and makes me even more nervous to commit to borg. I'm now wondering
about stashing the contents of the second external backup disk on some cloud
service as a fail-safe.
There was one known-good copy of Sarah's music: on her ancient iPod Nano.
Apple have gone to varying lengths to prevent you from copying music from an
iPod. When Music is copied to an iPod, the files are stripped of all their
metadata (artist, title, album, etc.) and renamed to something non-identifying
(e.g.
My maybe most impactful piece of code is
In Emacs, you can use
Scaffolding is fairly expensive but building things out of it is enormous fun! You can see a complete sequence of the build process, including pictures of the "engineering maquette", at
Last week I received the official notice: There is now a German company named "Fre(i)e Software GmbH" registered with the German Trade Register.
Founding a New Company
Over the past months I have put my energy into founding a new company. As a freelancing IT consultant I started facing the limitation of other companies having strict policies that forbid the cooperation with one person businesses (Personengesellschaften).
Thus, the requirement for setting up a GmbH business came onto my agenda. I will move some of my business activities into this new company, starting next year.
Policy Ideas
The "Fre(i)e Software GmbH" will be a platform to facilitate the growth and spreading of Free Software on this planet.
Here are some first ideas for company policies:
Sent a pull request to document sshfs slave mode.
Every time I try to do it I forget, so at least I have a
document about how to do it. Also changed the name from
slave to passive, but I don't think that will help me
remember... Not feeling particularly creative about the
name.
I was assigned 6.25 hours of work by Freexian's Debian LTS
initiative and carried over 17.5 hours from earlier months. I
worked 11.5 hours this month and returned 7.75 hours to the pool, so
I will carry over 4.5 hours to December.
I updated linux-4.19 to include the changes in
About a month worth of updates on KDE/Plasma in Debian has accumulated, so here we go. The highlights are: Plasma 5.19.5 based on Qt 5.15 is in Debian/experimental and hopefully soon in Debian/unstable, and my own builds at OBS have been updated to Plasma 5.20.2, Frameworks 5.75, Apps 20.08.2.
Thanks to the dedicated work of the Qt maintainers, Qt 5.15 has finally entered Debian/unstable and we can finally target Plasma 5.20.
OBS packages
The OBS packages as usual follow the latest release, and currently ship KDE Frameworks 5.75, KDE Apps 20.08.2, and new, Plasma 5.20.2. The package sources are as usual (note the different path for the Plasma packages and the App packages, containing the release version!), for Debian/unstable:
A couple of year ago, I moved into a new flat that comes with RJ45 sockets wired for 10 Gigabit (but currently offering 1 Gigabit) Ethernet.This also meant changing the settings on my router box for my new ISP.I took this opportunity to review my router's other settings too. I'll be blogging about these over the next few posts.
Adding IPv6 support to my home LAN
I have been following the evolution of IPv6 ever since the KAME project produced the first IPv6 implementation. I have also been keeping track of the IPv4 address depletion.
Around the time the IPv6 Day was organized in 2011, I started investigating the situation of IPv6 support at local ISPs.
Well, never mind all those rumors about Finland being some high-tech mecca. Back then, no ISP went beyond testing their routers for IPv6 compatibility and producing white papers on what their limited test deployments accomplished.
Not that it matters much, in practice. Most IPv6 documentation out there, including
A new
I frequently see a pattern in image build/refresh scripts where a set of packages is installed, and then all packages are updated:

We all know these situations when we receive an email asking Can you
check the design of X, I need a reply by tonight. Or an instant
message: My website went down, can you check? Another email: I
canceled a plan at the hosting company, can you restore my website as
fast as possible? A phone call: The TLS certificate didn t get
updated, and now we can t access service Y. Yet another email: Our
super important medical advice website is suddenly being censored in
country Z, can you help?
Everyone knows those messages that have URGENT in capital letters in
the email subject. It might be that some of them really are urgent.
Others are the written signs of someone having a hard time properly
planning their own work and passing their delays on to someone who comes
later in the creation or production chain. And others again come from
people who are overworked and try to delegate some of their tasks to a
friendly soul who is likely to help.