Dec 22, 2017 7:56:50 PM (5 years ago)

make scriptable Py3 ready and add new features; minor fix for new G2 installation

1 edited


  • Tutorials/PythonScript/Scripting.htm

    r3132 r3202  
    2020This exercise assumes that the reader has reasonable familiarity with
    2121the Python language.
    22 Before beginning this exercise, the documentation on the
     22Also, the documentation on the
    2323<A href="http://gsas-ii.readthedocs.io/en/latest/GSASIIscripts.html"
    3939Python will make this a more pleasant experience.
     41<h2>Multi-step Script Approach</h2>
    4143<h4>0: Load the GSASIIscriptable module</H4>
    4850script as is done in the example below. Note that a common location
    4951for this will be
    50 <TT>os.path.expanduser("~/g2conda/GSASII/")</TT>. Thus the script will
    51 begin with:
     52<TT>os.path.expanduser("~/g2conda/GSASII/")</TT> or
     53<tt>'/Users/toby/software/GSASII'</tt>, etc.
     54Thus the script will begin with something like this:
    5356<blockquote><textarea rows="3" cols="60" readonly>
    5457import os,sys
    55 sys.path.insert(0,'/Users/toby/software/G2/GSASII')
    5659import GSASIIscriptable as G2sc</textarea></blockquote>
    9699access a GSAS-II project, which is done with a call to
    97100<TT>GSASIIscriptable.G2Project()</tt>. This can be done in one of two
    98 ways, a call with <tt>G2sc.G2Project(filename=</tt><I>file</I><tt>)</tt> creates a new
     101ways: a call with <tt>G2sc.G2Project(filename=</tt><I>file</I><tt>)</tt> creates a new
    99102(empty) project, while a call with
    100103<tt>G2sc.G2Project(gpxfile=</tt><I>file</I><tt>)</tt> opens and
    101 reads an existing project (.gpx) file. Both return a Project wrapper
     104reads an existing project (.gpx) file. Both return a <tt>G2Project</tt> wrapper
    102105object that is used to access a number of methods and variables.
    103106Note that <TT>GSASIIscriptable.G2Project()</tt> can read .gpx files
    107110In this example, we create a new project by using the
    108 <tt>filename=</tt><I>file</I> argument. Note that this will not
    109 actually create a file until a save operation is done.
     111<tt>filename=</tt><I>file</I> argument with this code:
    111113<blockquote><textarea rows="3" cols="70" readonly>
    113115gpx = G2sc.G2Project(filename='PbSO4.gpx')</textarea></blockquote>
    115 </blockquote>
     117Note that the file will not actually be created until an operation
     118that saves the project is called.
    116121<h4>3: Add Histograms and Phase to the GSAS-II project</H4>
    118 To add two powder diffraction datasets (histograms) to the
    119 project we use the <I>project</I><tt>.add_powder_histogram()</tt> method in
    120 the <TT>GSASIIscriptable</tt> class. The two arguments to
     123To add two powder diffraction datasets (histograms) and a phase to the
     124project using this code:
     126<blockquote><textarea rows="10" cols="70" readonly>
     127# setup step 1: add two histograms to the project
     128hist1 = gpx.add_powder_histogram(os.path.join(datadir,"PBSO4.XRA"),
     129                          os.path.join(datadir,"INST_XRY.PRM"))
     130hist2 = gpx.add_powder_histogram(os.path.join(datadir,"PBSO4.CWN"),
     131                          os.path.join(datadir,"inst_d1a.prm"))
     132# setup step 2: add a phase and link it to the previous histograms
     133phase0 = gpx.add_phase(os.path.join(datadir,"PbSO4-Wyckoff.cif"),
     134                      phasename="PbSO4",
     135                      histograms=[hist1,hist2])</textarea></blockquote>
     138We use the <I>project</I><tt>.add_powder_histogram()</tt> method in
     139the <TT>GSASIIscriptable</tt> class to read in the powder data.
     140The two arguments to
    121141<tt>.add_powder_histogram()</tt> are the powder dataset and the
    122   instrument parameter file. While neither powder data file uses a
    123   standard extension, the importer is able to determine the file
    124   format anyway. This will not be true for all file formats.
     142  instrument parameter file. Note that these files are both "GSAS
     143  powder data" files and the importer for this format (and many
     144  others) allows files with arbitrary extensions to be read.
     145All importers that allow for extensions .XRA and .CWN will be
     146used to attempt to read the file, producing a number of warning
     147messages. To specify that only the GSAS powder data importer be
     148used, include a third argument, <tt>fmthint="GSAS powder"</tt> or
     149something similar (<tt>fmthint="GSAS"</tt> is also fine, but will
     150cause both the "GSAS powder data" and the "GSAS-II .gpx" importer to be considered.)
    126152  Note that <I>project</I><tt>.add_powder_histogram()</tt> returns a
    127   powder histogram objects which are saved for later reference. It is
     153  powder histogram objects, which here are saved for later reference. It is
    128154  also possible to obtain these using <tt>gpx.histograms()</tt>, which
    129155  returns a list of defined histograms.
    133159  <I>project</I><tt>.add_phase()</tt>. This specifies a CIF containing the
    134160  structural information, a name for the phase and specifies that the
    135   two histograms are "added" (linked) to the phase.
     161  two histograms are "added" (linked) to the phase. The
     162<tt>fmthint="CIF"</tt> parameter can also optionally be specified to limit the
     163importers that will be tried.
    136165  <UL><LI>
    137166  Note that <I>project</I><tt>.add_phase()</tt>
    145174  These three ways to use the <tt>histograms</tt> parameter produce
    146175  the same result.
    148 <blockquote><textarea rows="10" cols="70" readonly>
    149 # setup step 1: add two histograms to the project
    150 hist1 = gpx.add_powder_histogram(os.path.join(datadir,"PBSO4.XRA"),
    151                           os.path.join(datadir,"INST_XRY.PRM"))
    152 hist2 = gpx.add_powder_histogram(os.path.join(datadir,"PBSO4.CWN"),
    153                           os.path.join(datadir,"inst_d1a.prm"))
    154 # setup step 2: add a phase and link it to the previous histograms
    155 phase0 = gpx.add_phase(os.path.join(datadir,"PbSO4-Wyckoff.cif"),
    156                       phasename="PbSO4",
    157                       histograms=[hist1,hist2])</textarea></blockquote>
    160 </blockquote>
    161178<A name="ChangeCycles">
    162179<h4>4: Change the number of refinement cycles</H4>
    166183  without converging the refinement (or at least coming close to
    167184  convergence) at each refinement step. This is best accomplished by
    168   increasing the number of least-squares cycles. There at present is
    169   no method in the project object that allows this parameter to be
    170   set, so this must be done by finding appropriate parameter
    171   dictionary entry.
     185  increasing the number of least-squares cycles. No supplied method (at
     186  present) allows this parameter to be set straightforwardly, but this
     187  code will do this:
     189 <blockquote><textarea rows="3" cols="70" readonly>
     190# not in tutorial: increase # of cycles to improve convergence
     191gpx.data['Controls']['data']['max cyc'] = 8 # not in API </textarea></blockquote>
    173   At this point, the Python command <tt>gpx.data.keys()</tt> shows the names of the
    174   entries in the GSAS-II tree; 'Controls' is the tree item
     194  To find this parameter in the GSAS-II data structure, I followed
     195  these steps: In the GUI, Controls is the tree item
    175196  corresponding to the section where Least Squares cycles are
    176   set. Command <tt>gpx.data['Controls'].keys()</tt> shows that all
     197  set. Executing the command <tt>gpx.data.keys()</tt> shows the names of the
     198  entries in the dictionary corresponding to the GSAS-II tree and
     199  indeed one entry is 'Controls'.
     200  Command <tt>gpx.data['Controls'].keys()</tt> shows that all
    177201  values are located in an entry labeled 'data' and
    178202  <tt>gpx.data['Controls']['data'].keys()</tt> shows the entries in
    179203this section. Examination of
    180 <BR><tt>gpx.data['Controls']['data']['max cyc']</tt>shows the value 3,
     204<tt>gpx.data['Controls']['data']['max cyc']</tt> shows the value 3,
    181205which is default number of cycles. Thus,
    182 the number of cycles is changed with this Python command:
    184 <blockquote><textarea rows="3" cols="70" readonly>
    185 # not in tutorial: increase # of cycles to improve convergence
    186 gpx.data['Controls']['data']['max cyc'] = 8 # not in API </textarea></blockquote>
    188 </blockquote>
     206the number of cycles is changed with the Python command above.
    189210<h4>5: Set initial variables and refine</H4>
    196217refinement flags are not turned on by default, so a dictionary must be
    197218created to set these histogram variables. This code:
     219<blockquote><textarea rows="5" cols="75" readonly>
     220# tutorial step 4: turn on background refinement (Hist)
     221refdict0 = {"set": {"Background": { "no. coeffs": 3, "refine": True }}}
    199226<LI>defines a dictionary (refdict0) that will be used to set the number of background coefficients (not really
    216243prints them. The function also writes the final refinement results
    217244into the current project file. </A>
    219 <blockquote><textarea rows="5" cols="75" readonly>
    220 # tutorial step 4: turn on background refinement (Hist)
    221 refdict0 = {"set": {"Background": { "no. coeffs": 3, "refine": True }}}
    222 gpx.save('step4.gpx')
    223 gpx.do_refinements([refdict0])
    224 HistStats(gpx)</textarea></blockquote>
    226246The output from this will be:<blockquote><pre>
    249269<tt>my_project.do_refinements()</tt>, as
    250270<A href="http://gsas-ii.readthedocs.io/en/latest/GSASIIscripts.html#refinement-parameters">
    251 described here</A>. The <tt>gpx.do_refinements([refdict0])</tt>
     271described here</A>. Thus, the <tt>gpx.do_refinements([refdict0])</tt>
    252272statement above could be replaced with:
    296316In Step 6 of the original tutorial, the refinement is performed again
    297 after adding Histogram/Phase (HAP) parameters that allow different
    298 lattice constants for the first histogram only.
     317after adding Histogram/Phase (HAP) parameters so that the lattice
     318constants for the first histogram (only) can vary. This is done with
     319this code:
    300321<blockquote><textarea rows="6" cols="75" readonly>
    308 Here we cannot use <tt>gpx.do_refinements([refdict2])</tt> because
    309 that would turn on refinement of the Hstrain terms for both histograms
    310 (if there were more than one phase, it would be all phases and all
    311 histograms), but in the above the <tt>gpx.set_refinement(...)</tt>
    312 statement alternately can be replaced with this:
     329Here we cannot use <tt>gpx.do_refinements([refdict2])</tt> with
     330<tt>refdict2</tt> defined as above because
     331that would turn on refinement of the Hstrain terms for all histograms
     332and all phases. There are several ways to restrict the parameter
     333changes to specified histogram(s) and phase(s). One is to call a
     334method in the phase object(s) directly, such as
     335replacing the <tt>gpx.set_refinement(...)</tt>
     336statement with this:
    314338phase0.set_HAP_refinements({"HStrain": True},histograms=[hist1])
    317 </blockquote>
     341It is also possible to add "histograms" and/or "phases" values into
     342the <tt>refdict2</tt> dict, as will be <a href="#SingeStep">described below.</a>
    318345<h4>8: Add X-ray Sample broadening terms</h4>
    328355existing default. Again, since these parameters are being set only for
    329356one histogram, either <tt>phase0.set_HAP_refinements()</tt> or
    330 <tt>gpx.set_refinement()</tt> must be used.
     357<tt>gpx.set_refinement()</tt> must be called or to use
     358<tt>gpx.do_refinements([refdict3])</tt> the "histograms" element must be
     359included inside <tt>refdict3</tt>.
    332361<blockquote><textarea rows="8" cols="75" readonly>
    333362# tutorial step 7: add size & strain broadening (HAP) for histogram 1 only
    335 refdict2 = {"set": {"Mustrain": {"type":"isotropic","refine":True},
     364refdict3 = {"set": {"Mustrain": {"type":"isotropic","refine":True},
    336365                    "Size":{"type":"isotropic","refine":True},
    337366                    }}
    338 gpx.set_refinement(refdict2,phase=phase0,histogram=[hist1])
    339368gpx.do_refinements([{}]) # refine after setting
    348377sample parameters using <tt>phase0.set_refinements()</tt> to set the
    349378"X" (coordinate) and "U" (displacement) refinement flags for all
    350 atoms. The original tutorial
    351 calls for the diffractometer radius to be changed. This parameter
    352 cannot be set from any GSASIIscriptable routines, but following a
    353 similar
    354 <A href="#ChangeCycles">process, as before</A>, the location for this
    355 setting can be located in the histogram's 'Sample Parameters' section
    356 (<tt>hist2.data['Sample Parameters']['Gonio. radius']</tt>).
     379atoms. This is done with this code:
    358381<blockquote><textarea rows="9" cols="75" readonly>
    368 Note that the settings provided in the
    369 <tt>phase0.set_refinements()</tt> statement could have been done using
    370 the <tt>gpx.do_refinements()</tt> call, but not those in the
    371 <tt>hist</tt><I>X</I><tt>.set_refinements()</tt> calls, since they
    372 must be different for each histogram.
     391Note that the original tutorial
     392calls for the diffractometer radius to be changed to the correct value
     393so that the displacement value is in the correct units. This parameter
     394cannot be set from any GSASIIscriptable routines, but following a
     395similar process,
     396<A href="#ChangeCycles">as before</A>, the location for this
     397setting can be located in the histogram's 'Sample Parameters' section
     398(as <tt>hist2.data['Sample Parameters']['Gonio. radius']</tt>).
     400Also note that the settings provided in the
     401<tt>phase0.set_refinements()</tt> and statements
     402<tt>gpx.do_refinements()</tt> could have
     403been combined into this single statement:
    405 </blockquote><hr>
     439<a name="SingeStep"><h2>Single Step Approach</h2></a>
     442As is noted in the
     443<A href="http://gsas-ii.readthedocs.io/en/latest/GSASIIscripts.html" target="_blank">
     444GSASIIscriptable module documentation</A>,
     445the <I>project</i><tt>.do_refinements()</tt> method can be used to
     446perform multiple refinement steps. To duplicate the above steps into a
     447single call a more complex set of dicts must be created, as shown
     450<blockquote><textarea rows="39" cols="75" readonly>
     451# tutorial step 4: turn on background refinement (Hist)
     452refdict0 = {"set": {"Background": { "no. coeffs": 3, "refine": True }},
     453            "output":'step4.gpx',
     454            "call":HistStats,"callargs":[gpx]} # callargs actually unneeded
     455                                               # as [gpx] is the default
     456# tutorial step 5: add unit cell refinement (Phase)
     457refdict1 = {"set": {"Cell": True},    # set the cell flag (for all phases)
     458            "output":'step5.gpx', "call":HistStats}
     459# tutorial step 6: add Dij terms (HAP) for phase 1 only
     460refdict2 = {"set": {"HStrain": True},  # set HAP parameters
     461            "histograms":[hist1],      # histogram 1 only
     462            "phases":[phase0],         # unneeded (default is all
     463                                       # phases) included as a example
     464            "output":'step6.gpx', "call":HistStats}
     465# tutorial step 7: add size & strain broadening (HAP) for histogram 1 only
     466refdict3 = {"set": {"Mustrain": {"type":"isotropic","refine":True},
     467                    "Size":{"type":"isotropic","refine":True},},
     468            "histograms":[hist1],      # histogram 1 only
     469            "output":'step7.gpx', "call":HistStats}
     470# tutorial step 8: add sample parameters & set radius (Hist); refine
     471#                  atom parameters (phase)
     472refdict4a = {"set": {'Sample Parameters': ['Shift']},
     473            "histograms":[hist1],      # histogram 1 only
     474             "skip": True}
     475refdict4b = {"set": {"Atoms":{"all":"XU"}, # not affected by histograms
     476             'Sample Parameters': ['DisplaceX', 'DisplaceY']},
     477            "histograms":[hist2],      # histogram 2 only
     478            "output":'step8.gpx', "call":HistStats}
     479# tutorial step 9: change data limits & inst. parm refinements (Hist)
     480refdict5a = {"set": {'Limits': [16.,158.4]},
     481            "histograms":[hist1],      # histogram 1 only
     482             "skip": True,}
     483refdict5b = {"set": {'Limits': [19.,153.]},
     484            "histograms":[hist2],      # histogram 2 only
     485             "skip": True}
     486refdict5c = {"set": {'Instrument Parameters': ['U', 'V', 'W']},
     487            "output":'step9.gpx', "call":HistStats}
     490Note that above the "call" and "callargs" dict entries are
     491defined to run <tt>HistStats</tt> and "output" is used to designate
     492the .gpx file that will be needed. When parameters should be changed
     493in specific histograms, the entries <tt>"histograms":[hist1]</tt> and
     494<tt>"histograms":[hist2]</tt> are used
     495(equivalent would be <tt>"histograms":[0]</tt> and
     497Since there is only one phase present, use of <tt>"phase":[0]</tt> is
     498superfluous, but in a more complex refinement, this could be needed.
     500A list of dicts is then prepared here:
     501<blockquote><textarea rows="3" cols="75" readonly>
     502dictList = [refdict0,refdict1,refdict2,refdict3,
     503            refdict4a,refdict4b,
     504            refdict5a,refdict5b,refdict5c]
     506Steps 4 through 10, above then can be performed with these few commands:
     507<blockquote><textarea rows="4" cols="75" readonly>
     508# Change number of cycles and radius
     509gpx.data['Controls']['data']['max cyc'] = 8 # not in API
     510hist2.data['Sample Parameters']['Gonio. radius'] = 650. # not in API
    407 <!-- hhmts start -->Last modified: Thu Oct 12 10:45:51 CDT 2017 <!-- hhmts end -->
     518<!-- hhmts start -->Last modified: Fri Dec 22 16:24:53 CST 2017 <!-- hhmts end -->
    408519</body> </html>
Note: See TracChangeset for help on using the changeset viewer.