I have a calculated spectrum stored in a file containing two columns: The first is the x-position (wavenumber), the second is the height (intensity). In order to simulate a real spectrum I'd like to place a Gaussian for each of these lines (around 60) and plot the sum of all. As explained here I read the coefficients position and height from the datafile:
g(x,x0,s,I) = I/sqrt(2*pi*s**2)*exp(-(x-x0)**2/(2*s**2))
stats "file.dat" nooutput
nlines=int(STATS_records-1)
paramstr(N) = sprintf('stats "file.dat" every ::%i::%i u (x%i=$1,I%i=$2) nooutput',N,N,N,N)
do for [i=0:nlines] {eval(paramstr(i))}
spectrum(x,s) = sum [i=0:nlines] g(x,value(sprintf('x%i',i)'),s,value(sprintf('I%i',i)))
This works well and produces the desired result. However, in my case, it's not a single file, but around 30, each containing a different spectrum. The files have systematic names and consist of a 5-symbol code build up from "t", "g+" and "g-", i.e. possible filenames are ttttt.dat, g+g+ttg-.dat etc.
I'd like to batch convert all of them, but then only plot specifically chosen ones in an interactive manner. Therefore my idea was to create a separately named function for each of these file, i.e. ttttt(x,s), g+g+ttg-(x,s) etc. Because + and - are not allowed in a function name I replace these with ¯ and _, respectively:
a = '"very/long/path/to/dir/with/files/'
filelist = system('ls '.@a")
conflist = system('ls '.@a"." | sed 's/.dat//' | sed 's/g+/g¯/g' | sed 's/g-/g_/g'")
Now I wrapped the code shown above inside a loop over the words in the filelist. The first attempt had the result that all functions looked the same and contained the parameters of the alphabetically last file, because each cycle overwrote the values of x%i and I%i. I therefore had to make sure each function refers to its own parameters by including the file name (e.g. x3 replaced by xttttt3). By doing so around 3600 variables are defined.
do for [c = 1:words(titlelist)] {
paramstr(N) = sprintf('stats @a/%s" every ::%i::%i u (x%s%i=$1,I%s%i=$2) nooutput',word(titlelist,c),N,N,word(conflist,c),N,word(conflist,c),N)
do for [i=0:nlines] {eval(paramstr(i))}
eval(sprintf("%s(x,s) = sum [i=0:nlines] g(x,value(sprintf('x%s%i',word(conflist,c),i)),s,value(sprintf('I%s%i',word(conflist,c),i)))",word(conflist,c)))
}
However, when calling plot ttttt(x,s=5)
I get the error message undefined variable: c
. After setting c to some value between 1 and 30, each and every function shows the same spectrum, namely the one corresponding to the 30th entry of filelist. At this point I'm running out of ideas. Does anyone has a suggestion on how to get the proper result from a command like plot tttg¯t(x,s), tg_g¯ttt(x,s), ttttt(x,s)
?
EDIT: The problem was caused by wrong nesting of sprintf
. Reshuffle of nested sprintf
s and careful concatenation of strings resulted in a correctly working call:
eval(sprintf("%s(x,s) = sum [i=0:nlines] g(x,value('x%s'.i),s,value('I%s'.i))", word(conflist,c),word(conflist,c),word(conflist,c)))
Obviously, this is very poorly written, cumbersome, barely understandable and very slow at plotting. I will happily appreciate any more elegant solution!