(Demeter main page) (Cookbook main page)

Atoms and Feff

The Atoms and Feff interfaces are evolving in Demeter. Their features and interfaces are subject to change.

How do I run Atoms using Demeter?

This script replicates almost all the functionality of any prior version of Atoms.

   1 #!/usr/bin/perl
   2 use Ifeffit::Demeter qw(Atoms);
   3 
   4 my $atoms = Ifeffit::Demeter::Atoms->new();
   5 $atoms->read_inp("ybco.inp");
   6 print $atoms->Write("feff6");

It's that simple. A Feff6 input file will be written to standard output.

At this moment, Demeter is not reading CIF files, but that is a small chore. When CIF import is supported, Demeter will figure out the input format seamlessly.

Output files are formed using templates. Currently templates exist for feff6, feff7, feff8, absorption, and atoms. The argument to the Write method chooses the output template.

In the future, OpenBabel will be used to write other output formats, such as Protein Data Bank, Alchemy, and so on. If you need one of those immediately, it would be simple to write a new template.

How do I run Feff using Demeter?

See Demeter/Feff for an overview of Demeter's interface with Feff.

This script reads a Feff input file, computes the potentials, runs the path finder, and serializes the results to a file. Although this example reads a file actually called feff.inp, the Feff input file need not actually be called that (which is a huge improvement over old skool Feff!)

   1 #!/usr/bin/perl
   2 use warnings;
   3 use strict;
   4 use Ifeffit::Demeter;
   5 use aliased 'Ifeffit::Demeter::Feff';
   6 
   7 my $feff = Feff -> new();
   8 $feff->set({workspace=>"pf", screen=>1, buffer=>q{}, save=>1});
   9 
  10 $feff -> rdinp("feff.inp") -> potentials();
  11 $feff -> pathfinder;
  12 
  13 ### Freezing this cluster+pathlist to a YAML
  14 $feff->freeze("feff.yaml");

Here is the screen output of this script. The first few lines are familiar to anyone who has ever run Feff. Only the first part of Feff is run -- the part that computes the potentials and writes the phase.bin file. The lines starting with equals signs are the progress messages of the path finder.

  •  Feff 6L.02
     Copper example
     Calculating potentials and phases...
         free atom potential and density for atom type    0
         free atom potential and density for atom type    1
         overlapped potential and density for unique potential    0
         overlapped potential and density for unique potential    1
         muffin tin radii and interstitial parameters
         phase shifts for unique potential    0
         phase shifts for unique potential    1
     Feff done.  Have a nice day.
    === Cluster contains 86 atoms
    === Populating Tree (contains 949 nodes from the 55 atoms within 5.2 Ang.)
    === Traversing Tree and populating Heap (contains 750 elements)
    === Collapsing Heap to a degenerate list (found 23 unique paths)
    

At the end, the state of the Feff calculation is written to the file feff.yaml. This is a text file in the YAML format. This file is used to do things with the results of the path finder calculation.

Writing an interpretation of the Feff calculation

This script writes an interpretation of the Feff calculation which is rather like the one presented in Artemis.

   1 #!/usr/bin/perl 
   2 use warnings;
   3 use strict;
   4 use Ifeffit::Demeter;
   5 
   6 ## Deserializing feff.yaml;
   7 my $feff = Ifeffit::Demeter::Feff -> thaw("feff.yaml");
   8 print $feff->intrp;
  • # Copper example
    # This paths.dat file was written by Demeter 0.0.1
    # The central atom is denoted by this token: <+>
    # Cluster size = 5.20000 Angstroms, containing 86 atoms
    # 23 paths were found
    # Forward scattering cutoff 20.00
    # Distance fuzz = 0.0100 Angstroms
    # Angle fuzz = 3.0000 degrees
    # Suppressing eta: yes
    # -------------------------------------------------------------------------------
    #     degen   Reff       scattering path                       I legs   type
     0001  12    2.553  ----  <+> Cu_1   <+>                       2  2 single scattering
     0002   6    3.610  ----  <+> Cu_2   <+>                       2  2 single scattering
     0003  48    3.829  ----  <+> Cu_1   Cu_1   <+>                1  3 acute triangle
     0004  24    4.358  ----  <+> Cu_1   Cu_1   <+>                0  3 other double scattering
     0005  48    4.358  ----  <+> Cu_1   Cu_2   <+>                0  3 other double scattering
     0006  24    4.421  ----  <+> Cu_3   <+>                       2  2 single scattering
     0007  48    4.763  ----  <+> Cu_1   Cu_1   <+>                1  3 obtuse triangle
     0008  96    4.763  ----  <+> Cu_1   Cu_3   <+>                1  3 obtuse triangle
     0009  12    5.105  ----  <+> Cu_4   <+>                       2  2 single scattering
     0010  12    5.105  ----  <+> Cu_1   Cu_1   <+>                2  3 non-forward linear
     0011  24    5.105  ----  <+> Cu_1   Cu_4   <+>                2  3 forward scattering
     0012  12    5.105  ----  <+> Cu_1   <+>    Cu_1   <+>         2  4 forward through absorber
     0013  12    5.105  ----  <+> Cu_1   Cu_4   Cu_1   <+>         2  4 double forward scattering
     0014  48    5.105  ----  <+> Cu_1   <+>    Cu_1   <+>         0  4 hinge
     0015  48    5.105  ----  <+> Cu_1   Cu_1   Cu_1   <+>         0  4 dog-leg
     0016  48    5.105  ----  <+> Cu_1   Cu_1   Cu_1   <+>         0  4 other triple scattering
     0017  48    5.105  ----  <+> Cu_1   Cu_3   Cu_1   <+>         1  4 obtuse triangle
     0018  12    5.105  ----  <+> Cu_1   <+>    Cu_1   <+>         1  4 rattle
     0019  48    5.105  ----  <+> Cu_1   <+>    Cu_1   <+>         0  4 hinge
     0020  48    5.105  ----  <+> Cu_1   Cu_3   Cu_1   <+>         0  4 dog-leg
     0021  24    5.105  ----  <+> Cu_1   <+>    Cu_1   <+>         0  4 hinge
     0022  24    5.105  ----  <+> Cu_1   Cu_2   Cu_1   <+>         0  4 dog-leg
     0023  24    5.105  ----  <+> Cu_1   Cu_2   Cu_1   <+>         0  4 other triple scattering
    

Some new information (compared to Artemis) is available in this interpretation. Demeter uses heuristics to make a guess about which paths are significant. The Importance column displays this guess. Paths with an importance of 2 probably cannot be ignored. These tend to be single scattering paths and colinear or nearly colinear multiple scattering paths. Paths with an importance of 1 include various triangles and four legged paths that "rattle" between the absorber and one other atoms. These may or may not be important. Paths with 0 importance probably do not carry significant spectral weight. Please not that these evaluations are determined by heuristics. I try to be conservative, preferring false positives to false negatives. You should always check your paths.

At the end of each line is a description of the paths geometry which, hopefully, will help you visualize the structure of the path.

Writing a paths.dat file and running genfmt

This script finishes off the Feff calculation in a way that closely resembles the normal behavior of Feff. Demeter writes a paths.dat file (line 13) then runs Feff's genfmt segment (line 16) which writes out the feffNNNN.dat files.

   1 #!/usr/bin/perl 
   2 use warnings;
   3 use strict;
   4 use Ifeffit::Demeter;
   5 
   6 ## Deserializing feff.yaml;
   7 my $feff = Ifeffit::Demeter::Feff -> thaw("feff.yaml");
   8 
   9 $feff->pathsdat(); # all paths
  10 #$feff->pathsdat(1,2,6,9); # the first four SS paths
  11 
  12 $feff->genfmt;

The genfmt output can be controlled using the argument of the pathsdat method, which is a list of path indeces. (See line 14, which is commented out.) Only those paths will be written to feffNNNN.dat files by genfmt since only those paths will be listed in the paths.dat file.

Examining the geometries contributing to the degeneracy of a path

One of the features of Demeter's path finder is that it remembers the scattering geometries of every degenerate path. This is demonstrated in this script, which writes out the guts of a paths.dat file with one entry for each of the degenerate paths.

   1 #!/usr/bin/perl 
   2 use warnings;
   3 use strict;
   4 use Ifeffit::Demeter;
   5 
   6 ## Deserializing feff.yaml;
   7 my $feff = Ifeffit::Demeter::Feff -> thaw("feff.yaml");
   8 my @list_of_paths = $feff->pathlist;
   9 
  10 ### The 6 scattering geometries that contribute to path #2:
  11 my $sp = $list_of_paths[1];
  12 my $j=1000;
  13 foreach my $s ($sp->all_strings) {
  14   print $sp -> pathsdat({index=>++$j, string=>$s, angles=>1});
  15 };

Here is what gets printed:

  • ### Here are the 6 scattering geometries that contribute to path #2:
      1001    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
        3.610000    0.000000    0.000000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
      1002    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
       -3.610000    0.000000    0.000000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
      1003    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
        0.000000    3.610000    0.000000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
      1004    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
        0.000000   -3.610000    0.000000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
      1005    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
        0.000000    0.000000    3.610000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
      1006    2   6.000  index, nleg, degeneracy, r= 3.6100
          x           y           z     ipot  label      rleg      beta        eta
        0.000000    0.000000   -3.610000   1 'Cu_2  '     3.6100  180.0000    0.0000
        0.000000    0.000000    0.000000   0 'abs   '     3.6100  180.0000    0.0000
    

Note that the pathlist method of the Feff object (line 10) returns a list of ScatteringPath objects. The pathsdat method of the ScatteringPath object is used to write out the paths.dat entry for each scattering geometry.

Plotting paths

This script imports the serialized path finder calculation and plots the first several paths. The next recipe is the first hint about how ScatteringPath objects will be used in a fit.

   1 #!/usr/bin/perl 
   2 use warnings;
   3 use strict;
   4 use Ifeffit::Demeter;
   5 my $plot_features = Ifeffit::Demeter::Plot -> new();
   6 $plot_features->legend({key_dy => 0.05, # set nice legend parameters for the plot
   7                         key_x  => 0.6});
   8 
   9 ## Deserializing feff.yaml;
  10 my $feff = Ifeffit::Demeter::Feff -> thaw("feff.yaml");
  11 my @list_of_paths = $feff->pathlist;
  12 
  13 ### Plotting the first 6 paths
  14 my @pobjects = ();
  15 foreach my $i (0 .. 5) {
  16   my $j = $i+1;
  17   Ifeffit::Demeter::Path -> new()
  18       -> set({sp    => $list_of_paths[$i],
  19               index => $j,
  20              })
  21         -> plot('r');
  22 };

Here is the plot. The sharp observer will see one difference between this list of paths and what a normal Feff6 calculation using the default heap and keep criteria values would produce. The fourth path is one which falls below the heap criterion, which uses a plane wave approximation to find paths which are too small to put onto the heap. With no such capability, Demeter's path finder includes that path in the final list.


/iffwiki/Demeter/Cookbook/AtomsAndFeff?action=AttachFile&do=get&target=paths.png

How do I integrate the Feff and Fitting systems in Demeter?

Here is the multiple data set copper fit from the data handling recipes page rewritten to use the Feff and ScatteringPath objects:

   1 #!/usr/bin/perl     ### multiple data set fit to Cu foil data at two temperatures
   2 ## -----------------------------------------------------------
   3 ## boilerplate required in every script:
   4 use warnings;
   5 use strict;
   6 use Ifeffit::Demeter;
   7 my $plot = Ifeffit::Demeter::Plot -> new();
   8 ## -----------------------------------------------------------
   9 Ifeffit::Demeter->set_mode({screen  => 0, ifeffit => 1, file => ">mdsfit.iff",});
  10 
  11 my %common = (fft_kmin   => 3,    fft_kmax   => 14,
  12               bft_rmax   => 1.0,  bft_rmax   => 4.3,
  13               fit_k1     => 1,    fit_k3     => 1,);
  14 
  15 my $data_010k = Ifeffit::Demeter::Data -> new({group => 'data0',});
  16 $data_010k -> set(\%common);
  17 $data_010k -> set({file       => "cu10k.chi",
  18                    label      => '10 K copper data',
  19                    cv         => 10,
  20                   });
  21 my $data_150k = Ifeffit::Demeter::Data -> new({group => 'data1',});
  22 $data_150k -> set(\%common);
  23 $data_150k -> set({file       => "cu150k.chi",
  24                    label      => '150 K copper data',
  25                    cv         => 150,
  26                   });
  27 
  28 ###--- make GDS objects for an isotropic expansion, correlated Debye model
  29 my @gdsobjects =  
  30    (Ifeffit::Demeter::GDS -> new({type => 'lguess', name => 'alpha', mathexp => 0,}),
  31     ## here is some syntactic sugar provided by the Tools module
  32     Ifeffit::Demeter::Tools -> simpleGDS("guess amp = 1"),
  33     Ifeffit::Demeter::GDS -> new({type => 'guess',  name => 'enot',  mathexp => 0,}),
  34     Ifeffit::Demeter::GDS -> new({type => 'guess',  name => 'theta', mathexp => 500,}),
  35     Ifeffit::Demeter::GDS -> new({type => 'set',    name => 'sigmm', mathexp => 0.0005,}),
  36    );
  37 
  38 ## thaw a Feff calculation
  39 my $feff = Ifeffit::Demeter::Feff -> thaw("cu_feff.yaml");
  40 my @scattering_paths = $feff->pathlist;
  41 
  42 ## make Path objects for the first 5 paths in copper (3 shell fit)
  43 my @paths_010k = ();
  44 foreach my $i (0 .. 4) {
  45   my $j = $i+1;
  46   $paths_010k[$i] = Ifeffit::Demeter::Path -> new();
  47   $paths_010k[$i]->set({data     => $data_010k,
  48                         sp       => $scattering_paths[$i],
  49                         label    => "10K, path $j",
  50                         s02      => 'amp',
  51                         e0       => 'enot',
  52                         delr     => 'alpha*reff',
  53                         sigma2   => 'debye([cv], theta) + sigmm',
  54                        });
  55 };
  56 
  57 ## clone these 5 paths for the second data set
  58 my @paths_150k = ();
  59 foreach my $i (0 .. 4) {
  60   my $j = $i+1;
  61   $paths_150k[$i] = $paths_010k[$i] -> clone({data   => $data_150k,
  62                                               label  => "150K, path $j",
  63                                              });
  64 };
  65 
  66 ## make a Fit object
  67 my $fitobject = Ifeffit::Demeter::Fit -> new({gds   => \@gdsobjects,
  68                                               data  => [$data_010k, $data_150k],
  69                                               paths => [@paths_010k, @paths_150k],
  70                                              });
  71 ## do the fit
  72 $fitobject -> fit;

A Feff calculation on copper metal is thawed at line 39 and the list of paths is read at line 40. Then at line 48, the sp attribute is set to a thawed ScatteringPath from the Feff calculation. When using a ScatteringPath object rather than directly reading a feffNNNN.dat file, you do not (must not!) set the file and folder attributes by hand. Note that the feffNNNN.dat file is given a strange name which is chosen to avoid filename collisions resulting from rerunning Feff or from running multiple Feff calculations.

When Demeter sets up the fit at line 72, it will notice that the feffNNNN.dat file does not exist for that Path and will run Feff to make it as soon as it is needed.

/!\ Note that in version 0.1 there are still some shortcomings in Demeter's serialization scheme. You need to be careful that Demeter can find the phase.bin file from the original Feff calculation. Fixing this shortcoming is one of the goals for version 0.2.


Demeter/Cookbook/AtomsAndFeff (last edited 2008-01-25 22:10:28 by BruceRavel)