4.2. Demeter's templating system¶
DEMETER uses Text::Template to construct all text
destined for IFEFFIT or LARCH as well as for
ATOMS and FEFF input files and the plotting
backends. The use of templating system add a bit of complexity to
DEMETER in the sense that the actual content of
IFEFFIT or LARCH commands (or input files) is
generated quite far away from the location in the code where that text
is used. However, the use of a templating system adds a lot to
DEMETER. Output can be highly customized or directed to a
different target altogether. For example, it is already possible in
version 0.2 to generate content for a feffit.inp
file rather
than for an IFEFFIT or LARCH script. In the
future, templates will make it easy for DEMETER to target
multiple plotting backends, write out functional DEMETER
scripts, use other FEFF versions, and so on.
Text::Template is wonderful – it hits a real sweet spot between simple and powerful. A template in this system is plain text with snippets of perl code interspersed. Here is an example:
{ # -*- ifm -*-
# Forward transform template
# {$D} returns the ifeffit group name
# {$D->get("parameter")} returns the value of that parameter
}
fftf({$D->group}.chi,
k = {$D}.k,
kmin = {$D->fft_kmin},
kmax = {$D->fft_kmax},
dk = {$D->fft_dk},
kwindow = {$D->fft_kwindow},
kweight = {$D->get_kweight},
rmax_out = {$D->rmax_out})
This is the template for generating a forward Fourier transform
command using the iff_columns
template set. Anything contained in
curly brackets is interpreted as perl, everything else is plain text
that gets passed through the templating system unaltered.
The way that this template gets used is like so:
$data -> set_mode(template_process => "iff_columns");
$string = $data -> template("process", "fft");
$data -> dispose($string);
The first line chooses the template set. The second line fills in the
fft
template from the process template group|/TEMPLATE GROUPS
using the parameters of the Data objects contained in $data
. The
template
method returns a string containing the appropriate
IFEFFIT or LARCH commands. This string is
disposed in the last line.
DEMETER uses certain conventions to push particular data into a
template. You can see two of those conventions in this example.
$D
, when used inside of curly braces, refers to the Data object of
the referent. $P
refers to the current Plot object, which is
defined as the plot
mode parameter.
Within the curly braces, DEMETER syntax is used and DEMETER methods are used to get data out of DEMETER objects. Some templates contain more complicated blocks of code, such as loops or control structures. Most curly-brackets perl blocks are simply object accesses, such as in the example above.
Here is a complete list of the special scalars for accessing DEMETER objects in templates.
$S
This refers to the object that invoked thetemplate
method.
$D
This refers to the Data object associated with the object that invoked thetemplate
method. For a Data object,$S
and$D
point at the same object. For a Path, SSPath, or VPath object, however,$D
points at the Data object to which that Path object belongs.
$P
This refers to the default Plot object. This is the same object that gets returned bypo
method of the base class.
$C
This refers to the Config object containing all the data from the configuration subsystem. Note that you should use the
default
(or possiblydemeter
) method to access system configuration parameters.The other use of
$C
is to access user-defined parameters. The merge templates for example make extensive use of this to set, for example, the boundaries of the merge range and the space in which the merge takes place. See Demeter::Config for details on setting user-defined Config parameters. For user-defined parameters, you should use theget
method.
$F
This refers to the current Fit object. Normally, thefit
orsum
method of the Demeter::Fit class will set the default for you.
$DS
This refers to the data object chosen as the data standard, as explained here. Data processing methods such asalign
will set the data standard so that$DS
evaluates correctly in templates.
$T
This refers to the active Feff object and is mostly used to generatefeff.inp
files.
$A
This refers to the Atoms object from which afeff.inp
is being generated.
There is one final mechanism for moving data into a template. This
method is quite similar to user-defined Config attributes, but may be
more convenient. You can supply an additional argument to the
template
method which is an anonymous hash. An example would be
the save_xmu
template from the process tamplate group. It is
called like so in save_xmu
in Demeter::Data::Mu
:
my $string = $self->template("process", "save_xmu",
{filename => $filename,
titles => "dem_data_*"});
The corresponding template looks like this:
write_data(file="{$filename}", ${$titles}, ${$D->group}_title_*,
{$D->group}.energy, {$D->group}.xmu, {$D->group}.bkg, {$D->group}.pre_edge,
{$D->group}.post_edge, {$D->group}.der, {$D->group}.sec)
Here the filename and titles glob are passed in the anonymous hash and accessed in the template via their hash keys inside of curly brackets.
4.2.1. Template Groups¶
DEMETER has a lot of templates and they are grouped according to general function as a way fo imposing some order on their large numbers. The (currently) five template groups are:
analysis
These templates are used for analysis chores that do not involve Feff. Things such as linear combination fitting and difference spectra go into this template group.
atoms
These templates are used by the Atoms object to structure its output files. Although in the future I hope to use OpenBabel to direct lists of atomic coordinates to differnt output targets, you could put a template in this group to make, say, an alchemy file.
feff
These templates are used to structure feff.inp files made using Feff objects as part of DEMETER's rewrite of FEFF fucntionality.
plot
These templates are used to generate plotting commands from Data or Path objects.
process
All the rest of the templates go into this group. Everything involved in reading, writing, or processing data goes in this template group.
4.2.2. Template Sets¶
Within the different template groups, you may find multiple template sets.
feff
The feff template group has sets for “feff6”, “feff7”, and “feff8”. The feff template set is chosen by setting thetemplate_feff
mode
plot
The plotting template sets are “pgplot”, “gnuplot”, and “demeter”. The first two generate commands for the currently available plotting backends. The last is intended for use with the DEMETER fitting and processing template set. In the future new sets may be written for different plotting backends (for example, Grace would be a target that would work very well within DEMETER). The plot template set is chosen by setting thetemplate_plot
mode.
fit and process
Template sets exist for IFEFFIT, LARCH, FEFFIT, and DEMETER. There are two version of the IFEFFIT template set called “ifeffit” and “iff_columns”. The first set uses a fairly terse style while the second one tries to align IFEFFIT command arguments into columns aligned at the equals sign wherever possible. The second one may be a bit more human readable. The fit and process template sets are chosen by setting thetemplate_fit
andtemplate_process
modes.
ATOMS does not use template sets and currently there are only IFEFFIT and LARCH sets for the analysis group.
4.2.3. Diagnostics¶
Unknown Demeter template file: group $group; type $file; $tmpl
You specified a combination of template group and template file that does not exist.
Todo
New template sets:
- More plotting backends? Matplotlib? thers?
DEMETER is copyright © 2009-2016 Bruce Ravel – This document is copyright © 2016 Bruce Ravel
This document is licensed under The Creative Commons Attribution-ShareAlike License.
If DEMETER and this document are useful to you, please consider supporting The Creative Commons.