Welcome | spec | C-PLOT | Support | Downloads | Users | Contact
Contents -> FOUR-CIRCLE REFERENCE -> Least-Squares Refinement of Lattice Parameters
spec Manual


4.13. - Least-Squares Refinement of Lattice Parameters



In the previous sections, the procedure described for determining the orientation matrix required a knowledge of the lattice parameters of the crystal and the position of two reflections. When such information is unknown, the orientation matrix can be fit to an unlimited number of observed peak positions using a least-squares procedure. ( J. Matthews and R.L. Walker, Mathematical Methods of Physics, (Benjamin, Menlo Park, 1970), p. 391. ) Lattice parameters derived from the fitted orientation matrix can then be calculated, although such lattice parameters are not constrained to exhibit any symmetry whatsoever.

In spec's implementation of least square refinement, three macros are used to create a file that contains the observed peak positions. That file is eventually run as a command file, and the least squares analysis is performed.


The reflex_beg macro initializes the reflections file:
    global REFLEX   # Variable for file name
    # Open the file, save old one as .bak and write header
    def reflex_beg '{
          if ("$1" == "0") {
                  if (REFLEX == ")
                          REFLEX = "reflex"
                  REFLEX = getval("Reflections file", REFLEX)
          } else
                  REFLEX = "$1"
    
          if (open(REFLEX))
                  exit
          close(REFLEX)
          if (file_info(REFLEX, "-s"))
                  unix(sprintf("mv %s %s.bak", REFLEX, REFLEX))
          fprintf(REFLEX,"# %s\n\n_begUB\n\n",date())
    }'
    


The reflex macro adds lines to the file that contain the (H,K,L) and (2,,,) of each reflection:
    # Add reflection to the file
    def reflex '
          if ($# != 3) {
                  print "Usage:  reflex H K L"
                  exit
          }
          if (REFLEX == ") {
                  REFLEX = getval("Reflections file", "reflex")
                  if (REFLEX == ")
                          exit
          }
          waitmove; get_angles; calcHKL
          fprintf(REFLEX,"H = %g;  K = %g;  L = %g\n",$1,$2,$3)
          {
            local i
    
            for (i=0; i<_numgeo; i++)
                  fprintf(REFLEX,"A[%s]=%9.4f;  ",motor_mne(mA[i]),A[mA[i]])
            fprintf(REFLEX,"\n")
          }
          fprintf(REFLEX,"# counts = %g\n", S[DET])
          fprintf(REFLEX,"_addUB\n\n")
    '
    



Finally, the reflex_end macro puts the proper trailer on the file:
    # Add trailer to file
    def reflex_end '
          fprintf(REFLEX,"_fitUB\n")
          printf("Type \"qdo %s\" to calculate new orientation matrix\n",\
                  REFLEX)
    '
    


When you are ready to calculate the orientation matrix, simply run the command file. There is no limit to the number of reflections contained in the file. You can also edit the file by hand to add or subtract reflections.

The calculated orientation matrix will remain valid until you type calcG, or invoke a macro that calls calcG. Those macros are or0, or1, or_swap and setlat.

The six original lattice parameters will remain unchanged when using the above macros to fit the orientation matrix to the reflections. The calcL macro can be invoked to calculate the lattice parameters derived from the fitted orientation matrix and place their values in the appropriate elements of the parameter array. The old lattice parameters will be lost.

Here is a sketch of the commands you use to perform the least squares refinement of the lattice parameters.
    1.FOURC> reflex_beg
    Reflections file (reflex)? <return> 2.FOURC> (find and move to a reflection ...)
    3.FOURC> reflex 2 2 0
    4.FOURC> (find and move to another reflection ...)
    5.FOURC> reflex 2 0 2
    6.FOURC> ...
    7.FOURC> reflex_end
    Type "qdo reflex" to recalculate orientation matrix. 8.FOURC> qdo reflex
    Opened command file `reflex' at level 1. 9.FOURC>



At least three reflections must be used for the least-squares fitting to work.


To calculate the new lattice parameters, use the calcL macro:
    1.FOURC> calcL
    2.FOURC> pa
    4-Circle Geometry, Omega-Fixed (mode 1), frozen coordinate, sector 0 Primary Reflection (at lambda 1.54): Omega Chi Phi = 5.00025 90.102 -82.5455 H K L = 2 2 0 Secondary (at lambda 1.54): Omega Chi Phi = 0 0 90 H K L = 0 1 0 Azimuthal Reference: H K L = 2 2 0 Lattice Constants: a b c = 4.12644 4.12295 4.11078 Alpha Beta Gamma = 90.0435 89.9763 90.1221 3.FOURC>

Here is a typical reflections file created by the above macros:
    # Wed Jan 31 21:55:01 1990
    
    _begUB
    
    H = 2;  K = 2;  L = 0
    A[tth]=  63.8185;  A[th]=  36.9320;  A[chi]=  89.8765;  A[phi]= -80.0815
    # counts = 3456
    _addUB
    
    H = 2;  K = 0;  L = 2
    A[tth]=  63.8335;  A[th]=  36.8920;  A[chi]= 145.4185;  A[phi]=  42.8145
    # counts = 6345
    _addUB
    
    H = 0;  K = 2;  L = -1
    A[tth]=  49.4100;  A[th]=  29.6725;  A[chi]=  35.8180;  A[phi]=  45.9070
    # counts = 5634
    _addUB
    
    H = 0;  K = 2;  L = -1
    A[tth]=  49.3550;  A[th]=  29.7225;  A[chi]=  35.9380;  A[phi]=  45.9070
    # counts = 4563
    _addUB
    
    _fitUB
    
Within this file, the calc() function codes defined by the macros _begUB, _addUB and _fitUB are used to access the C code that performs the least squares operations.


  Top
  Prev | Next