source: trunk/GSASIIobj.py @ 5110

Last change on this file since 5110 was 5110, checked in by toby, 3 years ago

constraint comments

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 168.3 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIobj - data objects for GSAS-II
3########### SVN repository information ###################
4# $Date: 2021-12-06 22:56:47 +0000 (Mon, 06 Dec 2021) $
5# $Author: toby $
6# $Revision: 5110 $
7# $URL: trunk/GSASIIobj.py $
8# $Id: GSASIIobj.py 5110 2021-12-06 22:56:47Z toby $
9########### SVN repository information ###################
10
11'''
12*GSASIIobj: Data objects*
13=========================
14
15This module defines and/or documents the data structures used in GSAS-II, as well
16as provides misc. support routines.
17
18.. Next command allows \\AA to be used in HTML
19
20.. only:: html
21
22   :math:`\\require{mediawiki-texvc}`
23
24.. _Constraints_table:
25
26.. index::
27   single: Constraints object description
28   single: Data object descriptions; Constraints
29
30Constraints Tree Item
31----------------------
32
33Constraints are stored in a dict, separated into groups.
34Note that parameter are named in the following pattern,
35p:h:<var>:n, where p is the phase number, h is the histogram number
36<var> is a variable name and n is the parameter number.
37If a parameter does not depend on a histogram or phase or is unnumbered, that
38number is omitted.
39Note that the contents of each dict item is a List where each element in the
40list is a :ref:`constraint definition objects <Constraint_definitions_table>`.
41The constraints in this form are converted in
42:func:`GSASIImapvars.ProcessConstraints` to the form used in :mod:`GSASIImapvars`
43
44The keys in the Constraints dict are:
45
46.. tabularcolumns:: |l|p{4.5in}|
47
48==========  ====================================================
49  key         explanation
50==========  ====================================================
51Hist        This specifies a list of constraints on
52            histogram-related parameters,
53            which will be of form :h:<var>:n.
54HAP         This specifies a list of constraints on parameters
55            that are defined for every histogram in each phase
56            and are of form p:h:<var>:n.
57Phase       This specifies a list of constraints on phase
58            parameters,
59            which will be of form p::<var>:n.
60Global      This specifies a list of constraints on parameters
61            that are not tied to a histogram or phase and
62            are of form ::<var>:n
63==========  ====================================================
64
65.. _Constraint_definitions_table:
66
67.. index::
68   single: Constraint definition object description
69   single: Data object descriptions; Constraint Definition
70
71Each constraint is defined as an item in a list. Each constraint is of form::
72
73[[<mult1>, <var1>], [<mult2>, <var2>],..., <fixedval>, <varyflag>, <constype>]
74
75Where the variable pair list item containing two values [<mult>, <var>], where:
76
77  * <mult> is a multiplier for the constraint (float)
78  * <var> a :class:`G2VarObj` object. (Note that in very old .gpx files this might be a str with a variable name of form 'p:h:name[:at]')
79
80Note that the last three items in the list play a special role:
81
82 * <fixedval> is the fixed value for a `constant equation` (``constype=c``)
83   constraint or is None. For a `New variable` (``constype=f``) constraint,
84   a variable name can be specified as a str (used for externally
85   generated constraints)
86 * <varyflag> is True or False for `New variable` (``constype=f``) constraints
87   or is None. This indicates if this variable should be refined.
88 * <constype> is one of four letters, 'e', 'c', 'h', 'f' that determines the type of constraint:
89
90    * 'e' defines a set of equivalent variables. Only the first variable is refined (if the
91      appropriate refine flag is set) and and all other equivalent variables in the list
92      are generated from that variable, using the appropriate multipliers.
93    * 'c' defines a constraint equation of form,
94      :math:`m_1 \\times var_1 + m_2 \\times var_2 + ... = c`
95    * 'h' defines a variable to hold (not vary). Any variable on this list is not varied,
96      even if its refinement flag is set. Only one [mult,var] pair is allowed in a hold
97      constraint and the mult value is ignored.
98      This is of particular value when needing to hold one or more variables where a
99      single flag controls a set of variables such as, coordinates,
100      the reciprocal metric tensor or anisotropic displacement parameter.
101    * 'f' defines a new variable (function) according to relationship
102      :math:`newvar = m_1 \\times var_1 + m_2 \\times var_2 + ...`
103
104.. _Covariance_table:
105
106.. index::
107   single: Covariance description
108   single: Data object descriptions; Covariance
109
110Covariance Tree Item
111--------------------
112
113The Covariance tree item has results from the last least-squares run. They
114are stored in a dict with these keys:
115
116.. tabularcolumns:: |l|l|p{4in}|
117
118=============  ===============  ====================================================
119  key            sub-key        explanation
120=============  ===============  ====================================================
121newCellDict    \\                (dict) ith lattice parameters computed by
122                                :func:`GSASIIstrMath.GetNewCellParms`
123title          \\                (str) Name of gpx file(?)
124variables      \\                (list) Values for all N refined variables
125                                (list of float values, length N,
126                                ordered to match varyList)
127sig            \\                (list) Uncertainty values for all N refined variables
128                                (list of float values, length N,
129                                ordered to match varyList)
130varyList       \\                (list of str values, length N) List of directly refined variables
131                               
132newAtomDict    \\                (dict) atom position values computed in
133                                :func:`GSASIIstrMath.ApplyXYZshifts`
134Rvals          \\                (dict) R-factors, GOF, Marquardt value for last
135                                refinement cycle
136\\              Nobs             (int) Number of observed data points
137\\              Rwp              (float) overall weighted profile R-factor (%)
138\\              chisq            (float) :math:`\\sum w*(I_{obs}-I_{calc})^2`                               
139                                for all data.
140                                Note: this is not the reduced :math:`\\chi^2`.
141\\              lamMax           (float) Marquardt value applied to Hessian diagonal
142\\              GOF              (float) The goodness-of-fit, aka square root of
143                                the reduced chi squared.
144covMatrix      \\                (np.array) The (NxN) covVariance matrix
145=============  ===============  ====================================================
146
147.. _Phase_table:
148
149.. index::
150   single: Phase object description
151   single: Data object descriptions; Phase
152
153Phase Tree Items
154----------------
155
156Phase information is stored in the GSAS-II data tree as children of the
157Phases item in a dict with keys:
158
159.. tabularcolumns:: |l|l|p{4in}|
160
161==========  ===============     =====================================================================================================
162  key         sub-key           explanation
163==========  ===============     =====================================================================================================
164General         \\               (dict) Overall information for the phase
165  \\         3Dproj              (list of str) projections for 3D pole distribution plots
166  \\         AngleRadii          (list of floats) Default radius for each atom used to compute
167                                interatomic angles
168  \\         AtomMass            (list of floats) Masses for atoms
169  \\         AtomPtrs            (list of int) four locations (cx,ct,cs & cu) to use to pull info
170                                from the atom records
171  \\         AtomTypes           (llist of str) Atom types
172  \\         BondRadii           (list of floats) Default radius for each atom used to compute
173                                interatomic distances
174  \\         Cell                Unit cell parameters & ref. flag
175                                (list with 8 items. All but first item are float.)
176
177                                 0: cell refinement flag (True/False),
178                                 1-3: a, b, c, (:math:`\\AA`)
179                                 4-6: alpha, beta & gamma, (degrees)
180                                 7: volume (:math:`\\AA^3`)
181  \\         Color               (list of (r,b,g) triplets) Colors for atoms
182  \\         Compare             (dict) Polygon comparison parameters
183  \\         Data plot type      (str) data plot type ('Mustrain', 'Size' or
184                                'Preferred orientation') for powder data
185  \\         DisAglCtls          (dDict) with distance/angle search controls,
186                                which has keys 'Name', 'AtomTypes',
187                                'BondRadii', 'AngleRadii' which are as above
188                                except are possibly edited. Also contains
189                                'Factors', which is a 2 element list with
190                                a multiplier for bond and angle search range
191                                [typically (0.85,0.85)].
192  \\         F000X               (float) x-ray F(000) intensity
193  \\         F000N               (float) neutron F(000) intensity
194  \\         Flip                (dict) Charge flip controls
195  \\         HydIds              (dict) geometrically generated hydrogen atoms
196  \\         Isotope             (dict) Isotopes for each atom type
197  \\         Isotopes            (dict) Scattering lengths for each isotope
198                                combination for each element in phase
199  \\         MCSA controls       (dict) Monte Carlo-Simulated Annealing controls
200  \\         Map                 (dict) Map parameters
201  \\         Mass                (float) Mass of unit cell contents in g/mol
202  \\         Modulated           (bool) True if phase modulated
203  \\         Mydir               (str) Directory of current .gpx file
204  \\         Name                (str) Phase name
205  \\         NoAtoms             (dict) Number of atoms per unit cell of each type
206  \\         POhkl               (list) March-Dollase preferred orientation direction
207  \\         Pawley dmin         (float) maximum Q (as d-space) to use for Pawley extraction
208  \\         Pawley dmax         (float) minimum Q (as d-space) to use for Pawley extraction
209  \\         Pawley neg wt       (float) Restraint value for negative Pawley intensities
210  \\         SGData              (object) Space group details as a
211                                :ref:`space group (SGData) <SGData_table>`
212                                object, as defined in :func:`GSASIIspc.SpcGroup`.
213  \\         SH Texture          (dict) Spherical harmonic preferred orientation parameters
214  \\         Super               (int) dimension of super group (0,1 only)
215  \\         Type                (str) phase type (e.g. 'nuclear')
216  \\         Z                   (dict) Atomic numbers for each atom type
217  \\         doDysnomia          (bool) flag for max ent map modification via Dysnomia
218  \\         doPawley            (bool) Flag for Pawley intensity extraction
219  \\         vdWRadii            (dict) Van der Waals radii for each atom type
220ranId           \\               (int) unique random number Id for phase
221pId             \\               (int) Phase Id number for current project.
222Atoms           \\               (list of lists) Atoms in phase as a list of lists. The outer list
223                                is for each atom, the inner list contains varying
224                                items depending on the type of phase, see
225                                the :ref:`Atom Records <Atoms_table>` description.
226Drawing         \\               (dict) Display parameters
227\\           Atoms               (list of lists) with an entry for each atom that is drawn
228\\           Plane               (list) Controls for contour density plane display
229\\           Quaternion          (4 element np.array) Viewing quaternion
230\\           Zclip               (float) clipping distance in :math:`\\AA`
231\\           Zstep               (float) Step to de/increase Z-clip
232\\           atomPtrs            (list) positions of x, type, site sym, ADP flag in Draw Atoms
233\\           backColor           (list) background for plot as and R,G,B triplet
234                                (default = [0, 0, 0], black).
235\\           ballScale           (float) Radius of spheres in ball-and-stick display
236\\           bondList            (dict) Bonds
237\\           bondRadius          (float) Radius of binds in :math:`\\AA`
238\\           cameraPos           (float) Viewing position in :math:`\\AA` for plot
239\\           contourLevel        (float) map contour level in :math:`e/\\AA^3`
240\\           contourMax          (float) map contour maximum
241\\           depthFog            (bool) True if use depthFog on plot - set currently as False
242\\           ellipseProb         (float) Probability limit for display of thermal
243                                ellipsoids in % .
244\\           magMult             (float) multiplier for magnetic moment arrows
245\\           mapSize             (float) x & y dimensions of contourmap (fixed internally)
246\\           modelView           (4,4 array) from openGL drawing transofmation matrix
247\\           oldxy               (list with two floats) previous view point
248\\           radiusFactor        (float) Distance ratio for searching for bonds. Bonds
249                                are located that are within r(Ra+Rb) and (Ra+Rb)/r
250                                where Ra and Rb are the atomic radii.
251\\           selectedAtoms       (list of int values) List of selected atoms
252\\           showABC             (bool) Flag to show view point triplet. True=show.
253\\           showHydrogen        (bool) Flag to control plotting of H atoms.
254\\           showRigidBodies     (bool) Flag to highlight rigid body placement
255\\           showSlice           (bool) flag to show contour map
256\\           sizeH               (float) Size ratio for H atoms
257\\           unitCellBox         (bool) Flag to control display of the unit cell.
258\\           vdwScale            (float) Multiplier of van der Waals radius for display of vdW spheres.
259\\           viewDir             (np.array with three floats) cartesian viewing direction
260\\           viewPoint           (list of lists) First item in list is [x,y,z]
261                                in fractional coordinates for the center of
262                                the plot. Second item list of previous & current
263                                atom number viewed (may be [0,0])
264RBModels        \\               Rigid body assignments (note Rigid body definitions
265                                are stored in their own main top-level tree entry.)
266RMC             \\               (dict) RMCProfile & rmcfull controls
267Pawley ref      \\               (list) Pawley reflections
268Histograms      \\               (dict of dicts) The key for the outer dict is
269                                the histograms tied to this phase. The inner
270                                dict contains the combined phase/histogram
271                                parameters for items such as scale factors,
272                                size and strain parameters. The following are the
273                                keys to the inner dict. (dict)
274\\           Babinet             (dict) For protein crystallography. Dictionary with two
275                                entries, 'BabA', 'BabU'
276\\           Extinction          (list of float, bool) Extinction parameter
277\\           Flack               (list of [float, bool]) Flack parameter & refine flag
278\\           HStrain             (list of two lists) Hydrostatic strain. The first is
279                                a list of the HStrain parameters (1, 2, 3, 4, or 6
280                                depending on unit cell), the second is a list of boolean
281                                refinement parameters (same length)
282\\           Histogram           (str) The name of the associated histogram
283\\           Layer Disp          (list of [float, bool]) Layer displacement in beam direction & refine flag
284\\           LeBail              (bool) Flag for LeBail extraction
285\\           Mustrain            (list) Microstrain parameters, in order:
286   
287                                0. Type, one of  u'isotropic', u'uniaxial', u'generalized'
288                                1. Isotropic/uniaxial parameters - list of 3 floats
289                                2. Refinement flags - list of 3 bools
290                                3. Microstrain axis - list of 3 ints, [h, k, l]
291                                4. Generalized mustrain parameters - list of 2-6 floats, depending on space group
292                                5. Generalized refinement flags - list of bools, corresponding to the parameters of (4)
293\\           Pref.Ori.           (list) Preferred Orientation. List of eight parameters.
294                                Items marked SH are only used for Spherical Harmonics.
295                               
296                                0. (str) Type, 'MD' for March-Dollase or 'SH' for Spherical Harmonics
297                                1. (float) Value
298                                2. (bool) Refinement flag
299                                3. (list) Preferred direction, list of ints, [h, k, l]
300                                4. (int) SH - number of terms
301                                5. (dict) SH - 
302                                6. (list) SH
303                                7. (float) SH
304\\           Scale               (list of [float, bool]) Phase fraction & refine flag
305\\           Size                List of crystallite size parameters, in order:
306
307                                0. (str) Type, one of  u'isotropic', u'uniaxial', u'ellipsoidal'
308                                1. (list) Isotropic/uniaxial parameters - list of 3 floats
309                                2. (list) Refinement flags - list of 3 bools
310                                3. (list) Size axis - list of 3 ints, [h, k, l]
311                                4. (list) Ellipsoidal size parameters - list of 6 floats
312                                5. (list) Ellipsoidal refinement flags - list of bools, corresponding to the parameters of (4)
313\\           Use                 (bool) True if this histogram is to be used in refinement
314MCSA            \\               (dict) Monte-Carlo simulated annealing parameters
315==========  ===============     =====================================================================================================
316
317.. _RBData_table:
318
319.. index::
320   single: Rigid Body Data description
321   single: Data object descriptions; Rigid Body Data
322
323Rigid Body Objects
324------------------
325
326Rigid body descriptions are available for two types of rigid bodies: 'Vector'
327and 'Residue'. Vector rigid bodies are developed by a sequence of translations each
328with a refinable magnitude and Residue rigid bodies are described as Cartesian coordinates
329with defined refinable torsion angles.
330
331.. tabularcolumns:: |l|l|p{4in}|
332
333==========  ===============     ====================================================
334  key         sub-key           explanation
335==========  ===============     ====================================================
336Vector      RBId                (dict of dict) vector rigid bodies
337\\           AtInfo              (dict) Drad, Color: atom drawing radius & color for each atom type
338\\           RBname              (str) Name assigned by user to rigid body
339\\           VectMag             (list) vector magnitudes in :math:`\\AA`
340\\           rbXYZ               (list of 3 float Cartesian coordinates for Vector rigid body )
341\\           rbRef               (list of 3 int & 1 bool) 3 assigned reference atom nos. in rigid body for origin
342                                definition, use center of atoms flag
343\\           VectRef             (list of bool refinement flags for VectMag values )
344\\           rbTypes             (list of str) Atom types for each atom in rigid body
345\\           rbVect              (list of lists) Cartesian vectors for each translation used to build rigid body
346\\           useCount            (int) Number of times rigid body is used in any structure
347Residue     RBId                (dict of dict) residue rigid bodies
348\\           AtInfo              (dict) Drad, Color: atom drawing radius & color for each atom type
349\\           RBname              (str) Name assigned by user to rigid body
350\\           rbXYZ               (list of 3 float) Cartesian coordinates for Residue rigid body
351\\           rbTypes             (list of str) Atom types for each atom in rigid body
352\\           atNames             (list of str) Names of each atom in rigid body (e.g. C1,N2...)
353\\           rbRef               (list of 3 int & 1 bool) 3 assigned reference atom nos. in rigid body for origin
354                                definition, use center of atoms flag
355\\           rbSeq               (list) Orig,Piv,angle,Riding : definition of internal rigid body
356                                torsion; origin atom (int), pivot atom (int), torsion angle (float),
357                                riding atoms (list of int)
358\\           SelSeq              (int,int) used by SeqSizer to identify objects
359\\           useCount            (int)Number of times rigid body is used in any structure
360RBIds           \\               (dict) unique Ids generated upon creation of each rigid body
361\\           Vector              (list) Ids for each Vector rigid body
362\\           Residue             (list) Ids for each Residue rigid body
363==========  ===============     ====================================================
364
365.. _SGData_table:
366
367.. index::
368   single: Space Group Data description
369   single: Data object descriptions; Space Group Data
370
371Space Group Objects
372-------------------
373
374Space groups are interpreted by :func:`GSASIIspc.SpcGroup`
375and the information is placed in a SGdata object
376which is a dict with these keys. Magnetic ones are marked "mag"
377
378.. tabularcolumns:: |l|p{4.5in}|
379
380==========  ========================================================================================
381  key         explanation
382==========  ========================================================================================
383BNSlattsym  mag - (str) BNS magnetic space group symbol and centering vector
384GenFlg      mag - (list) symmetry generators indices
385GenSym      mag - (list) names for each generator
386MagMom      mag - (list) "time reversals" for each magnetic operator
387MagPtGp     mag - (str) Magnetic point group symbol
388MagSpGrp    mag - (str) Magnetic space group symbol
389OprNames    mag - (list) names for each space group operation
390SGCen       (np.array) Symmetry cell centering vectors. A (n,3) np.array
391            of centers. Will always have at least one row: ``np.array([[0, 0, 0]])``
392SGFixed     (bool) Only True if phase mported from a magnetic cif file
393            then the space group can not be changed by the user because
394            operator set from cif may be nonstandard
395SGGen       (list) generators
396SGGray      (bool) True if space group is a gray group (incommensurate magnetic structures)
397SGInv       (bool) True if centrosymmetric, False if not
398SGLatt      (str)Lattice centering type. Will be one of
399            P, A, B, C, I, F, R
400SGLaue      (str) one of the following 14 Laue classes:
401            -1, 2/m, mmm, 4/m, 4/mmm, 3R,
402            3mR, 3, 3m1, 31m, 6/m, 6/mmm, m3, m3m
403SGOps       (list) symmetry operations as a list of form
404            ``[[M1,T1], [M2,T2],...]``
405            where :math:`M_n` is a 3x3 np.array
406            and :math:`T_n` is a length 3 np.array.
407            Atom coordinates are transformed where the
408            Asymmetric unit coordinates [X is (x,y,z)]
409            are transformed using
410            :math:`X^\\prime = M_n*X+T_n`
411SGPolax     (str) Axes for space group polarity. Will be one of
412            '', 'x', 'y', 'x y', 'z', 'x z', 'y z',
413            'xyz'. In the case where axes are arbitrary
414            '111' is used (P 1, and ?).
415SGPtGrp     (str) Point group of the space group
416SGUniq      unique axis if monoclinic. Will be
417            a, b, or c for monoclinic space groups.
418            Will be blank for non-monoclinic.
419SGSpin      mag - (list) of spin flip operatiors (+1 or -1) for the space group operations
420SGSys       (str) symmetry unit cell: type one of
421            'triclinic', 'monoclinic', 'orthorhombic',
422            'tetragonal', 'rhombohedral', 'trigonal',
423            'hexagonal', 'cubic'
424SSGK1       (list) Superspace multipliers
425SpGrp       (str) space group symbol
426SpnFlp      mag - (list) Magnetic spin flips for every magnetic space group operator
427==========  ========================================================================================
428
429.. _SSGData_table:
430
431.. index::
432   single: Superspace Group Data description
433   single: Data object descriptions; Superspace Group Data
434
435Superspace groups [3+1] are interpreted by :func:`GSASIIspc.SSpcGroup`
436and the information is placed in a SSGdata object
437which is a dict with these keys:
438
439.. tabularcolumns:: |l|p{4.5in}|
440
441==========  ====================================================
442  key         explanation
443==========  ====================================================
444SSGCen      (list) 4D cell centering vectors [0,0,0,0] at least
445SSGK1       (list) Superspace multipliers
446SSGOps      (list) 4D symmetry operations as [M,T] so that M*x+T = x'
447SSpGrp      (str) superspace group symbol extension to space group
448            symbol, accidental spaces removed
449modQ        (list) modulation/propagation vector
450modSymb     (list of str) Modulation symbols
451==========  ====================================================
452
453
454Phase Information
455--------------------
456
457.. index::
458   single: Phase information record description
459
460Phase information is placed in one of the following keys:
461
462.. tabularcolumns:: |l|p{4.5in}|
463
464==========  ==============================================================
465  key         explanation
466==========  ==============================================================
467General       Overall information about a phase
468Histograms    Information about each histogram linked to the
469              current phase as well as parameters that
470              are defined for each histogram and phase
471              (such as sample peak widths and preferred
472              orientation parameters.
473Atoms         Contains a list of atoms, as described in the
474              :ref:`Atom Records <Atoms_table>` description.
475Drawing       Parameters that determine how the phase is
476              displayed, including a list of atoms to be
477              included, as described in the
478              :ref:`Drawing Atom Records <Drawing_atoms_table>`
479              description
480MCSA          Monte-Carlo simulated annealing parameters
481pId           The index of each phase in the project, numbered
482              starting at 0
483ranId         An int value with a unique value for each phase
484RBModels      A list of dicts with parameters for each
485              rigid body inserted into the current phase,
486              as defined in the
487              :ref:`Rigid Body Insertions <Rigid_Body_Insertions>`.
488              Note that the rigid bodies are defined as
489              :ref:`Rigid Body Objects <RBData_table>`
490RMC           PDF modeling parameters
491Pawley ref    Pawley refinement parameters
492
493==========  ==============================================================
494
495.. _Atoms_table:
496
497.. index::
498   single: Atoms record description
499   single: Data object descriptions; Atoms record
500
501--------------------
502Atom Records
503--------------------
504
505If ``phasedict`` points to the phase information in the data tree, then
506atoms are contained in a list of atom records (list) in
507``phasedict['Atoms']``. Also needed to read atom information
508are four pointers, ``cx,ct,cs,cia = phasedict['General']['AtomPtrs']``,
509which define locations in the atom record, as shown below. Items shown are
510always present; additional ones for macromolecular phases are marked 'mm',
511and those for magnetic structures are marked 'mg'
512
513.. tabularcolumns:: |l|p{4.5in}|
514
515==============      ====================================================
516location            explanation
517==============      ====================================================
518ct-4                mm - (str) residue number
519ct-3                mm - (str) residue name (e.g. ALA)
520ct-2                mm - (str) chain label
521ct-1                (str) atom label
522ct                  (str) atom type
523ct+1                (str) refinement flags; combination of 'F', 'X', 'U', 'M'
524cx,cx+1,cx+2        (3 floats) the x,y and z coordinates
525cx+3                (float) site occupancy
526cx+4,cx+5,cx+6      mg - (list) atom magnetic moment along a,b,c in Bohr magnetons
527cs                  (str) site symmetry
528cs+1                (int) site multiplicity
529cia                 (str) ADP flag: Isotropic ('I') or Anisotropic ('A')
530cia+1               (float) Uiso
531cia+2...cia+7       (6 floats) U11, U22, U33, U12, U13, U23
532atom[cia+8]         (int) unique atom identifier
533
534==============      ====================================================
535
536.. _Drawing_atoms_table:
537
538.. index::
539   single: Drawing atoms record description
540   single: Data object descriptions; Drawing atoms record
541
542----------------------------
543Drawing Atom Records
544----------------------------
545
546If ``phasedict`` points to the phase information in the data tree, then
547drawing atoms are contained in a list of drawing atom records (list) in
548``phasedict['Drawing']['Atoms']``. Also needed to read atom information
549are four pointers, ``cx,ct,cs,ci = phasedict['Drawing']['AtomPtrs']``,
550which define locations in the atom record, as shown below. Items shown are
551always present; additional ones for macromolecular phases are marked 'mm',
552and those for magnetic structures are marked 'mg'
553
554.. tabularcolumns:: |l|p{4.5in}|
555
556==============   ===================================================================================
557location            explanation
558==============   ===================================================================================
559ct-4                mm - (str) residue number
560ct-3                mm - (str) residue name (e.g. ALA)
561ct-2                mm - (str) chain label
562ct-1                (str) atom label
563ct                  (str) atom type
564cx,cx+1,cx+2        (3 floats) the x,y and z coordinates
565cx+3,cx+4,cx+5      mg - (3 floats) atom magnetic moment along a,b,c in Bohr magnetons
566cs-1                (str) Sym Op symbol; sym. op number + unit cell id (e.g. '1,0,-1')
567cs                  (str) atom drawing style; e.g. 'balls & sticks'
568cs+1                (str) atom label style (e.g. 'name')
569cs+2                (int) atom color (RBG triplet)
570cs+3                (str) ADP flag: Isotropic ('I') or Anisotropic ('A')
571cs+4                (float) Uiso
572cs+5...cs+11        (6 floats) U11, U22, U33, U12, U13, U23
573ci                  (int) unique atom identifier; matches source atom Id in Atom Records
574==============   ===================================================================================
575
576.. _Rigid_Body_Insertions:
577
578----------------------------
579Rigid Body Insertions
580----------------------------
581
582If ``phasedict`` points to the phase information in the data tree, then
583rigid body information is contained in list(s) in
584``phasedict['RBModels']['Residue']`` and/or ``phasedict['RBModels']['Vector']``
585for each rigid body inserted into the current phase.
586
587.. tabularcolumns:: |l|p{4.5in}|
588
589==============   ===================================================================================
590key              explanation
591==============   ===================================================================================
592fixOrig           Should the origin be fixed (when editing, not the refinement flag)
593Ids               Ids for assignment of atoms in the rigid body
594numChain          Chain number for macromolecular fits
595Orient            Orientation of the RB as a quaternion and a refinement flag (' ', 'A' or 'AV')
596OrientVec         Orientation of the RB expressed as a vector and azimuthal rotation angle
597Orig              Origin of the RB in fractional coordinates and refinement flag (bool)
598RBId              References the unique ID of a rigid body in the
599                  :ref:`Rigid Body Objects <RBData_table>`
600RBname            The name for the rigid body (str)
601AtomFrac          The atom fractions for the rigid body
602ThermalMotion     The thermal motion description for the rigid body, which includes a choice for
603                  the model and can include TLS parameters or an overall Uiso value.
604Torsions          Defines the torsion angle and refinement flag for each torsion defined in
605                  the :ref:`Rigid Body Object <RBData_table>`
606==============   ===================================================================================
607
608.. _Powder_table:
609
610.. index::
611   single: Powder data object description
612   single: Data object descriptions; Powder Data
613
614Powder Diffraction Tree Items
615-----------------------------
616
617Every powder diffraction histogram is stored in the GSAS-II data tree
618with a top-level entry named beginning with the string "PWDR ". The
619diffraction data for that information are directly associated with
620that tree item and there are a series of children to that item. The
621routines :func:`GSASIIdataGUI.GSASII.GetUsedHistogramsAndPhasesfromTree`
622and :func:`GSASIIstrIO.GetUsedHistogramsAndPhases` will
623load this information into a dictionary where the child tree name is
624used as a key, and the information in the main entry is assigned
625a key of ``Data``, as outlined below.
626
627.. tabularcolumns:: |p{1in}|p{1in}|p{4in}|
628
629======================     ===============  ===========================================================
630  key                       sub-key          explanation
631======================     ===============  ===========================================================
632Comments                    \\               (list of str) Text strings extracted from the original powder
633                                            data header. These cannot be changed by the user;
634                                            it may be empty.
635Limits                      \\               (list) two two element lists, as [[Ld,Hd],[L,H]]
636                                            where L and Ld are the current and default lowest
637                                            two-theta value to be used and
638                                            where H and Hd are the current and default highest
639                                            two-theta value to be used.
640Reflection Lists            \\               (dict of dicts) with an entry for each phase in the
641                                            histogram. The contents of each dict item
642                                            is a dict containing reflections, as described in
643                                            the :ref:`Powder Reflections <PowderRefl_table>`
644                                            description.
645Instrument Parameters       \\               (dict) The instrument parameters uses different dicts
646                                            for the constant wavelength (CW) and time-of-flight (TOF)
647                                            cases. See below for the descriptions of each.
648wtFactor                    \\               (float) A weighting factor to increase or decrease
649                                            the leverage of data in the histogram .
650                                            A value of 1.0 weights the data with their
651                                            standard uncertainties and a larger value
652                                            increases the weighting of the data (equivalent
653                                            to decreasing the uncertainties).
654Sample Parameters           \\               (dict) Parameters that describe how
655                                            the data were collected, as listed
656                                            below. Refinable parameters are a list containing
657                                            a float and a bool, where the second value
658                                            specifies if the value is refined, otherwise
659                                            the value is a float unless otherwise noted.
660\\                           Scale           The histogram scale factor (refinable)
661\\                           Absorption      The sample absorption coefficient as
662                                            :math:`\\mu r` where r is the radius
663                                            (refinable). Only valid for Debye-Scherrer geometry.
664\\                           SurfaceRoughA   Surface roughness parameter A as defined by
665                                            Surotti, *J. Appl. Cryst*, **5**, 325-331, 1972.
666                                            (refinable - only valid for Bragg-Brentano geometry)
667\\                           SurfaceRoughB   Surface roughness parameter B (refinable -
668                                            only valid for Bragg-Brentano geometry)
669\\                           DisplaceX,      Sample displacement from goniometer center
670                            DisplaceY       where Y is along the beam direction and
671                                            X is perpendicular. Units are :math:`\\mu m`
672                                            (refinable).
673\\                           Phi, Chi,       Goniometer sample setting angles, in degrees.
674                            Omega
675\\                           Gonio. radius   Radius of the diffractometer in mm
676\\                           InstrName       (str) A name for the instrument, used in preparing
677                                            a CIF .
678\\                           Force,          Variables that describe how the measurement
679                            Temperature,    was performed. Not used directly in
680                            Humidity,       any computations.
681                            Pressure,
682                            Voltage
683\\                           ranId           (int) The random-number Id for the histogram
684                                            (same value as where top-level key is ranId)
685\\                           Type            (str) Type of diffraction data, may be 'Debye-Scherrer'
686                                            or 'Bragg-Brentano' .
687hId                         \\               (int) The number assigned to the histogram when
688                                            the project is loaded or edited (can change)
689ranId                       \\               (int) A random number id for the histogram
690                                            that does not change
691Background                  \\               (list) The background is stored as a list with where
692                                            the first item in the list is list and the second
693                                            item is a dict. The list contains the background
694                                            function and its coefficients; the dict contains
695                                            Debye diffuse terms and background peaks.
696                                            (TODO: this needs to be expanded.)
697Data                        \\               (list) The data consist of a list of 6 np.arrays
698                                            containing in order:
699
700                                            0. the x-postions (two-theta in degrees),
701                                            1. the intensity values (Yobs),
702                                            2. the weights for each Yobs value
703                                            3. the computed intensity values (Ycalc)
704                                            4. the background values
705                                            5. Yobs-Ycalc
706======================     ===============  ===========================================================
707
708.. _CWPowder_table:
709
710.. index::
711   single: Powder data CW Instrument Parameters
712
713-----------------------------
714CW Instrument Parameters
715-----------------------------
716
717Instrument Parameters are placed in a list of two dicts,
718where the keys in the first dict are listed below. Note that the dict contents are different for
719constant wavelength (CW) vs. time-of-flight (TOF) histograms.
720The value for each item is a list containing three values: the initial value, the current value
721and a refinement flag which can have a value of True, False or 0 where 0 indicates a value that
722cannot be refined. The first and second values are floats unless otherwise noted.
723Items not refined are noted as [*]
724
725.. tabularcolumns:: |l|p{1in}|p{4in}|
726
727========================    ===============  ===========================================================
728  key                       sub-key           explanation
729========================    ===============  ===========================================================
730Instrument Parameters[0]    Type [*]            (str) Histogram type:
731                                                * 'PXC' for constant wavelength x-ray
732                                                * 'PNC' for constant wavelength neutron
733\\                           Bank [*]            (int) Data set number in a multidata file (usually 1)
734\\                           Lam                 (float) Specifies a wavelength in :math:`\\AA`
735\\                           Lam1 [*]            (float) Specifies the primary wavelength in
736                                                :math:`\\AA`, used in place of Lam
737                                                when an :math:`\\alpha_1, \\alpha_2`
738                                                source is used.
739\\                           Lam2 [*]            (float) Specifies the secondary wavelength in
740                                                :math:`\\AA`, used with Lam1
741\\                           I(L2)/I(L1)         (float) Ratio of Lam2 to Lam1, used with Lam1
742\\                           Zero                (float) Two-theta zero correction in *degrees*
743\\                           Azimuth [*]         (float) Azimuthal setting angle for data recorded with differing setting angles
744\\                           U, V, W             (float) Cagliotti profile coefficients
745                                                for Gaussian instrumental broadening, where the
746                                                FWHM goes as
747                                                :math:`U \\tan^2\\theta + V \\tan\\theta + W`
748\\                           X, Y, Z             (float) Cauchy (Lorentzian) instrumental broadening coefficients
749\\                           SH/L                (float) Variant of the Finger-Cox-Jephcoat asymmetric
750                                                peak broadening ratio. Note that this is the
751                                                sum of S/L and H/L where S is
752                                                sample height, H is the slit height and
753                                                L is the goniometer diameter.
754\\                           Polariz.            (float) Polarization coefficient.
755Instrument Parameters[1]                        (empty dict)
756========================    ===============  ===========================================================
757
758.. _TOFPowder_table:
759
760.. index::
761   single: Powder data TOF Instrument Parameters
762
763-----------------------------
764TOF Instrument Parameters
765-----------------------------
766
767Instrument Parameters are also placed in a list of two dicts,
768where the keys in each dict listed below, but here for
769time-of-flight (TOF) histograms.
770The value for each item is a list containing three values: the initial value, the current value
771and a refinement flag which can have a value of True, False or 0 where 0 indicates a value that
772cannot be refined. The first and second values are floats unless otherwise noted.
773Items not refined are noted as [*]
774
775.. tabularcolumns:: |l|p{1.5in}|p{4in}|
776
777========================    ===============  ===========================================================
778  key                        sub-key          explanation
779========================    ===============  ===========================================================
780Instrument Parameters[0]    Type [*]            (str) Histogram type:
781                                                * 'PNT' for time of flight neutron
782\\                           Bank                (int) Data set number in a multidata file
783\\                           2-theta [*]         (float) Nominal scattering angle for the detector
784\\                           fltPath [*]         (float) Total flight path source-sample-detector
785\\                           Azimuth [*]         (float) Azimuth angle for detector right hand rotation
786                                                from horizontal away from source
787\\                           difC,difA,          (float) Diffractometer constants for conversion of d-spacing to TOF
788                            difB                in microseconds
789\\                           Zero                (float) Zero point offset (microseconds)
790\\                           alpha               (float) Exponential rise profile coefficients
791\\                           beta-0              (float) Exponential decay profile coefficients
792                            beta-1
793                            beta-q
794\\                           sig-0               (float) Gaussian profile coefficients
795                            sig-1
796                            sig-2
797                            sig-q   
798\\                           X,Y,Z               (float) Lorentzian profile coefficients
799Instrument Parameters[1]    Pdabc               (list of 4 float lists) Originally created for use in gsas as optional tables
800                                                of d, alp, bet, d-true; for a reflection alpha & beta are obtained via interpolation
801                                                from the d-spacing and these tables. The d-true column is apparently unused.
802========================    ===============  ===========================================================
803
804
805.. _PowderRefl_table:
806
807.. index::
808   single: Powder reflection object description
809   single: Data object descriptions; Powder Reflections
810
811Powder Reflection Data Structure
812--------------------------------
813
814For every phase in a histogram, the ``Reflection Lists`` value is a dict
815one element of which is `'RefList'`, which is a np.array containing
816reflections. The columns in that array are documented below.
817
818==========  ====================================================
819  index         explanation
820==========  ====================================================
821 0,1,2          h,k,l (float)
822 3              (int) multiplicity
823 4              (float) d-space, :math:`\\AA`
824 5              (float) pos, two-theta
825 6              (float) sig, Gaussian width
826 7              (float) gam, Lorenzian width
827 8              (float) :math:`F_{obs}^2`
828 9              (float) :math:`F_{calc}^2`
829 10             (float) reflection phase, in degrees
830 11             (float) intensity correction for reflection, this times
831                :math:`F_{obs}^2` or :math:`F_{calc}^2` gives Iobs or Icalc
832 12             (float) Preferred orientation correction
833 13             (float) Transmission (absorption correction)
834 14             (float) Extinction correction
835==========  ====================================================
836
837.. _Xtal_table:
838
839.. index::
840   single: Single Crystal data object description
841   single: Data object descriptions; Single crystal data
842
843Single Crystal Tree Items
844-------------------------
845
846Every single crystal diffraction histogram is stored in the GSAS-II data tree
847with a top-level entry named beginning with the string "HKLF ". The
848diffraction data for that information are directly associated with
849that tree item and there are a series of children to that item. The
850routines :func:`GSASIIdataGUI.GSASII.GetUsedHistogramsAndPhasesfromTree`
851and :func:`GSASIIstrIO.GetUsedHistogramsAndPhases` will
852load this information into a dictionary where the child tree name is
853used as a key, and the information in the main entry is assigned
854a key of ``Data``, as outlined below.
855
856.. tabularcolumns:: |l|l|p{4in}|
857
858======================  ===============     ====================================================
859  key                      sub-key          explanation
860======================  ===============     ====================================================
861Data                        \\               (dict) that contains the
862                                            reflection table,
863                                            as described in the
864                                            :ref:`Single Crystal Reflections
865                                            <XtalRefl_table>`
866                                            description.
867
868Instrument Parameters       \\               (list) containing two dicts where the possible
869                                            keys in each dict are listed below. The value
870                                            for most items is a list containing two values:
871                                            the initial value, the current value.
872                                            The first and second
873                                            values are floats unless otherwise noted.
874\\                           Lam             (two floats) Specifies a wavelength in :math:`\\AA`
875\\                           Type            (two str values) Histogram type :
876                                            * 'SXC' for constant wavelength x-ray
877                                            * 'SNC' for constant wavelength neutron
878                                            * 'SNT' for time of flight neutron
879\\                           InstrName       (str) A name for the instrument, used in preparing a CIF
880wtFactor                    \\               (float) A weighting factor to increase or decrease
881                                            the leverage of data in the histogram.
882                                            A value of 1.0 weights the data with their
883                                            standard uncertainties and a larger value
884                                            increases the weighting of the data (equivalent
885                                            to decreasing the uncertainties).
886
887hId                         \\               (int) The number assigned to the histogram when
888                                            the project is loaded or edited (can change)
889ranId                       \\               (int) A random number id for the histogram
890                                            that does not change
891======================  ===============     ====================================================
892
893.. _XtalRefl_table:
894
895.. index::
896   single: Single Crystal reflection object description
897   single: Data object descriptions; Single Crystal Reflections
898
899Single Crystal Reflection Data Structure
900----------------------------------------
901
902For every single crystal a histogram, the ``'Data'`` item contains
903the structure factors as an np.array in item `'RefList'`.
904The columns in that array are documented below.
905
906.. tabularcolumns:: |l|p{4in}|
907
908==========  ====================================================
909  index         explanation
910==========  ====================================================
911 0,1,2          (float) h,k,l
912 3              (int) multiplicity
913 4              (float) d-space, :math:`\\AA`
914 5              (float) :math:`F_{obs}^2`
915 6              (float) :math:`\\sigma(F_{obs}^2)`
916 7              (float) :math:`F_{calc}^2`
917 8              (float) :math:`F_{obs}^2T`
918 9              (float) :math:`F_{calc}^2T`
919 10             (float) reflection phase, in degrees
920 11             (float) intensity correction for reflection, this times
921                :math:`F_{obs}^2` or :math:`F_{calc}^2`
922                gives Iobs or Icalc
923==========  ====================================================
924
925.. _Image_table:
926
927.. index::
928   image: Image data object description
929   image: Image object descriptions
930
931Image Data Structure
932--------------------
933
934Every 2-dimensional image is stored in the GSAS-II data tree
935with a top-level entry named beginning with the string "IMG ". The
936image data are directly associated with that tree item and there
937are a series of children to that item. The routines :func:`GSASIIdataGUI.GSASII.GetUsedHistogramsAndPhasesfromTree`
938and :func:`GSASIIstrIO.GetUsedHistogramsAndPhases` will
939load this information into a dictionary where the child tree name is
940used as a key, and the information in the main entry is assigned
941a key of ``Data``, as outlined below.
942
943.. tabularcolumns:: |l|l|p{4in}|
944
945======================  ======================  ====================================================
946  key                      sub-key              explanation
947======================  ======================  ====================================================
948Comments                    \\                   (list of str) Text strings extracted from the original image data
949                                                header or a metafile. These cannot be changed by
950                                                the user; it may be empty.
951Image Controls              azmthOff            (float) The offset to be applied to an azimuthal
952                                                value. Accomodates
953                                                detector orientations other than with the detector
954                                                X-axis
955                                                horizontal.
956\\                           background image    (list:str,float) The name of a tree item ("IMG ...") that is to be subtracted
957                                                during image integration multiplied by value. It must have the same size/shape as
958                                                the integrated image. NB: value < 0 for subtraction.
959\\                           calibrant           (str) The material used for determining the position/orientation
960                                                of the image. The data is obtained from :func:`ImageCalibrants`
961                                                and UserCalibrants.py (supplied by user).
962\\                           calibdmin           (float) The minimum d-spacing used during the last calibration run.
963\\                           calibskip           (int) The number of expected diffraction lines skipped during the last
964                                                calibration run.
965\\                           center              (list:floats) The [X,Y] point in detector coordinates (mm) where the direct beam
966                                                strikes the detector plane as determined by calibration. This point
967                                                does not have to be within the limits of the detector boundaries.
968\\                           centerAzm           (bool) If True then the azimuth reported for the integrated slice
969                                                of the image is at the center line otherwise it is at the leading edge.
970\\                           color               (str) The name of the colormap used to display the image. Default = 'Paired'.
971\\                           cutoff              (float) The minimum value of I/Ib for a point selected in a diffraction ring for
972                                                calibration calculations. See pixLimit for details as how point is found.
973\\                           DetDepth            (float) Coefficient for penetration correction to distance; accounts for diffraction
974                                                ring offset at higher angles. Optionally determined by calibration.
975\\                           DetDepthRef         (bool) If True then refine DetDepth during calibration/recalibration calculation.
976\\                           distance            (float) The distance (mm) from sample to detector plane.
977\\                           ellipses            (list:lists) Each object in ellipses is a list [center,phi,radii,color] where
978                                                center (list) is location (mm) of the ellipse center on the detector plane, phi is the
979                                                rotation of the ellipse minor axis from the x-axis, and radii are the minor & major
980                                                radii of the ellipse. If radii[0] is negative then parameters describe a hyperbola. Color
981                                                is the selected drawing color (one of 'b', 'g' ,'r') for the ellipse/hyperbola.
982\\                           edgemin             (float) Not used;  parameter in EdgeFinder code.
983\\                           fullIntegrate       (bool) If True then integrate over full 360 deg azimuthal range.
984\\                           GonioAngles         (list:floats) The 'Omega','Chi','Phi' goniometer angles used for this image.
985                                                Required for texture calculations.
986\\                           invert_x            (bool) If True display the image with the x-axis inverted.
987\\                           invert_y            (bool) If True display the image with the y-axis inverted.
988\\                           IOtth               (list:floats) The minimum and maximum 2-theta values to be used for integration.
989\\                           LRazimuth           (list:floats) The minimum and maximum azimuth values to be used for integration.
990\\                           Oblique             (list:float,bool) If True apply a detector absorption correction using the value to the
991                                                intensities obtained during integration.
992\\                           outAzimuths         (int) The number of azimuth pie slices.
993\\                           outChannels         (int) The number of 2-theta steps.
994\\                           pixelSize           (list:ints) The X,Y dimensions (microns) of each pixel.
995\\                           pixLimit            (int) A box in the image with 2*pixLimit+1 edges is searched to find the maximum.
996                                                This value (I) along with the minimum (Ib) in the box is reported by :func:`GSASIIimage.ImageLocalMax`
997                                                and subject to cutoff in :func:`GSASIIimage.makeRing`.
998                                                Locations are used to construct rings of points for calibration calcualtions.
999\\                           PolaVal             (list:float,bool) If type='SASD' and if True, apply polarization correction to intensities from
1000                                                integration using value.
1001\\                           rings               (list:lists) Each entry is [X,Y,dsp] where X & Y are lists of x,y coordinates around a
1002                                                diffraction ring with the same d-spacing (dsp)
1003\\                           ring                (list) The x,y coordinates of the >5 points on an inner ring
1004                                                selected by the user,
1005\\                           Range               (list) The minimum & maximum values of the image
1006\\                           rotation            (float) The angle between the x-axis and the vector about which the
1007                                                detector is tilted. Constrained to -180 to 180 deg.
1008\\                           SampleShape         (str) Currently only 'Cylinder'. Sample shape for Debye-Scherrer experiments; used for absorption
1009                                                calculations.
1010\\                           SampleAbs           (list: float,bool) Value of absorption coefficient for Debye-Scherrer experimnents, flag if True
1011                                                to cause correction to be applied.
1012\\                           setDefault          (bool) If True the use the image controls values for all new images to be read. (might be removed)
1013\\                           setRings            (bool) If True then display all the selected x,y ring positions (vida supra rings) used in the calibration.
1014\\                           showLines           (bool) If True then isplay the integration limits to be used.
1015\\                           size                (list:int) The number of pixels on the image x & y axes
1016\\                           type                (str) One of 'PWDR', 'SASD' or 'REFL' for powder, small angle or reflectometry data, respectively.
1017\\                           tilt                (float) The angle the detector normal makes with the incident beam; range -90 to 90.
1018\\                           wavelength          (float) The radiation wavelength (:math:`\\AA`) as entered by the user
1019                                                (or someday obtained from the image header).
1020Masks                       Arcs                (list: lists) Each entry [2-theta,[azimuth[0],azimuth[1]],thickness] describes an arc mask
1021                                                to be excluded from integration
1022\\                           Frames              (list:lists) Each entry describes the x,y points (3 or more - mm) that describe a frame outside
1023                                                of which is excluded from recalibration and integration. Only one frame is allowed.
1024\\                           Points              (list:lists) Each entry [x,y,radius] (mm) describes an excluded spot on the image to be excluded
1025                                                from integration.
1026\\                           Polygons            (list:lists) Each entry is a list of 3+ [x,y] points (mm) that describe a polygon on the image
1027                                                to be excluded from integration.
1028\\                           Rings               (list: lists) Each entry [2-theta,thickness] describes a ring mask
1029                                                to be excluded from integration.
1030\\                           Thresholds          (list:[tuple,list]) [(Imin,Imax),[Imin,Imax]] This gives lower and upper limits for points on the image to be included
1031                                                in integrsation. The tuple is the image intensity limits and the list are those set by the user.
1032\\                           SpotMask            (dict: int & array)
1033                                                'esdMul'(int) number of standard deviations above mean ring intensity to mask
1034                                                'spotMask' (bool array) the spot mask for every pixel in image         
1035
1036Stress/Strain               Sample phi          (float) Sample rotation about vertical axis.
1037\\                           Sample z            (float) Sample translation from the calibration sample position (for Sample phi = 0)
1038                                                These will be restricted by space group symmetry; result of strain fit refinement.
1039\\                           Type                (str) 'True' or 'Conventional': The strain model used for the calculation.
1040\\                           d-zero              (list:dict) Each item is for a diffraction ring on the image; all items are from the same phase
1041                                                and are used to determine the strain tensor.
1042                                                The dictionary items are:
1043                                                'Dset': (float) True d-spacing for the diffraction ring; entered by the user.
1044                                                'Dcalc': (float) Average calculated d-spacing determined from strain coeff.
1045                                                'Emat': (list: float) The strain tensor elements e11, e12 & e22 (e21=e12, rest are 0)
1046                                                'Esig': (list: float) Esds for Emat from fitting.
1047                                                'pixLimit': (int) Search range to find highest point on ring for each data point
1048                                                'cutoff': (float) I/Ib cutoff for searching.
1049                                                'ImxyObs': (list: lists) [[X],[Y]] observed points to be used for strain calculations.
1050                                                'ImtaObs': (list: lists) [[d],[azm]] transformed via detector calibration from ImxyObs.
1051                                                'ImtaCalc': (list: lists [[d],[azm]] calculated d-spacing & azimuth from fit.
1052
1053======================  ======================  ====================================================
1054
1055.. _parmDict_table:
1056
1057.. index::
1058   single: Parameter dictionary
1059
1060Parameter Dictionary
1061-------------------------
1062
1063The parameter dictionary contains all of the variable parameters for the refinement.
1064The dictionary keys are the name of the parameter (<phase>:<hist>:<name>:<atom>).
1065It is prepared in two ways. When loaded from the tree
1066(in :meth:`GSASIIdataGUI.GSASII.MakeLSParmDict` and
1067:meth:`GSASIIIO.ExportBaseclass.loadParmDict`),
1068the values are lists with two elements: ``[value, refine flag]``
1069
1070When loaded from the GPX file (in
1071:func:`GSASIIstrMain.Refine` and :func:`GSASIIstrMain.SeqRefine`), the value in the
1072dict is the actual parameter value (usually a float, but sometimes a
1073letter or string flag value (such as I or A for iso/anisotropic).
1074
1075Texture implementation
1076------------------------------
1077
1078There are two different places where texture can be treated in GSAS-II.
1079One is for mitigating the effects of texture in a structural refinement.
1080The other is for texture characterization.
1081
1082For reducing the effect of texture in a structural refinement
1083there are entries labeled preferred orientation in each phase's
1084data tab. Two different approaches can be used for this, the March-Dollase
1085model and spherical harmonics.
1086
1087For the March-Dollase model, one axis in reciprocal space is designated as
1088unique (defaulting to the 001 axis) and reflections are corrected
1089according to the angle they make with this axis depending on
1090the March-Dollase ratio. (If unity, no correction is made).
1091The ratio can be greater than one or less than one depending on if
1092crystallites oriented along the designated axis are
1093overrepresented or underrepresented. For most crystal systems there is an
1094obvious choice for the direction of the unique axis and then only a single
1095term needs to be refined. If the number is close to 1, then the correction
1096is not needed.
1097
1098The second method for reducing the effect of texture in a structural
1099refinement is to create a crystallite orientation probability surface as an
1100expansion in terms spherical harmonic functions. Only functions consistent with
1101cylindrical diffraction suymmetry and having texture symmetry
1102consistent with the Laue class of phase are used and are allowed,
1103so the higher the symmetry the fewer terms that are available for a given spherical harmonics order.
1104To use this correction, select the lowest order that provides
1105refinable terms and perform a refinement. If the texture index remains close to
1106one, then the correction is not needed. If a significant improvement is
1107noted in the profile Rwp, one may wish to see if a higher order expansion
1108gives an even larger improvement.
1109
1110To characterize texture in a material, generally one needs data collected with the
1111sample at multiple orientations or, for TOF, with detectors at multiple
1112locations around the sample. In this case the detector orientation is given in
1113each histogram's Sample Parameters and the sample's orientation is described
1114with the Euler angles specifed on the phase's Texture tab, which is also
1115where the texture type (cylindrical, rolling,...) and the spherical
1116harmonic order is selected. This should not be used with a single dataset and
1117should not be used if the preferred orientations corrections are used.
1118
1119The coordinate system used for texture characterization is defined where
1120the sample coordinates (Psi, gamma) are defined with an instrument coordinate
1121system (I, J, K) such that K is normal to the diffraction plane and J is coincident with the
1122direction of the incident radiation beam toward the source. We further define
1123a standard set of right-handed goniometer eulerian angles (Omega, Chi, Phi) so that Omega and Phi are
1124rotations about K and Chi is a rotation about J when Omega = 0. Finally, as the sample
1125may be mounted so that the sample coordinate system (Is, Js, Ks) does not coincide with
1126the instrument coordinate system (I, J, K), we define three eulerian sample rotation angles
1127(Omega-s, Chi-s, Phi-s) that describe the rotation from (Is, Js, Ks) to (I, J, K). The sample rotation
1128angles are defined so that with the goniometer angles at zero Omega-s and Phi-s are rotations
1129about K and Chi-s is a rotation about J.
1130
1131Three typical examples:
1132
1133    1) Bragg-Brentano laboratory diffractometer: Chi=0
1134    2) Debye-Scherrer counter detector; sample capillary axis perpendicular to diffraction plane: Chi=90
1135    3) Debye-Scherrer 2D area detector positioned directly behind sample; sample capillary axis horizontal; Chi=0
1136
1137NB: The area detector azimuthal angle will equal 0 in horizontal plane to right as viewed from x-ray source and will equal
113890 at vertical "up" direction.
1139           
1140ISODISTORT implementation
1141------------------------------
1142
1143CIFs prepared with the ISODISTORT web site
1144https://stokes.byu.edu/iso/isodistort_version5.6.1/isodistort.php
1145[B. J. Campbell, H. T. Stokes, D. E. Tanner, and D. M. Hatch, "ISODISPLACE: An Internet Tool for Exploring Structural Distortions."
1146J. Appl. Cryst. 39, 607-614 (2006).] can be read into GSAS-II using import CIF. This will cause constraints to be established for
1147structural distortion modes read from the CIF. At present, of the five types of modes  only displacive(``_iso_displacivemode``...)
1148and occupancy (``_iso_occupancymode``...) are processed. Not yet processed: ``_iso_magneticmode``...,
1149``_iso_rotationalmode``... & ``_iso_strainmode``...
1150
1151The CIF importer :mod:`G2phase_CIF` implements class :class:`G2phase_CIF.CIFPhaseReader` which offers two methods associated
1152with ISODISTORT (ID) input. Method :meth:`G2phase_CIF.CIFPhaseReader.ISODISTORT_test` checks to see if a CIF block contains
1153the loops with ``_iso_displacivemode_label`` or  ``_iso_occupancymode_label`` items. If so, method
1154:meth:`G2phase_CIF.CIFPhaseReader.ISODISTORT_proc` is called to read and interpret them. The results are placed into the
1155reader object's ``.Phase`` class variable as a dict item with key ``'ISODISTORT'``.
1156
1157Note that each mode ID has a long label with a name such as  Pm-3m[1/2,1/2,1/2]R5+(a,a,0)[La:b:dsp]T1u(a). Function
1158:func:`G2phase_CIF.ISODISTORT_shortLbl` is used to create a short name for this, such as R5_T1u(a) which is made unique
1159by addition of _n if the short name is duplicated. As each mode is processed, a constraint corresponding to that mode is
1160created and is added to list in the reader object's ``.Constraints`` class variable. Items placed into that list can either
1161be a list, which corresponds to a function (new var) type :ref:`constraint definition <Constraints_table>` entry, or an item
1162can be a dict, which provides help information for each constraint.
1163
1164------------------------------
1165Displacive modes
1166------------------------------
1167
1168The coordinate variables, as named by ISODISTORT, are placed in ``.Phase['ISODISTORT']['IsoVarList']`` and the
1169corresponding :class:`GSASIIobj.G2VarObj` objects for each are placed in ``.Phase['ISODISTORT']['G2VarList']``.
1170The mode variables, as named by ISODISTORT, are placed in ``.Phase['ISODISTORT']['IsoModeList']`` and the
1171corresponding :class:`GSASIIobj.G2VarObj` objects for each are placed in ``.Phase['ISODISTORT']['G2ModeList']``.
1172[Use ``str(G2VarObj)`` to get the variable name from the G2VarObj object, but note that the phase number, *n*, for the prefix
1173"*n*::" cannot be determined as the phase number is not yet assigned.]
1174
1175Displacive modes are a bit complex in that they relate to delta displacements, relative to an offset value for each coordinate,
1176and because the modes are normalized. While GSAS-II also uses displacements,  these are added to the coordinates after
1177each refinement cycle and then the delta values are set to zero.
1178ISODISTORT uses fixed offsets (subtracted from the actual position
1179to obtain the delta values) that are taken from the parent structure coordinate and the initial offset value
1180(in ``_iso_deltacoordinate_value``) and these are placed in
1181``.Phase['ISODISTORT']['G2coordOffset']`` in the same order as ``.Phase['ISODISTORT']['G2ModeList']`` and
1182``.Phase['ISODISTORT']['IsoVarList']``.
1183
1184The normalization factors (which the delta values are divided by)
1185are taken from ``_iso_displacivemodenorm_value`` and are placed in ``.Phase['ISODISTORT']['NormList']`` in the same
1186order as as ``...['IsoModeList']`` and ``...['G2ModeList']``.
1187
1188The CIF contains a sparse matrix, from the ``loop_`` containing ``_iso_displacivemodematrix_value`` which provides the equations
1189for determining the mode values from the coordinates, that matrix is placed in ``.Phase['ISODISTORT']['Mode2VarMatrix']``.
1190The matrix is inverted to produce ``.Phase['ISODISTORT']['Var2ModeMatrix']``, which determines how to compute the
1191mode values from the delta coordinate values. These values are used for the in :func:`GSASIIconstrGUI.ShowIsoDistortCalc`,
1192which shows coordinate and mode values, the latter with s.u. values.
1193
1194------------------------------
1195Occupancy modes
1196------------------------------
1197
1198
1199The delta occupancy variables, as named by ISODISTORT, are placed in
1200``.Phase['ISODISTORT']['OccVarList']`` and the corresponding :class:`GSASIIobj.G2VarObj` objects for each are placed
1201in ``.Phase['ISODISTORT']['G2OccVarList']``. The mode variables, as named by ISODISTORT, are placed in
1202``.Phase['ISODISTORT']['OccModeList']`` and the corresponding :class:`GSASIIobj.G2VarObj` objects for each are placed
1203in ``.Phase['ISODISTORT']['G2OccModeList']``.
1204
1205Occupancy modes, like Displacive modes, are also refined as delta values.  However, GSAS-II directly refines the fractional
1206occupancies. Offset values for each atom, are taken from ``_iso_occupancy_formula`` and are placed in
1207``.Phase['ISODISTORT']['ParentOcc]``. (Offset values are subtracted from the actual position to obtain the delta values.)
1208Modes are normalized (where the mode values are divided by the normalization factor) are taken from ``_iso_occupancymodenorm_value``
1209and are placed in ``.Phase['ISODISTORT']['OccNormList']`` in the same order as as ``...['OccModeList']`` and
1210``...['G2OccModeList']``.
1211
1212The CIF contains a sparse matrix, from the ``loop_`` containing ``_iso_occupancymodematrix_value``, which provides the
1213equations for determining the mode values from the coordinates. That matrix is placed in ``.Phase['ISODISTORT']['Occ2VarMatrix']``.
1214The matrix is inverted to produce ``.Phase['ISODISTORT']['Var2OccMatrix']``, which determines how to compute the
1215mode values from the delta coordinate values.
1216
1217
1218------------------------------
1219Mode Computations
1220------------------------------
1221
1222Constraints are processed after the CIF has been read in :meth:`GSASIIdataGUI.GSASII.OnImportPhase` or 
1223:meth:`GSASIIscriptable.G2Project.add_phase` by moving them from the reader object's ``.Constraints``
1224class variable to the Constraints tree entry's ['Phase'] list (for list items defining constraints) or
1225the Constraints tree entry's ['_Explain'] dict (for dict items defining constraint help information)
1226
1227The information in ``.Phase['ISODISTORT']`` is used in :func:`GSASIIconstrGUI.ShowIsoDistortCalc` which shows coordinate and mode
1228values, the latter with s.u. values. This can be called from the Constraints and Phase/Atoms tree items.
1229
1230Before each refinement, constraints are processed as :ref:`described elsewhere <Constraints_processing>`. After a refinement
1231is complete, :func:`GSASIImapvars.PrintIndependentVars` shows the shifts and s.u.'s on the refined modes,
1232using GSAS-II values, but :func:`GSASIIstrIO.PrintISOmodes` prints the ISODISTORT modes as computed in the web site.
1233
1234
1235.. _ParameterLimits:
1236
1237.. index::
1238   single: Parameter limits
1239
1240Parameter Limits
1241------------------------------
1242
1243One of the most often requested "enhancements" for GSAS-II would be the inclusion
1244of constraints to force parameters such as occupancies or Uiso values to stay within
1245expected ranges. While it is possible for users to supply their own restraints that would
1246perform this by supplying an appropriate expression with the "General" restraints, the
1247GSAS-II authors do not feel that use of restraints or constraints are a good solution for
1248this common problem where parameters refine to non-physical values. This is because when
1249this occurs, most likely one of the following cases is occurring:
1250
1251#. there is a significant problem
1252   with the model, for example for an x-ray fit if an O atom is placed where a S is actually
1253   present, the Uiso will refine artificially small or the occupancy much larger than unity
1254   to try to compensate for the missing electrons; or
1255 
1256#. the data are simply insensitive
1257   to the parameter or combination of parameters, for example unless very high-Q data
1258   are included, the effects of a occupancy and Uiso value can have compensating effects,
1259   so an assumption must be made; likewise, with neutron data natural-abundance V atoms
1260   are nearly invisible due to weak coherent scattering. No parameters can be fit for a
1261   V atom with neutrons.
1262
1263#. the parameter is non-physical (such as a negative Uiso value) but within
1264   two sigma (sigma = standard uncertainty, aka e.s.d.) of a reasonable value,
1265   in which case the
1266   value is not problematic as it is experimentally indistinguishable from an
1267   expected value. 
1268
1269#. there is a systematic problem with the data (experimental error)
1270
1271In all these cases, this situation needs to be reviewed by a crystallographer to decide
1272how to best determine a structural model for these data. An implementation with a constraint
1273or restraint is likely to simply hide the problem from the user, making it more probable
1274that a poor model choice is obtained.
1275
1276What GSAS-II does implement is to allow users to specify ranges for parameters
1277that works by disabling
1278refinement of parameters that refine beyond either a lower limit or an upper limit, where
1279either or both may be optionally specified. Parameters limits are specified in the Controls
1280tree entry in dicts named as ``Controls['parmMaxDict']`` and ``Controls['parmMinDict']``, where
1281the keys are :class:`G2VarObj` objects corresponding to standard GSAS-II variable
1282(see :func:`getVarDescr` and :func:`CompileVarDesc`) names, where a
1283wildcard ('*') may optionally be used for histogram number or atom number
1284(phase number is intentionally not  allowed as a wildcard as it makes little sense
1285to group the same parameter together different phases). Note
1286that :func:`prmLookup` is used to see if a name matches a wildcard. The upper or lower limit
1287is placed into these dicts as a float value. These values can be edited using the window
1288created by the Calculate/"View LS parms" menu command or in scripting with the
1289:meth:`GSASIIscriptable.G2Project.set_Controls` function.
1290In the GUI, a checkbox labeled "match all histograms/atoms" is used to insert a wildcard
1291into the appropriate part of the variable name.
1292
1293When a refinement is conducted, routine :func:`GSASIIstrMain.dropOOBvars` is used to
1294find parameters that have refined to values outside their limits. If this occurs, the parameter
1295is set to the limiting value and the variable name is added to a list of frozen variables
1296(as a :class:`G2VarObj` objects) kept in a list in the
1297``Controls['parmFrozen']`` dict. In a sequential refinement, this is kept separate for
1298each histogram as a list in
1299``Controls['parmFrozen'][histogram]`` (where the key is the histogram name) or as a list in
1300``Controls['parmFrozen']['FrozenList']`` for a non-sequential fit.
1301This allows different variables
1302to be frozen in each section of a sequential fit.
1303Frozen parameters are not included in refinements through removal from the
1304list of parameters to be refined (``varyList``) in :func:`GSASIIstrMain.Refine` or
1305:func:`GSASIIstrMain.SeqRefine`.
1306The data window for the Controls tree item shows the number of Frozen variables and
1307the individual variables can be viewed with the Calculate/"View LS parms" menu window or
1308obtained with :meth:`GSASIIscriptable.G2Project.get_Frozen`.
1309Once a variable is frozen, it will not be refined in any
1310future refinements unless the the variable is removed (manually) from the list. This can also
1311be done with the Calculate/"View LS parms" menu window or
1312:meth:`GSASIIscriptable.G2Project.set_Frozen`.
1313
1314
1315.. seealso::
1316  :class:`G2VarObj`
1317  :func:`getVarDescr`
1318  :func:`CompileVarDesc`
1319  :func:`prmLookup`
1320  :class:`GSASIIctrlGUI.ShowLSParms`
1321  :class:`GSASIIctrlGUI.VirtualVarBox`
1322  :func:`GSASIIstrIO.SetUsedHistogramsAndPhases`
1323  :func:`GSASIIstrIO.SaveUpdatedHistogramsAndPhases`
1324  :func:`GSASIIstrIO.SetSeqResult`
1325  :func:`GSASIIstrMain.dropOOBvars`
1326  :meth:`GSASIIscriptable.G2Project.set_Controls`
1327  :meth:`GSASIIscriptable.G2Project.get_Frozen`
1328  :meth:`GSASIIscriptable.G2Project.set_Frozen`
1329
1330*Classes and routines*
1331----------------------
1332
1333'''
1334from __future__ import division, print_function
1335import platform
1336import re
1337import random as ran
1338import sys
1339import os.path
1340if '2' in platform.python_version_tuple()[0]:
1341    import cPickle
1342else:
1343    import pickle as cPickle
1344import GSASIIpath
1345import GSASIImath as G2mth
1346import GSASIIspc as G2spc
1347import numpy as np
1348
1349GSASIIpath.SetVersionNumber("$Revision: 5110 $")
1350
1351DefaultControls = {
1352    'deriv type':'analytic Hessian',
1353    'min dM/M':0.001,'shift factor':1.,'max cyc':3,'F**2':False,'SVDtol':1.e-6,
1354    'UsrReject':{'minF/sig':0.,'MinExt':0.01,'MaxDF/F':100.,'MaxD':500.,'MinD':0.05},
1355    'Copy2Next':False,'Reverse Seq':False,'HatomFix':False,
1356    'Author':'no name','newLeBail':False,
1357    'FreePrm1':'Sample humidity (%)',
1358    'FreePrm2':'Sample voltage (V)',
1359    'FreePrm3':'Applied load (MN)',
1360    'ShowCell':False,
1361    }
1362'''Values to be used as defaults for the initial contents of the ``Controls``
1363data tree item.
1364'''
1365def StripUnicode(string,subs='.'):
1366    '''Strip non-ASCII characters from strings
1367
1368    :param str string: string to strip Unicode characters from
1369    :param str subs: character(s) to place into string in place of each
1370      Unicode character. Defaults to '.'
1371
1372    :returns: a new string with only ASCII characters
1373    '''
1374    s = ''
1375    for c in string:
1376        if ord(c) < 128:
1377            s += c
1378        else:
1379            s += subs
1380    return s
1381#    return s.encode('ascii','replace')
1382
1383def MakeUniqueLabel(lbl,labellist):
1384    '''Make sure that every a label is unique against a list by adding
1385    digits at the end until it is not found in list.
1386
1387    :param str lbl: the input label
1388    :param list labellist: the labels that have already been encountered
1389    :returns: lbl if not found in labellist or lbl with ``_1-9`` (or
1390      ``_10-99``, etc.) appended at the end
1391    '''
1392    lbl = StripUnicode(lbl.strip(),'_')
1393    if not lbl: # deal with a blank label
1394        lbl = '_1'
1395    if lbl not in labellist:
1396        labellist.append(lbl)
1397        return lbl
1398    i = 1
1399    prefix = lbl
1400    if '_' in lbl:
1401        prefix = lbl[:lbl.rfind('_')]
1402        suffix = lbl[lbl.rfind('_')+1:]
1403        try:
1404            i = int(suffix)+1
1405        except: # suffix could not be parsed
1406            i = 1
1407            prefix = lbl
1408    while prefix+'_'+str(i) in labellist:
1409        i += 1
1410    else:
1411        lbl = prefix+'_'+str(i)
1412        labellist.append(lbl)
1413    return lbl
1414
1415PhaseIdLookup = {}
1416'''dict listing phase name and random Id keyed by sequential phase index as a str;
1417best to access this using :func:`LookupPhaseName`
1418'''
1419PhaseRanIdLookup = {}
1420'''dict listing phase sequential index keyed by phase random Id;
1421best to access this using :func:`LookupPhaseId`
1422'''
1423HistIdLookup = {}
1424'''dict listing histogram name and random Id, keyed by sequential histogram index as a str;
1425best to access this using :func:`LookupHistName`
1426'''
1427HistRanIdLookup = {}
1428'''dict listing histogram sequential index keyed by histogram random Id;
1429best to access this using :func:`LookupHistId`
1430'''
1431AtomIdLookup = {}
1432'''dict listing for each phase index as a str, the atom label and atom random Id,
1433keyed by atom sequential index as a str;
1434best to access this using :func:`LookupAtomLabel`
1435'''
1436AtomRanIdLookup = {}
1437'''dict listing for each phase the atom sequential index keyed by atom random Id;
1438best to access this using :func:`LookupAtomId`
1439'''
1440ShortPhaseNames = {}
1441'''a dict containing a possibly shortened and when non-unique numbered
1442version of the phase name. Keyed by the phase sequential index.
1443'''
1444ShortHistNames = {}
1445'''a dict containing a possibly shortened and when non-unique numbered
1446version of the histogram name. Keyed by the histogram sequential index.
1447'''
1448
1449#VarDesc = {}  # removed 1/30/19 BHT as no longer needed (I think)
1450#''' This dictionary lists descriptions for GSAS-II variables,
1451#as set in :func:`CompileVarDesc`. See that function for a description
1452#for how keys and values are written.
1453#'''
1454
1455reVarDesc = {}
1456''' This dictionary lists descriptions for GSAS-II variables where
1457keys are compiled regular expressions that will match the name portion
1458of a parameter name. Initialized in :func:`CompileVarDesc`.
1459'''
1460
1461reVarStep = {}
1462''' This dictionary lists the preferred step size for numerical
1463derivative computation w/r to a GSAS-II variable. Keys are compiled
1464regular expressions and values are the step size for that parameter.
1465Initialized in :func:`CompileVarDesc`.
1466'''
1467# create a default space group object for P1; N.B. fails when building documentation
1468try:
1469    P1SGData = G2spc.SpcGroup('P 1')[1] # data structure for default space group
1470except:
1471    pass
1472
1473def GetPhaseNames(fl):
1474    ''' Returns a list of phase names found under 'Phases' in GSASII gpx file
1475    NB: there is another one of these in GSASIIstrIO.py that uses the gpx filename
1476
1477    :param file fl: opened .gpx file
1478    :return: list of phase names
1479    '''
1480    PhaseNames = []
1481    while True:
1482        try:
1483            data = cPickle.load(fl)
1484        except EOFError:
1485            break
1486        datum = data[0]
1487        if 'Phases' == datum[0]:
1488            for datus in data[1:]:
1489                PhaseNames.append(datus[0])
1490    fl.seek(0)          #reposition file
1491    return PhaseNames
1492
1493def SetNewPhase(Name='New Phase',SGData=None,cell=None,Super=None):
1494    '''Create a new phase dict with default values for various parameters
1495
1496    :param str Name: Name for new Phase
1497
1498    :param dict SGData: space group data from :func:`GSASIIspc:SpcGroup`;
1499      defaults to data for P 1
1500
1501    :param list cell: unit cell parameter list; defaults to
1502      [1.0,1.0,1.0,90.,90,90.,1.]
1503
1504    '''
1505    if SGData is None: SGData = P1SGData
1506    if cell is None: cell=[1.0,1.0,1.0,90.,90.,90.,1.]
1507    phaseData = {
1508        'ranId':ran.randint(0,sys.maxsize),
1509        'General':{
1510            'Name':Name,
1511            'Type':'nuclear',
1512            'Modulated':False,
1513            'AtomPtrs':[3,1,7,9],
1514            'SGData':SGData,
1515            'Cell':[False,]+cell,
1516            'Pawley dmin':1.0,
1517            'Data plot type':'None',
1518            'SH Texture':{
1519                'Order':0,
1520                'Model':'cylindrical',
1521                'Sample omega':[False,0.0],
1522                'Sample chi':[False,0.0],
1523                'Sample phi':[False,0.0],
1524                'SH Coeff':[False,{}],
1525                'SHShow':False,
1526                'PFhkl':[0,0,1],
1527                'PFxyz':[0,0,1],
1528                'PlotType':'Pole figure',
1529                'Penalty':[['',],0.1,False,1.0]}},
1530        'Atoms':[],
1531        'Drawing':{},
1532        'Histograms':{},
1533        'Pawley ref':[],
1534        'RBModels':{},
1535        }
1536    if Super and Super.get('Use',False):
1537        phaseData['General'].update({'Modulated':True,'Super':True,'SuperSg':Super['ssSymb']})
1538        phaseData['General']['SSGData'] = G2spc.SSpcGroup(SGData,Super['ssSymb'])[1]
1539        phaseData['General']['SuperVec'] = [Super['ModVec'],False,Super['maxH']]
1540
1541    return phaseData
1542
1543def ReadCIF(URLorFile):
1544    '''Open a CIF, which may be specified as a file name or as a URL using PyCifRW
1545    (from James Hester).
1546    The open routine gets confused with DOS names that begin with a letter and colon
1547    "C:\\dir\" so this routine will try to open the passed name as a file and if that
1548    fails, try it as a URL
1549
1550    :param str URLorFile: string containing a URL or a file name. Code will try first
1551      to open it as a file and then as a URL.
1552
1553    :returns: a PyCifRW CIF object.
1554    '''
1555    import CifFile as cif # PyCifRW from James Hester
1556
1557    # alternate approach:
1558    #import urllib
1559    #ciffile = 'file:'+urllib.pathname2url(filename)
1560
1561    try:
1562        fp = open(URLorFile,'r')
1563        cf = cif.ReadCif(fp)
1564        fp.close()
1565        return cf
1566    except IOError:
1567        return cif.ReadCif(URLorFile)
1568
1569def TestIndexAll():
1570    '''Test if :func:`IndexAllIds` has been called to index all phases and
1571    histograms (this is needed before :func:`G2VarObj` can be used.
1572
1573    :returns: Returns True if indexing is needed.
1574    '''
1575    if PhaseIdLookup or AtomIdLookup or HistIdLookup:
1576        return False
1577    return True
1578       
1579def IndexAllIds(Histograms,Phases):
1580    '''Scan through the used phases & histograms and create an index
1581    to the random numbers of phases, histograms and atoms. While doing this,
1582    confirm that assigned random numbers are unique -- just in case lightning
1583    strikes twice in the same place.
1584
1585    Note: this code assumes that the atom random Id (ranId) is the last
1586    element each atom record.
1587
1588    This is called when phases & histograms are looked up
1589    in these places (only):
1590       
1591     * :func:`GSASIIstrIO.GetUsedHistogramsAndPhases` (which loads the histograms and phases from a GPX file),
1592     * :meth:`~GSASIIdataGUI.GSASII.GetUsedHistogramsAndPhasesfromTree` (which does the same thing but from the data tree.)
1593     * :meth:`~GSASIIdataGUI.GSASII.OnFileClose` (clears out an old project)
1594   
1595    Note that globals :data:`PhaseIdLookup` and :data:`PhaseRanIdLookup` are
1596    also set in :func:`AddPhase2Index` to temporarily assign a phase number
1597    as a phase is being imported.
1598 
1599    TODO: do we need a lookup for rigid body variables?
1600    '''
1601    # process phases and atoms
1602    PhaseIdLookup.clear()
1603    PhaseRanIdLookup.clear()
1604    AtomIdLookup.clear()
1605    AtomRanIdLookup.clear()
1606    ShortPhaseNames.clear()
1607    for ph in Phases:
1608        cx,ct,cs,cia = Phases[ph]['General']['AtomPtrs']
1609        ranId = Phases[ph]['ranId']
1610        while ranId in PhaseRanIdLookup:
1611            # Found duplicate random Id! note and reassign
1612            print ("\n\n*** Phase "+str(ph)+" has repeated ranId. Fixing.\n")
1613            Phases[ph]['ranId'] = ranId = ran.randint(0,sys.maxsize)
1614        pId = str(Phases[ph]['pId'])
1615        PhaseIdLookup[pId] = (ph,ranId)
1616        PhaseRanIdLookup[ranId] = pId
1617        shortname = ph  #[:10]
1618        while shortname in ShortPhaseNames.values():
1619            shortname = ph[:8] + ' ('+ pId + ')'
1620        ShortPhaseNames[pId] = shortname
1621        AtomIdLookup[pId] = {}
1622        AtomRanIdLookup[pId] = {}
1623        for iatm,at in enumerate(Phases[ph]['Atoms']):
1624            ranId = at[cia+8]
1625            while ranId in AtomRanIdLookup[pId]: # check for dups
1626                print ("\n\n*** Phase "+str(ph)+" atom "+str(iatm)+" has repeated ranId. Fixing.\n")
1627                at[cia+8] = ranId = ran.randint(0,sys.maxsize)
1628            AtomRanIdLookup[pId][ranId] = str(iatm)
1629            if Phases[ph]['General']['Type'] == 'macromolecular':
1630                label = '%s_%s_%s_%s'%(at[ct-1],at[ct-3],at[ct-4],at[ct-2])
1631            else:
1632                label = at[ct-1]
1633            AtomIdLookup[pId][str(iatm)] = (label,ranId)
1634    # process histograms
1635    HistIdLookup.clear()
1636    HistRanIdLookup.clear()
1637    ShortHistNames.clear()
1638    for hist in Histograms:
1639        ranId = Histograms[hist]['ranId']
1640        while ranId in HistRanIdLookup:
1641            # Found duplicate random Id! note and reassign
1642            print ("\n\n*** Histogram "+str(hist)+" has repeated ranId. Fixing.\n")
1643            Histograms[hist]['ranId'] = ranId = ran.randint(0,sys.maxsize)
1644        hId = str(Histograms[hist]['hId'])
1645        HistIdLookup[hId] = (hist,ranId)
1646        HistRanIdLookup[ranId] = hId
1647        shortname = hist[:15]
1648        while shortname in ShortHistNames.values():
1649            shortname = hist[:11] + ' ('+ hId + ')'
1650        ShortHistNames[hId] = shortname
1651
1652def AddPhase2Index(rdObj,filename):
1653    '''Add a phase to the index during reading
1654    Used where constraints are generated during import (ISODISTORT CIFs)       
1655    '''
1656    ranId = rdObj.Phase['ranId']
1657    ph = 'from  '+filename #  phase is not named yet
1658    if ranId in PhaseRanIdLookup: return
1659    maxph = -1
1660    for r in PhaseRanIdLookup:
1661        maxph = max(maxph,int(PhaseRanIdLookup[r]))
1662    PhaseRanIdLookup[ranId] = pId = str(maxph + 1)
1663    PhaseIdLookup[pId] = (ph,ranId)
1664    shortname = 'from '+ os.path.splitext((os.path.split(filename))[1])[0]
1665    while shortname in ShortPhaseNames.values():
1666        shortname = ph[:8] + ' ('+ pId + ')'
1667    ShortPhaseNames[pId] = shortname
1668    AtomIdLookup[pId] = {}
1669    AtomRanIdLookup[pId] = {}
1670    for iatm,at in enumerate(rdObj.Phase['Atoms']):
1671        ranId = at[-1]
1672        while ranId in AtomRanIdLookup[pId]: # check for dups
1673            print ("\n\n*** Phase "+str(ph)+" atom "+str(iatm)+" has repeated ranId. Fixing.\n")
1674            at[-1] = ranId = ran.randint(0,sys.maxsize)
1675        AtomRanIdLookup[pId][ranId] = str(iatm)
1676        #if Phases[ph]['General']['Type'] == 'macromolecular':
1677        #    label = '%s_%s_%s_%s'%(at[ct-1],at[ct-3],at[ct-4],at[ct-2])
1678        #else:
1679        #    label = at[ct-1]
1680        label = at[0]
1681        AtomIdLookup[pId][str(iatm)] = (label,ranId)
1682
1683def LookupAtomId(pId,ranId):
1684    '''Get the atom number from a phase and atom random Id
1685
1686    :param int/str pId: the sequential number of the phase
1687    :param int ranId: the random Id assigned to an atom
1688
1689    :returns: the index number of the atom (str)
1690    '''
1691    if not AtomRanIdLookup:
1692        raise Exception('Error: LookupAtomId called before IndexAllIds was run')
1693    if pId is None or pId == '':
1694        raise KeyError('Error: phase is invalid (None or blank)')
1695    pId = str(pId)
1696    if pId not in AtomRanIdLookup:
1697        raise KeyError('Error: LookupAtomId does not have phase '+pId)
1698    if ranId not in AtomRanIdLookup[pId]:
1699        raise KeyError('Error: LookupAtomId, ranId '+str(ranId)+' not in AtomRanIdLookup['+pId+']')
1700    return AtomRanIdLookup[pId][ranId]
1701
1702def LookupAtomLabel(pId,index):
1703    '''Get the atom label from a phase and atom index number
1704
1705    :param int/str pId: the sequential number of the phase
1706    :param int index: the index of the atom in the list of atoms
1707
1708    :returns: the label for the atom (str) and the random Id of the atom (int)
1709    '''
1710    if not AtomIdLookup:
1711        raise Exception('Error: LookupAtomLabel called before IndexAllIds was run')
1712    if pId is None or pId == '':
1713        raise KeyError('Error: phase is invalid (None or blank)')
1714    pId = str(pId)
1715    if pId not in AtomIdLookup:
1716        raise KeyError('Error: LookupAtomLabel does not have phase '+pId)
1717    if index not in AtomIdLookup[pId]:
1718        raise KeyError('Error: LookupAtomLabel, ranId '+str(index)+' not in AtomRanIdLookup['+pId+']')
1719    return AtomIdLookup[pId][index]
1720
1721def LookupPhaseId(ranId):
1722    '''Get the phase number and name from a phase random Id
1723
1724    :param int ranId: the random Id assigned to a phase
1725    :returns: the sequential Id (pId) number for the phase (str)
1726    '''
1727    if not PhaseRanIdLookup:
1728        raise Exception('Error: LookupPhaseId called before IndexAllIds was run')
1729    if ranId not in PhaseRanIdLookup:
1730        raise KeyError('Error: LookupPhaseId does not have ranId '+str(ranId))
1731    return PhaseRanIdLookup[ranId]
1732
1733def LookupPhaseName(pId):
1734    '''Get the phase number and name from a phase Id
1735
1736    :param int/str pId: the sequential assigned to a phase
1737    :returns:  (phase,ranId) where phase is the name of the phase (str)
1738      and ranId is the random # id for the phase (int)
1739    '''
1740    if not PhaseIdLookup:
1741        raise Exception('Error: LookupPhaseName called before IndexAllIds was run')
1742    if pId is None or pId == '':
1743        raise KeyError('Error: phase is invalid (None or blank)')
1744    pId = str(pId)
1745    if pId not in PhaseIdLookup:
1746        raise KeyError('Error: LookupPhaseName does not have index '+pId)
1747    return PhaseIdLookup[pId]
1748
1749def LookupHistId(ranId):
1750    '''Get the histogram number and name from a histogram random Id
1751
1752    :param int ranId: the random Id assigned to a histogram
1753    :returns: the sequential Id (hId) number for the histogram (str)
1754    '''
1755    if not HistRanIdLookup:
1756        raise Exception('Error: LookupHistId called before IndexAllIds was run')
1757    if ranId not in HistRanIdLookup:
1758        raise KeyError('Error: LookupHistId does not have ranId '+str(ranId))
1759    return HistRanIdLookup[ranId]
1760
1761def LookupHistName(hId):
1762    '''Get the histogram number and name from a histogram Id
1763
1764    :param int/str hId: the sequential assigned to a histogram
1765    :returns:  (hist,ranId) where hist is the name of the histogram (str)
1766      and ranId is the random # id for the histogram (int)
1767    '''
1768    if not HistIdLookup:
1769        raise Exception('Error: LookupHistName called before IndexAllIds was run')
1770    if hId is None or hId == '':
1771        raise KeyError('Error: histogram is invalid (None or blank)')
1772    hId = str(hId)
1773    if hId not in HistIdLookup:
1774        raise KeyError('Error: LookupHistName does not have index '+hId)
1775    return HistIdLookup[hId]
1776
1777def fmtVarDescr(varname):
1778    '''Return a string with a more complete description for a GSAS-II variable
1779
1780    :param str varname: A full G2 variable name with 2 or 3 or 4
1781       colons (<p>:<h>:name[:<a>] or <p>::RBname:<r>:<t>])
1782
1783    :returns: a string with the description
1784    '''
1785    s,l = VarDescr(varname)
1786    return s+": "+l
1787
1788def VarDescr(varname):
1789    '''Return two strings with a more complete description for a GSAS-II variable
1790
1791    :param str name: A full G2 variable name with 2 or 3 or 4
1792       colons (<p>:<h>:name[:<a>] or <p>::RBname:<r>:<t>])
1793
1794    :returns: (loc,meaning) where loc describes what item the variable is mapped
1795      (phase, histogram, etc.) and meaning describes what the variable does.
1796    '''
1797
1798    # special handling for parameter names without a colon
1799    # for now, assume self-defining
1800    if varname.find(':') == -1:
1801        return "Global",varname
1802
1803    l = getVarDescr(varname)
1804    if not l:
1805        return ("invalid variable name ("+str(varname)+")!"),""
1806#        return "invalid variable name!",""
1807
1808    if not l[-1]:
1809        l[-1] = "(variable needs a definition! Set it in CompileVarDesc)"
1810
1811    if len(l) == 3:         #SASD variable name!
1812        s = 'component:'+l[1]
1813        return s,l[-1]
1814    s = ""
1815    if l[0] is not None and l[1] is not None: # HAP: keep short
1816        if l[2] == "Scale": # fix up ambigous name
1817            l[5] = "Phase fraction"
1818        if l[0] == '*':
1819            lbl = 'Seq. ref.'
1820        else:
1821            lbl = ShortPhaseNames.get(l[0],'? #'+str(l[0]))
1822        if l[1] == '*':
1823            hlbl = 'Seq. ref.'
1824        else:
1825            hlbl = ShortHistNames.get(l[1],'? #'+str(l[1]))
1826        if hlbl[:4] == 'HKLF':
1827            hlbl = 'Xtl='+hlbl[5:]
1828        elif hlbl[:4] == 'PWDR':
1829            hlbl = 'Pwd='+hlbl[5:]
1830        else:
1831            hlbl = 'Hist='+hlbl
1832        s = "Ph="+str(lbl)+" * "+str(hlbl)
1833    else:
1834        if l[2] == "Scale": # fix up ambigous name: must be scale factor, since not HAP
1835            l[5] = "Scale factor"
1836        if l[2] == 'Back': # background parameters are "special", alas
1837            s = 'Hist='+ShortHistNames.get(l[1],'? #'+str(l[1]))
1838            l[-1] += ' #'+str(l[3])
1839        elif l[4] is not None: # rigid body parameter or modulation parm
1840            lbl = ShortPhaseNames.get(l[0],'phase?')
1841            if 'RB' in l[2]:    #rigid body parm
1842                s = "RB body #"+str(l[3])+" (type "+str(l[4])+") in "+str(lbl) + ','
1843            else: #modulation parm
1844                s = 'Atom %s wave %s in %s'%(LookupAtomLabel(l[0],l[3])[0],l[4],lbl)
1845        elif l[3] is not None: # atom parameter,
1846            lbl = ShortPhaseNames.get(l[0],'phase?')
1847            try:
1848                albl = LookupAtomLabel(l[0],l[3])[0]
1849            except KeyError:
1850                albl = 'Atom?'
1851            s = "Atom "+str(albl)+" in "+str(lbl)
1852        elif l[0] == '*':
1853            s = "All phases "
1854        elif l[0] is not None:
1855            lbl = ShortPhaseNames.get(l[0],'phase?')
1856            s = "Phase "+str(lbl)
1857        elif l[1] == '*':
1858            s = 'All hists'
1859        elif l[1] is not None:
1860            hlbl = ShortHistNames.get(l[1],'? #'+str(l[1]))
1861            if hlbl[:4] == 'HKLF':
1862                hlbl = 'Xtl='+hlbl[5:]
1863            elif hlbl[:4] == 'PWDR':
1864                hlbl = 'Pwd='+hlbl[5:]
1865            else:
1866                hlbl = 'Hist='+hlbl
1867            s = str(hlbl)
1868    if not s:
1869        s = 'Global'
1870    return s,l[-1]
1871
1872def getVarDescr(varname):
1873    '''Return a short description for a GSAS-II variable
1874
1875    :param str name: A full G2 variable name with 2 or 3 or 4
1876       colons (<p>:<h>:name[:<a1>][:<a2>])
1877
1878    :returns: a six element list as [`p`,`h`,`name`,`a1`,`a2`,`description`],
1879      where `p`, `h`, `a1`, `a2` are str values or `None`, for the phase number,
1880      the histogram number and the atom number; `name` will always be
1881      a str; and `description` is str or `None`.
1882      If the variable name is incorrectly formed (for example, wrong
1883      number of colons), `None` is returned instead of a list.
1884    '''
1885    l = varname.split(':')
1886    if len(l) == 2:     #SASD parameter name
1887        return varname,l[0],getDescr(l[1])
1888    if len(l) == 3:
1889        l += [None,None]
1890    elif len(l) == 4:
1891        l += [None]
1892    elif len(l) != 5:
1893        return None
1894    for i in (0,1,3,4):
1895        if l[i] == "":
1896            l[i] = None
1897    l += [getDescr(l[2])]
1898    return l
1899
1900def CompileVarDesc():
1901    '''Set the values in the variable lookup tables
1902    (:attr:`reVarDesc` and :attr:`reVarStep`).
1903    This is called in :func:`getDescr` and :func:`getVarStep` so this
1904    initialization is always done before use.
1905
1906    Note that keys may contain regular expressions, where '[xyz]'
1907    matches 'x' 'y' or 'z' (equivalently '[x-z]' describes this as range
1908    of values). '.*' matches any string. For example::
1909
1910    'AUiso':'Atomic isotropic displacement parameter',
1911
1912    will match variable ``'p::AUiso:a'``.
1913    If parentheses are used in the key, the contents of those parentheses can be
1914    used in the value, such as::
1915
1916    'AU([123][123])':'Atomic anisotropic displacement parameter U\\1',
1917
1918    will match ``AU11``, ``AU23``,... and `U11`, `U23` etc will be displayed
1919    in the value when used.
1920
1921    '''
1922    if reVarDesc: return # already done
1923    for key,value in {
1924        # derived or other sequential vars
1925        '([abc])$' : 'Lattice parameter, \\1, from Ai and Djk', # N.B. '$' prevents match if any characters follow
1926        u'\u03B1' : u'Lattice parameter, \u03B1, from Ai and Djk',
1927        u'\u03B2' : u'Lattice parameter, \u03B2, from Ai and Djk',
1928        u'\u03B3' : u'Lattice parameter, \u03B3, from Ai and Djk',
1929        # ambiguous, alas:
1930        'Scale' : 'Phase or Histogram scale factor',
1931        # Phase vars (p::<var>)
1932        'A([0-5])' : ('Reciprocal metric tensor component \\1',1e-5),
1933        '[vV]ol' : 'Unit cell volume', # probably an error that both upper and lower case are used
1934        # Atom vars (p::<var>:a)
1935        'dA([xyz])$' : ('change to atomic coordinate, \\1',1e-6),
1936        'A([xyz])$' : '\\1 fractional atomic coordinate',
1937        'AUiso':('Atomic isotropic displacement parameter',1e-4),
1938        'AU([123][123])':('Atomic anisotropic displacement parameter U\\1',1e-4),
1939        'Afrac': ('Atomic site fraction parameter',1e-5),
1940        'Amul': 'Atomic site multiplicity value',
1941        'AM([xyz])$' : 'Atomic magnetic moment parameter, \\1',
1942        # Hist (:h:<var>) & Phase (HAP) vars (p:h:<var>)
1943        'Back': 'Background term',
1944        'BkPkint;(.*)':'Background peak #\\1 intensity',
1945        'BkPkpos;(.*)':'Background peak #\\1 position',
1946        'BkPksig;(.*)':'Background peak #\\1 Gaussian width',
1947        'BkPkgam;(.*)':'Background peak #\\1 Cauchy width',
1948#        'Back File' : 'Background file name',
1949        'BF mult' : 'Background file multiplier',
1950        'Bab([AU])': 'Babinet solvent scattering coef. \\1',
1951        'D([123][123])' : 'Anisotropic strain coef. \\1',
1952        'Extinction' : 'Extinction coef.',
1953        'MD' : 'March-Dollase coef.',
1954        'Mustrain;.*' : 'Microstrain coef.',
1955        'Size;.*' : 'Crystallite size value',
1956        'eA$' : 'Cubic mustrain value',
1957        'Ep$' : 'Primary extinction',
1958        'Es$' : 'Secondary type II extinction',
1959        'Eg$' : 'Secondary type I extinction',
1960        'Flack' : 'Flack parameter',
1961        'TwinFr' : 'Twin fraction',
1962        'Layer Disp'  : 'Layer displacement along beam',
1963        #Histogram vars (:h:<var>)
1964        'Absorption' : 'Absorption coef.',
1965        'LayerDisp'  : 'Bragg-Brentano Layer displacement',
1966        'Displace([XY])' : ('Debye-Scherrer sample displacement \\1',0.1),
1967        'Lam' : ('Wavelength',1e-6),
1968        'I\\(L2\\)\\/I\\(L1\\)' : ('Ka2/Ka1 intensity ratio',0.001),
1969        'Polariz\\.' : ('Polarization correction',1e-3),
1970        'SH/L' : ('FCJ peak asymmetry correction',1e-4),
1971        '([UVW])$' : ('Gaussian instrument broadening \\1',1e-5),
1972        '([XYZ])$' : ('Cauchy instrument broadening \\1',1e-5),
1973        'Zero' : 'Debye-Scherrer zero correction',
1974        'Shift' : 'Bragg-Brentano sample displ.',
1975        'SurfRoughA' : 'Bragg-Brenano surface roughness A',
1976        'SurfRoughB' : 'Bragg-Brenano surface roughness B',
1977        'Transparency' : 'Bragg-Brentano sample tranparency',
1978        'DebyeA' : 'Debye model amplitude',
1979        'DebyeR' : 'Debye model radius',
1980        'DebyeU' : 'Debye model Uiso',
1981        'RBV.*' : 'Vector rigid body parameter',
1982        'RBVO([aijk])' : 'Vector rigid body orientation parameter \\1',
1983        'RBVP([xyz])' : 'Vector rigid body \\1 position parameter',
1984        'RBVf' : 'Vector rigid body site fraction',
1985        'RBV([TLS])([123AB][123AB])' : 'Residue rigid body group disp. param.',
1986        'RBVU' : 'Residue rigid body group Uiso param.',
1987        'RBRO([aijk])' : 'Residue rigid body orientation parameter \\1',
1988        'RBRP([xyz])' : 'Residue rigid body \\1 position parameter',
1989        'RBRTr;.*' : 'Residue rigid body torsion parameter',
1990        'RBRf' : 'Residue rigid body site fraction',
1991        'RBR([TLS])([123AB][123AB])' : 'Residue rigid body group disp. param.',
1992        'RBRU' : 'Residue rigid body group Uiso param.',
1993        'constr([0-9]*)' : 'Parameter from constraint',
1994        'nv-([^_]+)_*' : 'New variable constraint parameter named \\1',
1995        # supersymmetry parameters  p::<var>:a:o 'Flen','Fcent'?
1996        'mV([0-2])$' : 'Modulation vector component \\1',
1997        'Fsin'  :   'Sin site fraction modulation',
1998        'Fcos'  :   'Cos site fraction modulation',
1999        'Fzero'  :   'Crenel function offset',      #may go away
2000        'Fwid'   :   'Crenel function width',
2001        'Tmin'   :   'ZigZag/Block min location',
2002        'Tmax'   :   'ZigZag/Block max location',
2003        '([XYZ])max': 'ZigZag/Block max value for \\1',
2004        '([XYZ])sin'  : 'Sin position wave for \\1',
2005        '([XYZ])cos'  : 'Cos position wave for \\1',
2006        'U([123][123])sin$' :  'Sin thermal wave for U\\1',
2007        'U([123][123])cos$' :  'Cos thermal wave for U\\1',
2008        'M([XYZ])sin$' :  'Sin mag. moment wave for \\1',
2009        'M([XYZ])cos$' :  'Cos mag. moment wave for \\1',
2010        # PDF peak parms (l:<var>;l = peak no.)
2011        'PDFpos'  : 'PDF peak position',
2012        'PDFmag'  : 'PDF peak magnitude',
2013        'PDFsig'  : 'PDF peak std. dev.',
2014        # SASD vars (l:<var>;l = component)
2015        'Aspect ratio' : 'Particle aspect ratio',
2016        'Length' : 'Cylinder length',
2017        'Diameter' : 'Cylinder/disk diameter',
2018        'Thickness' : 'Disk thickness',
2019        'Shell thickness' : 'Multiplier to get inner(<1) or outer(>1) sphere radius',
2020        'Dist' : 'Interparticle distance',
2021        'VolFr' : 'Dense scatterer volume fraction',
2022        'epis' : 'Sticky sphere epsilon',
2023        'Sticky' : 'Stickyness',
2024        'Depth' : 'Well depth',
2025        'Width' : 'Well width',
2026        'Volume' : 'Particle volume',
2027        'Radius' : 'Sphere/cylinder/disk radius',
2028        'Mean' : 'Particle mean radius',
2029        'StdDev' : 'Standard deviation in Mean',
2030        'G$': 'Guinier prefactor',
2031        'Rg$': 'Guinier radius of gyration',
2032        'B$': 'Porod prefactor',
2033        'P$': 'Porod power',
2034        'Cutoff': 'Porod cutoff',
2035        'PkInt': 'Bragg peak intensity',
2036        'PkPos': 'Bragg peak position',
2037        'PkSig': 'Bragg peak sigma',
2038        'PkGam': 'Bragg peak gamma',
2039        'e([12][12])' : 'strain tensor e\\1',   # strain vars e11, e22, e12
2040        'Dcalc': 'Calc. d-spacing',
2041        'Back$': 'background parameter',
2042        'pos$': 'peak position',
2043        'int$': 'peak intensity',
2044        'WgtFrac':'phase weight fraction',
2045        'alpha':'TOF profile term',
2046        'alpha-[01]':'Pink profile term',
2047        'beta-[01q]':'TOF/Pink profile term',
2048        'sig-[012q]':'TOF profile term',
2049        'dif[ABC]':'TOF to d-space calibration',
2050        'C\\([0-9]*,[0-9]*\\)' : 'spherical harmonics preferred orientation coef.',
2051        'Pressure': 'Pressure level for measurement in MPa',
2052        'Temperature': 'T value for measurement, K',
2053        'FreePrm([123])': 'User defined measurement parameter \\1',
2054        'Gonio. radius': 'Distance from sample to detector, mm',
2055        }.items():
2056        # Needs documentation: HAP: LeBail, newLeBail
2057        # hist: Azimuth, Chi, Omega, Phi, Bank, nDebye, nPeaks
2058       
2059        if len(value) == 2:
2060            #VarDesc[key] = value[0]
2061            reVarDesc[re.compile(key)] = value[0]
2062            reVarStep[re.compile(key)] = value[1]
2063        else:
2064            #VarDesc[key] = value
2065            reVarDesc[re.compile(key)] = value
2066
2067def removeNonRefined(parmList):
2068    '''Remove items from variable list that are not refined and should not
2069    appear as options for constraints
2070
2071    :param list parmList: a list of strings of form "p:h:VAR:a" where
2072      VAR is the variable name
2073
2074    :returns: a list after removing variables where VAR matches a
2075      entry in local variable NonRefinedList
2076    '''
2077    NonRefinedList = ['Omega','Type','Chi','Phi', 'Azimuth','Gonio. radius',
2078                          'Lam1','Lam2','Back','Temperature','Pressure',
2079                          'FreePrm1','FreePrm2','FreePrm3',
2080                          'Source','nPeaks','LeBail','newLeBail','Bank',
2081                          'nDebye', #'',
2082                    ]
2083    return [prm for prm in parmList if prm.split(':')[2] not in NonRefinedList]
2084       
2085def getDescr(name):
2086    '''Return a short description for a GSAS-II variable
2087
2088    :param str name: The descriptive part of the variable name without colons (:)
2089
2090    :returns: a short description or None if not found
2091    '''
2092
2093    CompileVarDesc() # compile the regular expressions, if needed
2094    for key in reVarDesc:
2095        m = key.match(name)
2096        if m:
2097            reVarDesc[key]
2098            return m.expand(reVarDesc[key])
2099    return None
2100
2101def getVarStep(name,parmDict=None):
2102    '''Return a step size for computing the derivative of a GSAS-II variable
2103
2104    :param str name: A complete variable name (with colons, :)
2105    :param dict parmDict: A dict with parameter values or None (default)
2106
2107    :returns: a float that should be an appropriate step size, either from
2108      the value supplied in :func:`CompileVarDesc` or based on the value for
2109      name in parmDict, if supplied. If not found or the value is zero,
2110      a default value of 1e-5 is used. If parmDict is None (default) and
2111      no value is provided in :func:`CompileVarDesc`, then None is returned.
2112    '''
2113    CompileVarDesc() # compile the regular expressions, if needed
2114    for key in reVarStep:
2115        m = key.match(name)
2116        if m:
2117            return reVarStep[key]
2118    if parmDict is None: return None
2119    val = parmDict.get(key,0.0)
2120    if abs(val) > 0.05:
2121        return abs(val)/1000.
2122    else:
2123        return 1e-5
2124
2125def GenWildCard(varlist):
2126    '''Generate wildcard versions of G2 variables. These introduce '*'
2127    for a phase, histogram or atom number (but only for one of these
2128    fields) but only when there is more than one matching variable in the
2129    input variable list. So if the input is this::
2130
2131      varlist = ['0::AUiso:0', '0::AUiso:1', '1::AUiso:0']
2132
2133    then the output will be this::
2134
2135       wildList = ['*::AUiso:0', '0::AUiso:*']
2136
2137    :param list varlist: an input list of GSAS-II variable names
2138      (such as 0::AUiso:0)
2139
2140    :returns: wildList, the generated list of wild card variable names.
2141    '''
2142    wild = []
2143    for i in (0,1,3):
2144        currentL = varlist[:]
2145        while currentL:
2146            item1 = currentL.pop(0)
2147            i1splt = item1.split(':')
2148            if i >= len(i1splt): continue
2149            if i1splt[i]:
2150                nextL = []
2151                i1splt[i] = '[0-9]+'
2152                rexp = re.compile(':'.join(i1splt))
2153                matchlist = [item1]
2154                for nxtitem in currentL:
2155                    if rexp.match(nxtitem):
2156                        matchlist += [nxtitem]
2157                    else:
2158                        nextL.append(nxtitem)
2159                if len(matchlist) > 1:
2160                    i1splt[i] = '*'
2161                    wild.append(':'.join(i1splt))
2162                currentL = nextL
2163    return wild
2164
2165def LookupWildCard(varname,varlist):
2166    '''returns a list of variable names from list varname
2167    that match wildcard name in varname
2168
2169    :param str varname: a G2 variable name containing a wildcard
2170      (such as \\*::var)
2171    :param list varlist: the list of all variable names used in
2172      the current project
2173    :returns: a list of matching GSAS-II variables (may be empty)
2174    '''
2175    rexp = re.compile(varname.replace('*','[0-9]+'))
2176    return sorted([var for var in varlist if rexp.match(var)])
2177
2178def prmLookup(name,prmDict):
2179    '''Looks for a parameter in a min/max dictionary, optionally
2180    considering a wild card for histogram or atom number (use of
2181    both will never occur at the same time).
2182
2183    :param name: a GSAS-II parameter name (str, see :func:`getVarDescr`
2184      and :func:`CompileVarDesc`) or a :class:`G2VarObj` object.
2185    :param dict prmDict: a min/max dictionary, (parmMinDict
2186      or parmMaxDict in Controls) where keys are :class:`G2VarObj`
2187      objects.
2188    :returns: Two values, (**matchname**, **value**), are returned where:
2189
2190       * **matchname** *(str)* is the :class:`G2VarObj` object
2191         corresponding to the actual matched name,
2192         which could contain a wildcard even if **name** does not; and
2193       * **value** *(float)* which contains the parameter limit.
2194    '''
2195    for key,value in prmDict.items():
2196        if str(key) == str(name): return key,value
2197        if key == name: return key,value
2198    return None,None
2199       
2200
2201def _lookup(dic,key):
2202    '''Lookup a key in a dictionary, where None returns an empty string
2203    but an unmatched key returns a question mark. Used in :class:`G2VarObj`
2204    '''
2205    if key is None:
2206        return ""
2207    elif key == "*":
2208        return "*"
2209    else:
2210        return dic.get(key,'?')
2211
2212def SortVariables(varlist):
2213    '''Sorts variable names in a sensible manner
2214    '''
2215    def cvnnums(var):
2216        v = []
2217        for i in var.split(':'):
2218#            if i == '' or i == '*':
2219#                v.append(-1)
2220#                continue
2221            try:
2222                v.append(int(i))
2223            except:
2224                v.append(-1)
2225        return v
2226    return sorted(varlist,key=cvnnums)
2227
2228class G2VarObj(object):
2229    '''Defines a GSAS-II variable either using the phase/atom/histogram
2230    unique Id numbers or using a character string that specifies
2231    variables by phase/atom/histogram number (which can change).
2232    Note that :func:`GSASIIstrIO.GetUsedHistogramsAndPhases`,
2233    which calls :func:`IndexAllIds` (or
2234    :func:`GSASIIscriptable.G2Project.index_ids`) should be used to
2235    (re)load the current Ids
2236    before creating or later using the G2VarObj object.
2237
2238    This can store rigid body variables, but does not translate the residue # and
2239    body # to/from random Ids
2240
2241    A :class:`G2VarObj` object can be created with a single parameter:
2242
2243    :param str/tuple varname: a single value can be used to create a :class:`G2VarObj`
2244      object. If a string, it must be of form "p:h:var" or "p:h:var:a", where
2245
2246     * p is the phase number (which may be left blank or may be '*' to indicate all phases);
2247     * h is the histogram number (which may be left blank or may be '*' to indicate all histograms);
2248     * a is the atom number (which may be left blank in which case the third colon is omitted).
2249       The atom number can be specified as '*' if a phase number is specified (not as '*').
2250       For rigid body variables, specify a will be a string of form "residue:body#"
2251
2252      Alternately a single tuple of form (Phase,Histogram,VarName,AtomID) can be used, where
2253      Phase, Histogram, and AtomID are None or are ranId values (or one can be '*')
2254      and VarName is a string. Note that if Phase is '*' then the AtomID is an atom number.
2255      For a rigid body variables, AtomID is a string of form "residue:body#".
2256
2257    If four positional arguments are supplied, they are:
2258
2259    :param str/int phasenum: The number for the phase (or None or '*')
2260    :param str/int histnum: The number for the histogram (or None or '*')
2261    :param str varname: a single value can be used to create a :class:`G2VarObj`
2262    :param str/int atomnum: The number for the atom (or None or '*')
2263
2264    '''
2265    IDdict = {}
2266    IDdict['phases'] = {}
2267    IDdict['hists'] = {}
2268    IDdict['atoms'] = {}
2269    def __init__(self,*args):
2270        self.phase = None
2271        self.histogram = None
2272        self.name = ''
2273        self.atom = None
2274        if len(args) == 1 and (type(args[0]) is list or type(args[0]) is tuple) and len(args[0]) == 4:
2275            # single arg with 4 values
2276            self.phase,self.histogram,self.name,self.atom = args[0]
2277        elif len(args) == 1 and ':' in args[0]:
2278            #parse a string
2279            lst = args[0].split(':')
2280            if lst[0] == '*':
2281                self.phase = '*'
2282                if len(lst) > 3:
2283                    self.atom = lst[3]
2284                self.histogram = HistIdLookup.get(lst[1],[None,None])[1]
2285            elif lst[1] == '*':
2286                self.histogram = '*'
2287                self.phase = PhaseIdLookup.get(lst[0],[None,None])[1]
2288            else:
2289                self.histogram = HistIdLookup.get(lst[1],[None,None])[1]
2290                self.phase = PhaseIdLookup.get(lst[0],[None,None])[1]
2291                if len(lst) == 4:
2292                    if lst[3] == '*':
2293                        self.atom = '*'
2294                    else:
2295                        self.atom = AtomIdLookup[lst[0]].get(lst[3],[None,None])[1]
2296                elif len(lst) == 5:
2297                    self.atom = lst[3]+":"+lst[4]
2298                elif len(lst) == 3:
2299                    pass
2300                else:
2301                    raise Exception("Incorrect number of colons in var name "+str(args[0]))
2302            self.name = lst[2]
2303        elif len(args) == 4:
2304            if args[0] == '*':
2305                self.phase = '*'
2306                self.atom = args[3]
2307            else:
2308                self.phase = PhaseIdLookup.get(str(args[0]),[None,None])[1]
2309                if args[3] == '*':
2310                    self.atom = '*'
2311                elif args[0] is not None:
2312                    self.atom = AtomIdLookup[args[0]].get(str(args[3]),[None,None])[1]
2313            if args[1] == '*':
2314                self.histogram = '*'
2315            else:
2316                self.histogram = HistIdLookup.get(str(args[1]),[None,None])[1]
2317            self.name = args[2]
2318        else:
2319            raise Exception("Incorrectly called GSAS-II parameter name")
2320
2321        #print "DEBUG: created ",self.phase,self.histogram,self.name,self.atom
2322
2323    def __str__(self):
2324        return self.varname()
2325
2326    def __hash__(self):
2327        'Allow G2VarObj to be a dict key by implementing hashing'
2328        return hash(self.varname())
2329
2330    def varname(self,hist=None):
2331        '''Formats the GSAS-II variable name as a "traditional" GSAS-II variable
2332        string (p:h:<var>:a) or (p:h:<var>)
2333
2334        :param str/int hist: if specified, overrides the histogram number
2335          with the specified value
2336        :returns: the variable name as a str
2337        '''
2338        a = ""
2339        if self.phase == "*":
2340            ph = "*"
2341            if self.atom:
2342                a = ":" + str(self.atom)
2343        else:
2344            ph = _lookup(PhaseRanIdLookup,self.phase)
2345            if self.atom == '*':
2346                a = ':*'
2347            elif self.atom:
2348                if ":" in str(self.atom):
2349                    a = ":" + str(self.atom)
2350                elif ph in AtomRanIdLookup:
2351                    a = ":" + AtomRanIdLookup[ph].get(self.atom,'?')
2352                else:
2353                    a = ":?"
2354        if hist is not None and self.histogram:
2355            hist = str(hist)
2356        elif self.histogram == "*":
2357            hist = "*"
2358        else:
2359            hist = _lookup(HistRanIdLookup,self.histogram)
2360        s = (ph + ":" + hist + ":" + str(self.name)) + a
2361        return s
2362
2363    def __repr__(self):
2364        '''Return the detailed contents of the object
2365        '''
2366        s = "<"
2367        if self.phase == '*':
2368            s += "Phases: all; "
2369            if self.atom is not None:
2370                if ":" in str(self.atom):
2371                    s += "Rigid body" + str(self.atom) + "; "
2372                else:
2373                    s += "Atom #" + str(self.atom) + "; "
2374        elif self.phase is not None:
2375            ph =  _lookup(PhaseRanIdLookup,self.phase)
2376            s += "Phase: rId=" + str(self.phase) + " (#"+ ph + "); "
2377            if self.atom == '*':
2378                s += "Atoms: all; "
2379            elif ":" in str(self.atom):
2380                s += "Rigid body" + str(self.atom) + "; "
2381            elif self.atom is not None:
2382                s += "Atom rId=" + str(self.atom)
2383                if ph in AtomRanIdLookup:
2384                    s += " (#" + AtomRanIdLookup[ph].get(self.atom,'?') + "); "
2385                else:
2386                    s += " (#? -- not found!); "
2387        if self.histogram == '*':
2388            s += "Histograms: all; "
2389        elif self.histogram is not None:
2390            hist = _lookup(HistRanIdLookup,self.histogram)
2391            s += "Histogram: rId=" + str(self.histogram) + " (#"+ hist + "); "
2392        s += 'Variable name="' + str(self.name) + '">'
2393        return s+" ("+self.varname()+")"
2394
2395    def __eq__(self, other):
2396        '''Allow comparison of G2VarObj to other G2VarObj objects or strings.
2397        If any field is a wildcard ('*') that field matches.
2398        '''
2399        if type(other) is str:
2400            other = G2VarObj(other)
2401        elif type(other) is not G2VarObj:
2402            raise Exception("Invalid type ({}) for G2VarObj comparison with {}"
2403                            .format(type(other),other))
2404        if self.phase != other.phase and self.phase != '*' and other.phase != '*':
2405            return False
2406        if self.histogram != other.histogram and self.histogram != '*' and other.histogram != '*':
2407            return False
2408        if self.atom != other.atom and self.atom != '*' and other.atom != '*':
2409            return False
2410        if self.name != other.name:
2411            return False
2412        return True
2413   
2414    def fmtVarByMode(self, seqmode, note, warnmsg):
2415        '''Format a parameter object for display. Note that these changes
2416        are only temporary and are only shown only when the Constraints
2417        data tree is selected.
2418
2419        * In a non-sequential refinement or where the mode is 'use-all', the
2420          name is converted unchanged to a str
2421        * In a sequential refinement when the mode is 'wildcards-only' the
2422          name is converted unchanged to a str but a warning is added
2423          for non-wildcarded HAP or Histogram parameters
2424        * In a sequential refinement or where the mode is 'auto-wildcard',
2425          a histogram number is converted to a wildcard (*) and then
2426          converted to str
2427
2428        :param str mode: the sequential mode (see above)
2429        :param str note: value displayed on the line of the constraint/equiv.
2430        :param str warnmsg: a message saying the constraint is not used
2431
2432        :returns: varname, explain, note, warnmsg (all str values) where:
2433
2434          * varname is the parameter expressed as a string,
2435          * explain is blank unless there is a warning explanation about
2436            the parameter or blank
2437          * note is the previous value unless overridden
2438          * warnmsg is the previous value unless overridden
2439        '''
2440        explain = ''
2441        s = self.varname()
2442        if seqmode == 'auto-wildcard':
2443            if self.histogram: s = self.varname('*')
2444        elif seqmode == 'wildcards-only' and self.histogram:
2445            if self.histogram != '*':
2446                warnmsg = 'Ignored due to use of a non-wildcarded histogram number'
2447                note = 'Ignored'
2448                explain = '\nIgnoring: '+self.varname()+' does not contain a wildcard.\n'
2449        elif seqmode != 'use-all' and seqmode != 'wildcards-only':
2450            print('Unexpected mode',seqmode,' in fmtVarByMode')
2451        return s,explain,note,warnmsg
2452
2453    def _show(self):
2454        'For testing, shows the current lookup table'
2455        print ('phases'+ self.IDdict['phases'])
2456        print ('hists'+ self.IDdict['hists'])
2457        print ('atomDict'+ self.IDdict['atoms'])
2458
2459#==========================================================================
2460def SetDefaultSample():
2461    'Fills in default items for the Sample dictionary for Debye-Scherrer & SASD'
2462    return {
2463        'InstrName':'',
2464        'ranId':ran.randint(0,sys.maxsize),
2465        'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],
2466        'DisplaceX':[0.0,False],'DisplaceY':[0.0,False],
2467        'Temperature':300.,'Pressure':0.1,'Time':0.0,
2468        'FreePrm1':0.,'FreePrm2':0.,'FreePrm3':0.,
2469        'Gonio. radius':200.0,
2470        'Omega':0.0,'Chi':0.0,'Phi':0.0,'Azimuth':0.0,
2471#SASD items
2472        'Materials':[{'Name':'vacuum','VolFrac':1.0,},{'Name':'vacuum','VolFrac':0.0,}],
2473        'Thick':1.0,'Contrast':[0.0,0.0],       #contrast & anomalous contrast
2474        'Trans':1.0,                            #measured transmission
2475        'SlitLen':0.0,                          #Slit length - in Q(A-1)
2476        }
2477######################################################################
2478class ImportBaseclass(object):
2479    '''Defines a base class for the reading of input files (diffraction
2480    data, coordinates,...). See :ref:`Writing a Import Routine<import_routines>`
2481    for an explanation on how to use a subclass of this class.
2482    '''
2483    class ImportException(Exception):
2484        '''Defines an Exception that is used when an import routine hits an expected error,
2485        usually in .Reader.
2486
2487        Good practice is that the Reader should define a value in self.errors that
2488        tells the user some information about what is wrong with their file.
2489        '''
2490        pass
2491
2492    UseReader = True  # in __init__ set value of self.UseReader to False to skip use of current importer
2493    def __init__(self,formatName,longFormatName=None,
2494                 extensionlist=[],strictExtension=False,):
2495        self.formatName = formatName # short string naming file type
2496        if longFormatName: # longer string naming file type
2497            self.longFormatName = longFormatName
2498        else:
2499            self.longFormatName = formatName
2500        # define extensions that are allowed for the file type
2501        # for windows, remove any extensions that are duplicate, as case is ignored
2502        if sys.platform == 'windows' and extensionlist:
2503            extensionlist = list(set([s.lower() for s in extensionlist]))
2504        self.extensionlist = extensionlist
2505        # If strictExtension is True, the file will not be read, unless
2506        # the extension matches one in the extensionlist
2507        self.strictExtension = strictExtension
2508        self.errors = ''
2509        self.warnings = ''
2510        self.SciPy = False          #image reader needed scipy
2511        # used for readers that will use multiple passes to read
2512        # more than one data block
2513        self.repeat = False
2514        self.selections = []
2515        self.repeatcount = 0
2516        self.readfilename = '?'
2517        self.scriptable = False
2518        #print 'created',self.__class__
2519
2520    def ReInitialize(self):
2521        'Reinitialize the Reader to initial settings'
2522        self.errors = ''
2523        self.warnings = ''
2524        self.SciPy = False          #image reader needed scipy
2525        self.repeat = False
2526        self.repeatcount = 0
2527        self.readfilename = '?'
2528
2529
2530#    def Reader(self, filename, filepointer, ParentFrame=None, **unused):
2531#        '''This method must be supplied in the child class to read the file.
2532#        if the read fails either return False or raise an Exception
2533#        preferably of type ImportException.
2534#        '''
2535#        #start reading
2536#        raise ImportException("Error occurred while...")
2537#        self.errors += "Hint for user on why the error occur
2538#        return False # if an error occurs
2539#        return True # if read OK
2540
2541    def ExtensionValidator(self, filename):
2542        '''This methods checks if the file has the correct extension
2543       
2544        :returns:
2545       
2546          * False if this filename will not be supported by this reader (only
2547            when strictExtension is True)
2548          * True if the extension matches the list supplied by the reader
2549          * None if the reader allows un-registered extensions
2550         
2551        '''
2552        if filename:
2553            ext = os.path.splitext(filename)[1]
2554            if not ext and self.strictExtension: return False
2555            for ext in self.extensionlist:               
2556                if sys.platform == 'windows':
2557                    if filename.lower().endswith(ext): return True
2558                else:
2559                    if filename.endswith(ext): return True
2560        if self.strictExtension:
2561            return False
2562        else:
2563            return None
2564
2565    def ContentsValidator(self, filename):
2566        '''This routine will attempt to determine if the file can be read
2567        with the current format.
2568        This will typically be overridden with a method that
2569        takes a quick scan of [some of]
2570        the file contents to do a "sanity" check if the file
2571        appears to match the selected format.
2572        the file must be opened here with the correct format (binary/text)
2573        '''
2574        #filepointer.seek(0) # rewind the file pointer
2575        return True
2576
2577    def CIFValidator(self, filepointer):
2578        '''A :meth:`ContentsValidator` for use to validate CIF files.
2579        '''
2580        filepointer.seek(0)
2581        for i,l in enumerate(filepointer):
2582            if i >= 1000: return True
2583            '''Encountered only blank lines or comments in first 1000
2584            lines. This is unlikely, but assume it is CIF anyway, since we are
2585            even less likely to find a file with nothing but hashes and
2586            blank lines'''
2587            line = l.strip()
2588            if len(line) == 0: # ignore blank lines
2589                continue
2590            elif line.startswith('#'): # ignore comments
2591                continue
2592            elif line.startswith('data_'): # on the right track, accept this file
2593                return True
2594            else: # found something invalid
2595                self.errors = 'line '+str(i+1)+' contains unexpected data:\n'
2596                if all([ord(c) < 128 and ord(c) != 0 for c in str(l)]): # show only if ASCII
2597                    self.errors += '  '+str(l)
2598                else:
2599                    self.errors += '  (binary)'
2600                self.errors += '\n  Note: a CIF should only have blank lines or comments before'
2601                self.errors += '\n        a data_ statement begins a block.'
2602                return False
2603
2604######################################################################
2605class ImportPhase(ImportBaseclass):
2606    '''Defines a base class for the reading of files with coordinates
2607
2608    Objects constructed that subclass this (in import/G2phase_*.py etc.) will be used
2609    in :meth:`GSASIIdataGUI.GSASII.OnImportPhase` and in
2610    :func:`GSASIIscriptable.import_generic`.
2611    See :ref:`Writing a Import Routine<import_routines>`
2612    for an explanation on how to use this class.
2613
2614    '''
2615    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2616        strictExtension=False,):
2617        # call parent __init__
2618        ImportBaseclass.__init__(self,formatName,longFormatName,
2619            extensionlist,strictExtension)
2620        self.Phase = None # a phase must be created with G2IO.SetNewPhase in the Reader
2621        self.SymOps = {} # specified when symmetry ops are in file (e.g. CIF)
2622        self.Constraints = None
2623
2624######################################################################
2625class ImportStructFactor(ImportBaseclass):
2626    '''Defines a base class for the reading of files with tables
2627    of structure factors.
2628
2629    Structure factors are read with a call to :meth:`GSASIIdataGUI.GSASII.OnImportSfact`
2630    which in turn calls :meth:`GSASIIdataGUI.GSASII.OnImportGeneric`, which calls
2631    methods :meth:`ExtensionValidator`, :meth:`ContentsValidator` and
2632    :meth:`Reader`.
2633
2634    See :ref:`Writing a Import Routine<import_routines>`
2635    for an explanation on how to use import classes in general. The specifics
2636    for reading a structure factor histogram require that
2637    the ``Reader()`` routine in the import
2638    class need to do only a few things: It
2639    should load :attr:`RefDict` item ``'RefList'`` with the reflection list,
2640    and set :attr:`Parameters` with the instrument parameters
2641    (initialized with :meth:`InitParameters` and set with :meth:`UpdateParameters`).
2642    '''
2643    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2644        strictExtension=False,):
2645        ImportBaseclass.__init__(self,formatName,longFormatName,
2646            extensionlist,strictExtension)
2647
2648        # define contents of Structure Factor entry
2649        self.Parameters = []
2650        'self.Parameters is a list with two dicts for data parameter settings'
2651        self.InitParameters()
2652        self.RefDict = {'RefList':[],'FF':{},'Super':0}
2653        self.Banks = []             #for multi bank data (usually TOF)
2654        '''self.RefDict is a dict containing the reflection information, as read from the file.
2655        Item 'RefList' contains the reflection information. See the
2656        :ref:`Single Crystal Reflection Data Structure<XtalRefl_table>`
2657        for the contents of each row. Dict element 'FF'
2658        contains the form factor values for each element type; if this entry
2659        is left as initialized (an empty list) it will be initialized as needed later.
2660        '''
2661    def ReInitialize(self):
2662        'Reinitialize the Reader to initial settings'
2663        ImportBaseclass.ReInitialize(self)
2664        self.InitParameters()
2665        self.Banks = []             #for multi bank data (usually TOF)
2666        self.RefDict = {'RefList':[],'FF':{},'Super':0}
2667
2668    def InitParameters(self):
2669        'initialize the instrument parameters structure'
2670        Lambda = 0.70926
2671        HistType = 'SXC'
2672        self.Parameters = [{'Type':[HistType,HistType], # create the structure
2673                            'Lam':[Lambda,Lambda]
2674                            }, {}]
2675        'Parameters is a list with two dicts for data parameter settings'
2676
2677    def UpdateParameters(self,Type=None,Wave=None):
2678        'Revise the instrument parameters'
2679        if Type is not None:
2680            self.Parameters[0]['Type'] = [Type,Type]
2681        if Wave is not None:
2682            self.Parameters[0]['Lam'] = [Wave,Wave]
2683
2684######################################################################
2685class ImportPowderData(ImportBaseclass):
2686    '''Defines a base class for the reading of files with powder data.
2687
2688    Objects constructed that subclass this (in import/G2pwd_*.py etc.) will be used
2689    in :meth:`GSASIIdataGUI.GSASII.OnImportPowder` and in
2690    :func:`GSASIIscriptable.import_generic`.
2691    See :ref:`Writing a Import Routine<import_routines>`
2692    for an explanation on how to use this class.
2693    '''
2694    def __init__(self,formatName,longFormatName=None,
2695        extensionlist=[],strictExtension=False,):
2696        ImportBaseclass.__init__(self,formatName,longFormatName,
2697            extensionlist,strictExtension)
2698        self.clockWd = None  # used in TOF
2699        self.ReInitialize()
2700
2701    def ReInitialize(self):
2702        'Reinitialize the Reader to initial settings'
2703        ImportBaseclass.ReInitialize(self)
2704        self.powderentry = ['',None,None] #  (filename,Pos,Bank)
2705        self.powderdata = [] # Powder dataset
2706        '''A powder data set is a list with items [x,y,w,yc,yb,yd]:
2707                np.array(x), # x-axis values
2708                np.array(y), # powder pattern intensities
2709                np.array(w), # 1/sig(intensity)^2 values (weights)
2710                np.array(yc), # calc. intensities (zero)
2711                np.array(yb), # calc. background (zero)
2712                np.array(yd), # obs-calc profiles
2713        '''
2714        self.comments = []
2715        self.idstring = ''
2716        self.Sample = SetDefaultSample() # default sample parameters
2717        self.Controls = {}  # items to be placed in top-level Controls
2718        self.GSAS = None     # used in TOF
2719        self.repeat_instparm = True # Should a parm file be
2720        #                             used for multiple histograms?
2721        self.instparm = None # name hint from file of instparm to use
2722        self.instfile = '' # full path name to instrument parameter file
2723        self.instbank = '' # inst parm bank number
2724        self.instmsg = ''  # a label that gets printed to show
2725                           # where instrument parameters are from
2726        self.numbanks = 1
2727        self.instdict = {} # place items here that will be transferred to the instrument parameters
2728        self.pwdparms = {} # place parameters that are transferred directly to the tree
2729                           # here (typically from an existing GPX file)
2730######################################################################
2731class ImportSmallAngleData(ImportBaseclass):
2732    '''Defines a base class for the reading of files with small angle data.
2733    See :ref:`Writing a Import Routine<import_routines>`
2734    for an explanation on how to use this class.
2735    '''
2736    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2737        strictExtension=False,):
2738
2739        ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist,
2740            strictExtension)
2741        self.ReInitialize()
2742
2743    def ReInitialize(self):
2744        'Reinitialize the Reader to initial settings'
2745        ImportBaseclass.ReInitialize(self)
2746        self.smallangleentry = ['',None,None] #  (filename,Pos,Bank)
2747        self.smallangledata = [] # SASD dataset
2748        '''A small angle data set is a list with items [x,y,w,yc,yd]:
2749                np.array(x), # x-axis values
2750                np.array(y), # powder pattern intensities
2751                np.array(w), # 1/sig(intensity)^2 values (weights)
2752                np.array(yc), # calc. intensities (zero)
2753                np.array(yd), # obs-calc profiles
2754                np.array(yb), # preset bkg
2755        '''
2756        self.comments = []
2757        self.idstring = ''
2758        self.Sample = SetDefaultSample()
2759        self.GSAS = None     # used in TOF
2760        self.clockWd = None  # used in TOF
2761        self.numbanks = 1
2762        self.instdict = {} # place items here that will be transferred to the instrument parameters
2763
2764######################################################################
2765class ImportReflectometryData(ImportBaseclass):
2766    '''Defines a base class for the reading of files with reflectometry data.
2767    See :ref:`Writing a Import Routine<import_routines>`
2768    for an explanation on how to use this class.
2769    '''
2770    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2771        strictExtension=False,):
2772
2773        ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist,
2774            strictExtension)
2775        self.ReInitialize()
2776
2777    def ReInitialize(self):
2778        'Reinitialize the Reader to initial settings'
2779        ImportBaseclass.ReInitialize(self)
2780        self.reflectometryentry = ['',None,None] #  (filename,Pos,Bank)
2781        self.reflectometrydata = [] # SASD dataset
2782        '''A small angle data set is a list with items [x,y,w,yc,yd]:
2783                np.array(x), # x-axis values
2784                np.array(y), # powder pattern intensities
2785                np.array(w), # 1/sig(intensity)^2 values (weights)
2786                np.array(yc), # calc. intensities (zero)
2787                np.array(yd), # obs-calc profiles
2788                np.array(yb), # preset bkg
2789        '''
2790        self.comments = []
2791        self.idstring = ''
2792        self.Sample = SetDefaultSample()
2793        self.GSAS = None     # used in TOF
2794        self.clockWd = None  # used in TOF
2795        self.numbanks = 1
2796        self.instdict = {} # place items here that will be transferred to the instrument parameters
2797
2798######################################################################
2799class ImportPDFData(ImportBaseclass):
2800    '''Defines a base class for the reading of files with PDF G(R) data.
2801    See :ref:`Writing a Import Routine<import_routines>`
2802    for an explanation on how to use this class.
2803    '''
2804    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2805        strictExtension=False,):
2806
2807        ImportBaseclass.__init__(self,formatName,longFormatName,extensionlist,
2808            strictExtension)
2809        self.ReInitialize()
2810
2811    def ReInitialize(self):
2812        'Reinitialize the Reader to initial settings'
2813        ImportBaseclass.ReInitialize(self)
2814        self.pdfentry = ['',None,None] #  (filename,Pos,Bank)
2815        self.pdfdata = [] # PDF G(R) dataset
2816        '''A pdf g(r) data set is a list with items [x,y]:
2817                np.array(x), # r-axis values
2818                np.array(y), # pdf g(r)
2819        '''
2820        self.comments = []
2821        self.idstring = ''
2822        self.numbanks = 1
2823
2824######################################################################
2825class ImportImage(ImportBaseclass):
2826    '''Defines a base class for the reading of images
2827
2828    Images are read in only these places:
2829
2830      * Initial reading is typically done from a menu item
2831        with a call to :meth:`GSASIIdataGUI.GSASII.OnImportImage`
2832        which in turn calls :meth:`GSASIIdataGUI.GSASII.OnImportGeneric`. That calls
2833        methods :meth:`ExtensionValidator`, :meth:`ContentsValidator` and
2834        :meth:`Reader`. This returns a list of reader objects for each read image.
2835        Also used in :func:`GSASIIscriptable.import_generic`.
2836
2837      * Images are read alternatively in :func:`GSASIIIO.ReadImages`, which puts image info
2838        directly into the data tree.
2839
2840      * Images are reloaded with :func:`GSASIIIO.GetImageData`.
2841
2842    When reading an image, the ``Reader()`` routine in the ImportImage class
2843    should set:
2844
2845      * :attr:`Comments`: a list of strings (str),
2846      * :attr:`Npix`: the number of pixels in the image (int),
2847      * :attr:`Image`: the actual image as a numpy array (np.array)
2848      * :attr:`Data`: a dict defining image parameters (dict). Within this dict the following
2849        data items are needed:
2850
2851         * 'pixelSize': size of each pixel in microns (such as ``[200.,200.]``.
2852         * 'wavelength': wavelength in :math:`\\AA`.
2853         * 'distance': distance of detector from sample in cm.
2854         * 'center': uncalibrated center of beam on detector (such as ``[204.8,204.8]``.
2855         * 'size': size of image (such as ``[2048,2048]``).
2856         * 'ImageTag': image number or other keyword used to retrieve image from
2857           a multi-image data file (defaults to ``1`` if not specified).
2858         * 'sumfile': holds sum image file name if a sum was produced from a multi image file
2859
2860    optional data items:
2861
2862      * :attr:`repeat`: set to True if there are additional images to
2863        read in the file, False otherwise
2864      * :attr:`repeatcount`: set to the number of the image.
2865
2866    Note that the above is initialized with :meth:`InitParameters`.
2867    (Also see :ref:`Writing a Import Routine<import_routines>`
2868    for an explanation on how to use import classes in general.)
2869    '''
2870    def __init__(self,formatName,longFormatName=None,extensionlist=[],
2871        strictExtension=False,):
2872        ImportBaseclass.__init__(self,formatName,longFormatName,
2873            extensionlist,strictExtension)
2874        self.InitParameters()
2875
2876    def ReInitialize(self):
2877        'Reinitialize the Reader to initial settings -- not used at present'
2878        ImportBaseclass.ReInitialize(self)
2879        self.InitParameters()
2880
2881    def InitParameters(self):
2882        'initialize the instrument parameters structure'
2883        self.Comments = ['No comments']
2884        self.Data = {'samplechangerpos':0.0,'det2theta':0.0,'Gain map':''}
2885        self.Npix = 0
2886        self.Image = None
2887        self.repeat = False
2888        self.repeatcount = 1
2889        self.sumfile = ''
2890
2891    def LoadImage(self,ParentFrame,imagefile,imagetag=None):
2892        '''Optionally, call this after reading in an image to load it into the tree.
2893        This saves time by preventing a reread of the same information.
2894        '''
2895        if ParentFrame:
2896            ParentFrame.ImageZ = self.Image   # store the image for plotting
2897            ParentFrame.oldImagefile = imagefile # save the name of the last image file read
2898            ParentFrame.oldImageTag = imagetag   # save the tag of the last image file read
2899
2900#################################################################################################
2901# shortcut routines
2902exp = np.exp
2903sind = sin = s = lambda x: np.sin(x*np.pi/180.)
2904cosd = cos = c = lambda x: np.cos(x*np.pi/180.)
2905tand = tan = t = lambda x: np.tan(x*np.pi/180.)
2906sqrt = sq = lambda x: np.sqrt(x)
2907pi = lambda: np.pi
2908
2909def FindFunction(f):
2910    '''Find the object corresponding to function f
2911
2912    :param str f: a function name such as 'numpy.exp'
2913    :returns: (pkgdict,pkgobj) where pkgdict contains a dict
2914      that defines the package location(s) and where pkgobj
2915      defines the object associated with the function.
2916      If the function is not found, pkgobj is None.
2917    '''
2918    df = f.split('.')
2919    pkgdict = {}
2920    # no listed module name, try in current namespace
2921    if len(df) == 1:
2922        try:
2923            fxnobj = eval(f)
2924            return pkgdict,fxnobj
2925        except (AttributeError, NameError):
2926            return None,None
2927
2928    # includes a package, see if package is already imported
2929    pkgnam = '.'.join(df[:-1])
2930    try:
2931        fxnobj = eval(f)
2932        pkgdict[pkgnam] = eval(pkgnam)
2933        return pkgdict,fxnobj
2934    except (AttributeError, NameError):
2935        pass
2936    # package not yet imported, so let's try
2937    if '.' not in sys.path: sys.path.append('.')
2938    pkgnam = '.'.join(df[:-1])
2939    #for pkg in f.split('.')[:-1]: # if needed, descend down the tree
2940    #    if pkgname:
2941    #        pkgname += '.' + pkg
2942    #    else:
2943    #        pkgname = pkg
2944    try:
2945        exec('import '+pkgnam)
2946        pkgdict[pkgnam] = eval(pkgnam)
2947        fxnobj = eval(f)
2948    except Exception as msg:
2949        print('load of '+pkgnam+' failed with error='+str(msg))
2950        return {},None
2951    # can we access the function? I am not exactly sure what
2952    #    I intended this to test originally (BHT)
2953    try:
2954        fxnobj = eval(f,globals(),pkgdict)
2955        return pkgdict,fxnobj
2956    except Exception as msg:
2957        print('call to',f,' failed with error=',str(msg))
2958        return None,None # not found
2959               
2960class ExpressionObj(object):
2961    '''Defines an object with a user-defined expression, to be used for
2962    secondary fits or restraints. Object is created null, but is changed
2963    using :meth:`LoadExpression`. This contains only the minimum
2964    information that needs to be stored to save and load the expression
2965    and how it is mapped to GSAS-II variables.
2966    '''
2967    def __init__(self):
2968        self.expression = ''
2969        'The expression as a text string'
2970        self.assgnVars = {}
2971        '''A dict where keys are label names in the expression mapping to a GSAS-II
2972        variable. The value a G2 variable name.
2973        Note that the G2 variable name may contain a wild-card and correspond to
2974        multiple values.
2975        '''
2976        self.freeVars = {}
2977        '''A dict where keys are label names in the expression mapping to a free
2978        parameter. The value is a list with:
2979
2980         * a name assigned to the parameter
2981         * a value for to the parameter and
2982         * a flag to determine if the variable is refined.
2983        '''
2984        self.depVar = None
2985
2986        self.lastError = ('','')
2987        '''Shows last encountered error in processing expression
2988        (list of 1-3 str values)'''
2989
2990        self.distance_dict  = None  # to be used for defining atom phase/symmetry info
2991        self.distance_atoms = None  # to be used for defining atom distances
2992
2993    def LoadExpression(self,expr,exprVarLst,varSelect,varName,varValue,varRefflag):
2994        '''Load the expression and associated settings into the object. Raises
2995        an exception if the expression is not parsed, if not all functions
2996        are defined or if not all needed parameter labels in the expression
2997        are defined.
2998
2999        This will not test if the variable referenced in these definitions
3000        are actually in the parameter dictionary. This is checked when the
3001        computation for the expression is done in :meth:`SetupCalc`.
3002
3003        :param str expr: the expression
3004        :param list exprVarLst: parameter labels found in the expression
3005        :param dict varSelect: this will be 0 for Free parameters
3006          and non-zero for expression labels linked to G2 variables.
3007        :param dict varName: Defines a name (str) associated with each free parameter
3008        :param dict varValue: Defines a value (float) associated with each free parameter
3009        :param dict varRefflag: Defines a refinement flag (bool)
3010          associated with each free parameter
3011        '''
3012        self.expression = expr
3013        self.compiledExpr = None
3014        self.freeVars = {}
3015        self.assgnVars = {}
3016        for v in exprVarLst:
3017            if varSelect[v] == 0:
3018                self.freeVars[v] = [
3019                    varName.get(v),
3020                    varValue.get(v),
3021                    varRefflag.get(v),
3022                    ]
3023            else:
3024                self.assgnVars[v] = varName[v]
3025        self.CheckVars()
3026
3027    def EditExpression(self,exprVarLst,varSelect,varName,varValue,varRefflag):
3028        '''Load the expression and associated settings from the object into
3029        arrays used for editing.
3030
3031        :param list exprVarLst: parameter labels found in the expression
3032        :param dict varSelect: this will be 0 for Free parameters
3033          and non-zero for expression labels linked to G2 variables.
3034        :param dict varName: Defines a name (str) associated with each free parameter
3035        :param dict varValue: Defines a value (float) associated with each free parameter
3036        :param dict varRefflag: Defines a refinement flag (bool)
3037          associated with each free parameter
3038
3039        :returns: the expression as a str
3040        '''
3041        for v in self.freeVars:
3042            varSelect[v] = 0
3043            varName[v] = self.freeVars[v][0]
3044            varValue[v] = self.freeVars[v][1]
3045            varRefflag[v] = self.freeVars[v][2]
3046        for v in self.assgnVars:
3047            varSelect[v] = 1
3048            varName[v] = self.assgnVars[v]
3049        return self.expression
3050
3051    def GetVaried(self):
3052        'Returns the names of the free parameters that will be refined'
3053        return ["::"+self.freeVars[v][0] for v in self.freeVars if self.freeVars[v][2]]
3054
3055    def GetVariedVarVal(self):
3056        'Returns the names and values of the free parameters that will be refined'
3057        return [("::"+self.freeVars[v][0],self.freeVars[v][1]) for v in self.freeVars if self.freeVars[v][2]]
3058
3059    def UpdateVariedVars(self,varyList,values):
3060        'Updates values for the free parameters (after a refinement); only updates refined vars'
3061        for v in self.freeVars:
3062            if not self.freeVars[v][2]: continue
3063            if "::"+self.freeVars[v][0] not in varyList: continue
3064            indx = list(varyList).index("::"+self.freeVars[v][0])
3065            self.freeVars[v][1] = values[indx]
3066
3067    def GetIndependentVars(self):
3068        'Returns the names of the required independent parameters used in expression'
3069        return [self.assgnVars[v] for v in self.assgnVars]
3070
3071    def CheckVars(self):
3072        '''Check that the expression can be parsed, all functions are
3073        defined and that input loaded into the object is internally
3074        consistent. If not an Exception is raised.
3075
3076        :returns: a dict with references to packages needed to
3077          find functions referenced in the expression.
3078        '''
3079        ret = self.ParseExpression(self.expression)
3080        if not ret:
3081            raise Exception("Expression parse error")
3082        exprLblList,fxnpkgdict = ret
3083        # check each var used in expression is defined
3084        defined = list(self.assgnVars.keys()) + list(self.freeVars.keys())
3085        notfound = []
3086        for var in exprLblList:
3087            if var not in defined:
3088                notfound.append(var)
3089        if notfound:
3090            msg = 'Not all variables defined'
3091            msg1 = 'The following variables were not defined: '
3092            msg2 = ''
3093            for var in notfound:
3094                if msg: msg += ', '
3095                msg += var
3096            self.lastError = (msg1,'  '+msg2)
3097            raise Exception(msg)
3098        return fxnpkgdict
3099
3100    def ParseExpression(self,expr):
3101        '''Parse an expression and return a dict of called functions and
3102        the variables used in the expression. Returns None in case an error
3103        is encountered. If packages are referenced in functions, they are loaded
3104        and the functions are looked up into the modules global
3105        workspace.
3106
3107        Note that no changes are made to the object other than
3108        saving an error message, so that this can be used for testing prior
3109        to the save.
3110
3111        :returns: a list of used variables
3112        '''
3113        self.lastError = ('','')
3114        import ast
3115        def ASTtransverse(node,fxn=False):
3116            '''Transverse a AST-parsed expresson, compiling a list of variables
3117            referenced in the expression. This routine is used recursively.
3118
3119            :returns: varlist,fxnlist where
3120              varlist is a list of referenced variable names and
3121              fxnlist is a list of used functions
3122            '''
3123            varlist = []
3124            fxnlist = []
3125            if isinstance(node, list):
3126                for b in node:
3127                    v,f = ASTtransverse(b,fxn)
3128                    varlist += v
3129                    fxnlist += f
3130            elif isinstance(node, ast.AST):
3131                for a, b in ast.iter_fields(node):
3132                    if isinstance(b, ast.AST):
3133                        if a == 'func':
3134                            fxnlist += ['.'.join(ASTtransverse(b,True)[0])]
3135                            continue
3136                        v,f = ASTtransverse(b,fxn)
3137                        varlist += v
3138                        fxnlist += f
3139                    elif isinstance(b, list):
3140                        v,f = ASTtransverse(b,fxn)
3141                        varlist += v
3142                        fxnlist += f
3143                    elif node.__class__.__name__ == "Name":
3144                        varlist += [b]
3145                    elif fxn and node.__class__.__name__ == "Attribute":
3146                        varlist += [b]
3147            return varlist,fxnlist
3148        try:
3149            exprast = ast.parse(expr)
3150        except SyntaxError:
3151            s = ''
3152            import traceback
3153            for i in traceback.format_exc().splitlines()[-3:-1]:
3154                if s: s += "\n"
3155                s += str(i)
3156            self.lastError = ("Error parsing expression:",s)
3157            return
3158        # find the variables & functions
3159        v,f = ASTtransverse(exprast)
3160        varlist = sorted(list(set(v)))
3161        fxnlist = list(set(f))
3162        pkgdict = {}
3163        # check the functions are defined
3164        for fxn in fxnlist:
3165            fxndict,fxnobj = FindFunction(fxn)
3166            if not fxnobj:
3167                self.lastError = ("Error: Invalid function",fxn,
3168                                  "is not defined")
3169                return
3170            if not hasattr(fxnobj,'__call__'):
3171                self.lastError = ("Error: Not a function.",fxn,
3172                                  "cannot be called as a function")
3173                return
3174            pkgdict.update(fxndict)
3175        return varlist,pkgdict
3176
3177    def GetDepVar(self):
3178        'return the dependent variable, or None'
3179        return self.depVar
3180
3181    def SetDepVar(self,var):
3182        'Set the dependent variable, if used'
3183        self.depVar = var
3184#==========================================================================
3185class ExpressionCalcObj(object):
3186    '''An object used to evaluate an expression from a :class:`ExpressionObj`
3187    object.
3188
3189    :param ExpressionObj exprObj: a :class:`~ExpressionObj` expression object with
3190      an expression string and mappings for the parameter labels in that object.
3191    '''
3192    def __init__(self,exprObj):
3193        self.eObj = exprObj
3194        'The expression and mappings; a :class:`ExpressionObj` object'
3195        self.compiledExpr = None
3196        'The expression as compiled byte-code'
3197        self.exprDict = {}
3198        '''dict that defines values for labels used in expression and packages
3199        referenced by functions
3200        '''
3201        self.lblLookup = {}
3202        '''Lookup table that specifies the expression label name that is
3203        tied to a particular GSAS-II parameters in the parmDict.
3204        '''
3205        self.fxnpkgdict = {}
3206        '''a dict with references to packages needed to
3207        find functions referenced in the expression.
3208        '''
3209        self.varLookup = {}
3210        '''Lookup table that specifies the GSAS-II variable(s)
3211        indexed by the expression label name. (Used for only for diagnostics
3212        not evaluation of expression.)
3213        '''
3214        self.su = None
3215        '''Standard error evaluation where supplied by the evaluator
3216        '''
3217        # Patch: for old-style expressions with a (now removed step size)
3218        if '2' in platform.python_version_tuple()[0]: 
3219            basestr = basestring
3220        else:
3221            basestr = str
3222        for v in self.eObj.assgnVars:
3223            if not isinstance(self.eObj.assgnVars[v], basestr):
3224                self.eObj.assgnVars[v] = self.eObj.assgnVars[v][0]
3225        self.parmDict = {}
3226        '''A copy of the parameter dictionary, for distance and angle computation
3227        '''
3228
3229    def SetupCalc(self,parmDict):
3230        '''Do all preparations to use the expression for computation.
3231        Adds the free parameter values to the parameter dict (parmDict).
3232        '''
3233        if self.eObj.expression.startswith('Dist') or self.eObj.expression.startswith('Angle'):
3234            return
3235        self.fxnpkgdict = self.eObj.CheckVars()
3236        # all is OK, compile the expression
3237        self.compiledExpr = compile(self.eObj.expression,'','eval')
3238
3239        # look at first value in parmDict to determine its type
3240        parmsInList = True
3241        if '2' in platform.python_version_tuple()[0]: 
3242            basestr = basestring
3243        else:
3244            basestr = str
3245        for key in parmDict:
3246            val = parmDict[key]
3247            if isinstance(val, basestr):
3248                parmsInList = False
3249                break
3250            try: # check if values are in lists
3251                val = parmDict[key][0]
3252            except (TypeError,IndexError):
3253                parmsInList = False
3254            break
3255
3256        # set up the dicts needed to speed computations
3257        self.exprDict = {}
3258        self.lblLookup = {}
3259        self.varLookup = {}
3260        for v in self.eObj.freeVars:
3261            varname = self.eObj.freeVars[v][0]
3262            varname = "::" + varname.lstrip(':').replace(' ','_').replace(':',';')
3263            self.lblLookup[varname] = v
3264            self.varLookup[v] = varname
3265            if parmsInList:
3266                parmDict[varname] = [self.eObj.freeVars[v][1],self.eObj.freeVars[v][2]]
3267            else:
3268                parmDict[varname] = self.eObj.freeVars[v][1]
3269            self.exprDict[v] = self.eObj.freeVars[v][1]
3270        for v in self.eObj.assgnVars:
3271            varname = self.eObj.assgnVars[v]
3272            if varname in parmDict:
3273                self.lblLookup[varname] = v
3274                self.varLookup[v] = varname
3275                if parmsInList:
3276                    self.exprDict[v] = parmDict[varname][0]
3277                else:
3278                    self.exprDict[v] = parmDict[varname]
3279            elif '*' in varname:
3280                varlist = LookupWildCard(varname,list(parmDict.keys()))
3281                if len(varlist) == 0:
3282                    raise Exception("No variables match "+str(v))
3283                for var in varlist:
3284                    self.lblLookup[var] = v
3285                if parmsInList:
3286                    self.exprDict[v] = np.array([parmDict[var][0] for var in varlist])
3287                else:
3288                    self.exprDict[v] = np.array([parmDict[var] for var in varlist])
3289                self.varLookup[v] = [var for var in varlist]
3290            else:
3291                self.exprDict[v] = None
3292#                raise Exception,"No value for variable "+str(v)
3293        self.exprDict.update(self.fxnpkgdict)
3294
3295    def UpdateVars(self,varList,valList):
3296        '''Update the dict for the expression with a set of values
3297        :param list varList: a list of variable names
3298        :param list valList: a list of corresponding values
3299        '''
3300        for var,val in zip(varList,valList):
3301            self.exprDict[self.lblLookup.get(var,'undefined: '+var)] = val
3302
3303    def UpdateDict(self,parmDict):
3304        '''Update the dict for the expression with values in a dict
3305        :param dict parmDict: a dict of values, items not in use are ignored
3306        '''
3307        if self.eObj.expression.startswith('Dist') or self.eObj.expression.startswith('Angle'):
3308            self.parmDict = parmDict
3309            return
3310        for var in parmDict:
3311            if var in self.lblLookup:
3312                self.exprDict[self.lblLookup[var]] = parmDict[var]
3313
3314    def EvalExpression(self):
3315        '''Evaluate an expression. Note that the expression
3316        and mapping are taken from the :class:`ExpressionObj` expression object
3317        and the parameter values were specified in :meth:`SetupCalc`.
3318        :returns: a single value for the expression. If parameter
3319        values are arrays (for example, from wild-carded variable names),
3320        the sum of the resulting expression is returned.
3321
3322        For example, if the expression is ``'A*B'``,
3323        where A is 2.0 and B maps to ``'1::Afrac:*'``, which evaluates to::
3324
3325        [0.5, 1, 0.5]
3326
3327        then the result will be ``4.0``.
3328        '''
3329        self.su = None
3330        if self.eObj.expression.startswith('Dist'):
3331#            GSASIIpath.IPyBreak()
3332            dist = G2mth.CalcDist(self.eObj.distance_dict, self.eObj.distance_atoms, self.parmDict)
3333            return dist
3334        elif self.eObj.expression.startswith('Angle'):
3335            angle = G2mth.CalcAngle(self.eObj.angle_dict, self.eObj.angle_atoms, self.parmDict)
3336            return angle
3337        if self.compiledExpr is None:
3338            raise Exception("EvalExpression called before SetupCalc")
3339        try:
3340            val = eval(self.compiledExpr,globals(),self.exprDict)
3341        except TypeError:
3342            val = None
3343        if not np.isscalar(val):
3344            val = np.sum(val)
3345        return val
3346
3347class G2Exception(Exception):
3348    'A generic GSAS-II exception class'
3349    def __init__(self,msg):
3350        self.msg = msg
3351    def __str__(self):
3352        return repr(self.msg)
3353
3354class G2RefineCancel(Exception):
3355    'Raised when Cancel is pressed in a refinement dialog'
3356    def __init__(self,msg):
3357        self.msg = msg
3358    def __str__(self):
3359        return repr(self.msg)
3360   
3361def HowDidIgetHere(wherecalledonly=False):
3362    '''Show a traceback with calls that brought us to the current location.
3363    Used for debugging.
3364    '''
3365    import traceback
3366    if wherecalledonly:
3367        i = traceback.format_list(traceback.extract_stack()[:-1])[-2]
3368        print(i.strip().rstrip())
3369    else:
3370        print (70*'*')
3371        for i in traceback.format_list(traceback.extract_stack()[:-1]): print(i.strip().rstrip())
3372        print (70*'*')
3373
3374# Note that this is GUI code and should be moved at somepoint
3375def CreatePDFitems(G2frame,PWDRtree,ElList,Qlimits,numAtm=1,FltBkg=0,PDFnames=[]):
3376    '''Create and initialize a new set of PDF tree entries
3377
3378    :param Frame G2frame: main GSAS-II tree frame object
3379    :param str PWDRtree: name of PWDR to be used to create PDF item
3380    :param dict ElList: data structure with composition
3381    :param list Qlimits: Q limits to be used for computing the PDF
3382    :param float numAtm: no. atom in chemical formula
3383    :param float FltBkg: flat background value
3384    :param list PDFnames: previously used PDF names
3385
3386    :returns: the Id of the newly created PDF entry
3387    '''
3388    PDFname = 'PDF '+PWDRtree[4:] # this places two spaces after PDF, which is needed is some places
3389    if PDFname in PDFnames:
3390        print('Skipping, entry already exists: '+PDFname)
3391        return None
3392    #PDFname = MakeUniqueLabel(PDFname,PDFnames)
3393    Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text=PDFname)
3394    Data = {
3395        'Sample':{'Name':PWDRtree,'Mult':1.0},
3396        'Sample Bkg.':{'Name':'','Mult':-1.0,'Refine':False},
3397        'Container':{'Name':'','Mult':-1.0,'Refine':False},
3398        'Container Bkg.':{'Name':'','Mult':-1.0},'ElList':ElList,
3399        'Geometry':'Cylinder','Diam':1.0,'Pack':0.50,'Form Vol':10.0*numAtm,'Flat Bkg':FltBkg,
3400        'DetType':'Area detector','ObliqCoeff':0.3,'Ruland':0.025,'QScaleLim':Qlimits,
3401        'Lorch':False,'BackRatio':0.0,'Rmax':100.,'noRing':False,'IofQmin':1.0,'Rmin':1.0,
3402        'I(Q)':[],'S(Q)':[],'F(Q)':[],'G(R)':[],
3403        #items for sequential PDFfit
3404        'Datarange':[0.,30.],'Fitrange':[0.,30.],'qdamp':[0.03,False],'qbroad':[0,False],'Temp':300}
3405    G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='PDF Controls'),Data)
3406    G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='PDF Peaks'),
3407        {'Limits':[1.,5.],'Background':[2,[0.,-0.2*np.pi],False],'Peaks':[]})
3408    return Id
3409
3410class ShowTiming(object):
3411    '''An object to use for timing repeated sections of code.
3412
3413    Create the object with::
3414       tim0 = ShowTiming()
3415
3416    Tag sections of code to be timed with::
3417       tim0.start('start')
3418       tim0.start('in section 1')
3419       tim0.start('in section 2')
3420       
3421    etc. (Note that each section should have a unique label.)
3422
3423    After the last section, end timing with::
3424       tim0.end()
3425
3426    Show timing results with::
3427       tim0.show()
3428       
3429    '''
3430    def __init__(self):
3431        self.timeSum =  []
3432        self.timeStart = []
3433        self.label = []
3434        self.prev = None
3435    def start(self,label):
3436        import time
3437        if label in self.label:
3438            i = self.label.index(label)
3439            self.timeStart[i] = time.time()
3440        else:
3441            i = len(self.label)
3442            self.timeSum.append(0.0)
3443            self.timeStart.append(time.time())
3444            self.label.append(label)
3445        if self.prev is not None:
3446            self.timeSum[self.prev] += self.timeStart[i] - self.timeStart[self.prev]
3447        self.prev = i
3448    def end(self):
3449        import time
3450        if self.prev is not None:
3451            self.timeSum[self.prev] += time.time() - self.timeStart[self.prev]
3452        self.prev = None
3453    def show(self):
3454        sumT = sum(self.timeSum)
3455        print('Timing results (total={:.2f} sec)'.format(sumT))
3456        for i,(lbl,val) in enumerate(zip(self.label,self.timeSum)):
3457            print('{} {:20} {:8.2f} ms {:5.2f}%'.format(i,lbl,1000.*val,100*val/sumT))
3458
3459def validateAtomDrawType(typ,generalData={}):
3460    '''Confirm that the selected Atom drawing type is valid for the current
3461    phase. If not, use 'vdW balls'. This is currently used only for setting a
3462    default when atoms are added to the atoms draw list.
3463    '''
3464    if typ in ('lines','vdW balls','sticks','balls & sticks','ellipsoids'):
3465        return typ
3466    # elif generalData.get('Type','') == 'macromolecular':
3467    #     if typ in ('backbone',):
3468    #         return typ
3469    return 'vdW balls'
3470
3471if __name__ == "__main__":
3472    # test variable descriptions
3473    for var in '0::Afrac:*',':1:Scale','1::dAx:0','::undefined':
3474        v = var.split(':')[2]
3475        print(var+':\t', getDescr(v),getVarStep(v))
3476    import sys; sys.exit()
3477    # test equation evaluation
3478    def showEQ(calcobj):
3479        print (50*'=')
3480        print (calcobj.eObj.expression+'='+calcobj.EvalExpression())
3481        for v in sorted(calcobj.varLookup):
3482            print ("  "+v+'='+calcobj.exprDict[v]+'='+calcobj.varLookup[v])
3483        # print '  Derivatives'
3484        # for v in calcobj.derivStep.keys():
3485        #     print '    d(Expr)/d('+v+') =',calcobj.EvalDeriv(v)
3486
3487    obj = ExpressionObj()
3488
3489    obj.expression = "A*np.exp(B)"
3490    obj.assgnVars =  {'B': '0::Afrac:1'}
3491    obj.freeVars =  {'A': [u'A', 0.5, True]}
3492    #obj.CheckVars()
3493    calcobj = ExpressionCalcObj(obj)
3494
3495    obj1 = ExpressionObj()
3496    obj1.expression = "A*np.exp(B)"
3497    obj1.assgnVars =  {'B': '0::Afrac:*'}
3498    obj1.freeVars =  {'A': [u'Free Prm A', 0.5, True]}
3499    #obj.CheckVars()
3500    calcobj1 = ExpressionCalcObj(obj1)
3501
3502    obj2 = ExpressionObj()
3503    obj2.distance_stuff = np.array([[0,1],[1,-1]])
3504    obj2.expression = "Dist(1,2)"
3505    GSASIIpath.InvokeDebugOpts()
3506    parmDict2 = {'0::Afrac:0':[0.0,True], '0::Afrac:1': [1.0,False]}
3507    calcobj2 = ExpressionCalcObj(obj2)
3508    calcobj2.SetupCalc(parmDict2)
3509    showEQ(calcobj2)
3510
3511    parmDict1 = {'0::Afrac:0':1.0, '0::Afrac:1': 1.0}
3512    print ('\nDict = '+parmDict1)
3513    calcobj.SetupCalc(parmDict1)
3514    showEQ(calcobj)
3515    calcobj1.SetupCalc(parmDict1)
3516    showEQ(calcobj1)
3517
3518    parmDict2 = {'0::Afrac:0':[0.0,True], '0::Afrac:1': [1.0,False]}
3519    print ('Dict = '+parmDict2)
3520    calcobj.SetupCalc(parmDict2)
3521    showEQ(calcobj)
3522    calcobj1.SetupCalc(parmDict2)
3523    showEQ(calcobj1)
3524    calcobj2.SetupCalc(parmDict2)
3525    showEQ(calcobj2)
Note: See TracBrowser for help on using the repository browser.