Changeset 3849


Ignore:
Timestamp:
Mar 10, 2019 9:21:51 PM (3 years ago)
Author:
toby
Message:

finish sequential ref. via scripting; doc updates

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIscriptable.py

    r3845 r3849  
    4747    gpx.set_refinement(pardict)
    4848
    49 Most functionallity is provided via the objects and methods described in this section.
     49GSASIIscriptable can be used to setup and start sequential refinements. This script
     50is used to take the single-dataset fit at the end of Step 1 of the
     51`Sequential Refinement tutorial <https://subversion.xray.aps.anl.gov/pyGSAS/Tutorials/SeqRefine/SequentialTutorial.htm>`
     52and turn off refinement flags, add histograms and setup the sequential fit, which is then run:
     53
     54.. code-block::  python
     55
     56    import os,sys,glob
     57    sys.path.insert(0,'/Users/toby/software/G2/GSASII')
     58    import GSASIIscriptable as G2sc
     59    datadir = os.path.expanduser("~/Scratch/SeqTut2019Mar")
     60    PathWrap = lambda fil: os.path.join(datadir,fil)
     61    # load and rename project
     62    gpx = G2sc.G2Project(PathWrap('7Konly.gpx'))
     63    gpx.save(PathWrap('SeqRef.gpx'))
     64    # turn off some variables; turn on Dijs
     65    for p in gpx.phases():
     66        p.set_refinements({"Cell": False})
     67    gpx.phase(0).set_HAP_refinements(
     68        {'Scale': False,
     69         "Size": {'type':'isotropic', 'refine': False},
     70         "Mustrain": {'type':'uniaxial', 'refine': False},
     71         "HStrain":True,})
     72    gpx.phase(1).set_HAP_refinements({'Scale': False})
     73    gpx.histogram(0).clear_refinements({'Background':False,
     74                     'Sample Parameters':['DisplaceX'],})
     75    gpx.histogram(0).ref_back_peak(0,[])
     76    gpx.phase(1).set_HAP_refinements({"HStrain":(1,1,1,0)})
     77    for fil in sorted(glob.glob(PathWrap('*.fxye'))): # load in remaining fxye files
     78        if '00' in fil: continue
     79        gpx.add_powder_histogram(fil, PathWrap('OH_00.prm'), fmthint="GSAS powder",phases='all')
     80    # copy HAP values, background, instrument params. & limits, not sample params.
     81    gpx.copyHistParms(0,'all',['b','i','l'])
     82    for p in gpx.phases(): p.copyHAPvalues(0,'all')
     83    # setup and launch sequential fit
     84    gpx.set_Controls('sequential',gpx.histograms())
     85    gpx.set_Controls('cycles',10)
     86    gpx.set_Controls('seqCopy',True)
     87    gpx.refine() 
     88
     89Most functionality is provided via the objects and methods described in this section.
    5090
    5191---------------------
     
    98138method                                                Use
    99139==================================================    ===============================================================================================================
    100 :meth:`G2Phase.set_refinements`                       Provides a mechanism to set values and refinement flags for the phase. See the :ref:`Phase_parameters_table`
     140:meth:`G2Phase.set_refinements`                       Provides a mechanism to set values and refinement flags for the phase. See :ref:`Phase_parameters_table`
    101141                                                      for more details. This information also can be supplied within a call to :meth:`G2Project.do_refinements`
    102142                                                      or :meth:`G2Project.set_refinement`.
    103143:meth:`G2Phase.clear_refinements`                     Unsets refinement flags for the phase.
    104144:meth:`G2Phase.set_HAP_refinements`                   Provides a mechanism to set values and refinement flags for parameters specific to both this phase and
    105                                                       one of its histograms. See the :ref:`HAP_parameters_table`. This information also can be supplied within
     145                                                      one of its histograms. See :ref:`HAP_parameters_table`. This information also can be supplied within
    106146                                                      a call to :meth:`G2Project.do_refinements` or :meth:`G2Project.set_refinement`.
    107147:meth:`G2Phase.clear_HAP_refinements`                 Clears refinement flags specific to both this phase and one of its histograms.
    108148:meth:`G2Phase.getHAPvalues`                          Returns values of parameters specific to both this phase and one of its histograms.
     149:meth:`G2Phase.copyHAPvalues`                         Copies HAP settings between from one phase/histogram and to other histograms in same phase.
    109150:meth:`G2Phase.atoms`                                 Returns a list of atoms in the phase
    110151:meth:`G2Phase.atom`                                  Returns an atom from its label
     
    112153:meth:`G2Phase.get_cell`                              Returns unit cell parameters (also see :meth:`G2Phase.get_cell_and_esd`)
    113154:meth:`G2Phase.export_CIF`                            Writes a CIF for the phase
     155:meth:`G2Phase.set_Controls`                          Set overall GSAS-II control settings such as number of cycles and to set up a sequential
     156                                                      fit. (Also see :meth:`G2Phase.get_Controls` to read values.)
    114157==================================================    ===============================================================================================================
    115158
     
    125168method                                                Use
    126169==================================================    ===============================================================================================================
    127 :meth:`G2PwdrData.set_refinements`                    Provides a mechanism to set values and refinement flags for the powder histogram. See the
     170:meth:`G2PwdrData.set_refinements`                    Provides a mechanism to set values and refinement flags for the powder histogram. See
    128171                                                      :ref:`Histogram_parameters_table` for details. 
    129172:meth:`G2PwdrData.clear_refinements`                  Unsets refinement flags for the the powder histogram.
    130 :meth:`G2PwdrData.residuals`                          Reports R-factors etc. for the the powder histogram (also see :meth:`G2PwdrData.get_wR`
     173:meth:`G2PwdrData.residuals`                          Reports R-factors etc. for the the powder histogram (also see :meth:`G2PwdrData.get_wR`)
    131174:meth:`G2PwdrData.add_back_peak`                      Adds a background peak to the histogram. Also see :meth:`G2PwdrData.del_back_peak` and
    132175                                                      :meth:`G2PwdrData.ref_back_peak`.
     
    165208  When working with phases, :class:`G2AtomRecord` objects provide access to the contents of each atom in a phase. This provides access to "properties" that can be
    166209  used to get values of much of the atoms associated settings: label, type, refinement_flags, coordinates, occupancy, ranId, adp_flag, and uiso. In addition,
    167   refinement_flags, occupancy and uiso can be used to set values. See the class docs and source code.
     210  refinement_flags, occupancy and uiso can be used to set values. See the :class:`G2AtomRecord` docs and source code.
    168211
    169212.. _Refinement_dicts:
     
    408451\                     Scale                 Histogram Scale factor
    409452
    410 Background                                  Sample background. If value is a boolean,
    411                                             the background's 'refine' parameter is set
    412                                             to the given boolean. Usually should be a
    413                                             dictionary with any of the following keys:
     453Background                                  Sample background. Value will be a dict or
     454                                            a boolean. If True or False, the refine
     455                                            parameter for background is set to that.
     456                                            Note that background peaks are not handled
     457                                            via this; see
     458                                            :meth:`G2PwdrData.ref_back_peak` instead.
     459                                            When value is a dict,
     460                                            supply any of the following keys:
    414461\                     type                  The background model, e.g. 'chebyschev'
    415462\                     refine                The value of the refine flag, boolean
     
    496543\               BabU
    497544Extinction                             Boolean, True to refine.
    498 HStrain                                Boolean, True to refine all appropriate
    499                                        $D_ij$ terms.
     545HStrain                                Boolean or list/tuple, True to refine all
     546                                       appropriate D\ :sub:`ij` terms or False
     547                                       to not refine any. If a list/tuple, will
     548                                       be a set of True & False values for each
     549                                       D\ :sub:`ij` term; number of items must
     550                                       match number of terms.
    500551Mustrain
    501552\               type                   Mustrain model. One of 'isotropic',
    502                                        'uniaxial', or 'generalized'. Should always
    503                                        be specified.
     553                                       'uniaxial', or 'generalized'. **Should always
     554                                       be included when Mustrain is used.**
    504555\              direction               For uniaxial only. A list of three
    505556                                       integers,
     
    513564Size                                   
    514565\               type                   Size broadening model. One of 'isotropic',
    515                                        'uniaxial', or 'ellipsoid'. Should always
    516                                        be specified.
     566                                       'uniaxial', or 'ellipsoid'. **Should always
     567                                       be specified when Size is used.**
    517568\              direction               For uniaxial only. A list of three
    518569                                       integers,
     
    598649       python <path/>GSASIIscriptable.py <subcommand> <file.gpx> <options>
    599650
    600     The following subcommands are defined:
     651The following subcommands are defined:
    601652
    602653        * create, see :func:`create`
     
    604655        * dump, see :func:`dump`
    605656        * refine, see :func:`refine`
    606         * seqrefine, see :func:`seqrefine`
    607657        * export, :func:`export`
    608658        * browse, see :func:`IPyBrowse`
     
    12411291    return HistName, [HistName] + names, output_dict
    12421292
    1243 
    12441293def _deep_copy_into(from_, into):
    12451294    """Helper function for reloading .gpx file. See G2Project.reload()
     
    14851534        :param str datafile: The powder data file to read, a filename.
    14861535        :param str iparams: The instrument parameters file, a filename.
    1487         :param list phases: Phases to link to the new histogram
     1536        :param list phases: A list of phases to link to the new histogram,
     1537           phases can be references by object, name, rId or number.
     1538           Alternately, use 'all' to link to all phases in the project.
    14881539        :param str fmthint: If specified, only importers where the format name
    14891540          (reader.formatName, as shown in Import menu) contains the
     
    15221573        self.update_ids()
    15231574
     1575        if phases == 'all':
     1576            phases = self.phases()
    15241577        for phase in phases:
    15251578            phase = self.phase(phase)
     
    16931746        .. seealso::
    16941747
    1695             :meth:`G2Project.histogram`
    1696             :meth:`G2Project.phase`"""
     1748            :meth:`~G2Project.histogram`
     1749            :meth:`~G2Project.phase`"""
    16971750        hist = self.histogram(histogram)
    16981751        phase = self.phase(phase)
     
    17191772            raise RuntimeError("Unexpected histogram" + hist.name)
    17201773
    1721 
    17221774    def reload(self):
    17231775        """Reload self from self.filename"""
     
    17301782
    17311783    def refine(self, newfile=None, printFile=None, makeBack=False):
    1732         # TODO migrate to RefineCore
    1733         # G2strMain.RefineCore(Controls,Histograms,Phases,restraintDict,rigidbodyDict,parmDict,varyList,
    1734         #      calcControls,pawleyLookup,ifPrint,printFile,dlg)
    1735         # index_ids will automatically save the project
    1736         self.index_ids()
    1737         # TODO G2strMain does not properly use printFile
    1738         G2strMain.Refine(self.filename, makeBack=makeBack)
    1739         # Reload yourself
    1740         self.reload()
     1784        '''Invoke a refinement for the project. The project is written to
     1785        the currently selected gpx file and then either a single or sequential refinement
     1786        is performed depending on the setting of 'Seq Data' in Controls
     1787        (set in :meth:`get_Controls`).
     1788        '''
     1789        seqSetting = self.data['Controls']['data'].get('Seq Data',[])
     1790        if not seqSetting:
     1791            self.index_ids()    # index_ids will automatically save the project
     1792            # TODO: migrate to RefineCore G2strMain does not properly use printFile
     1793            # G2strMain.RefineCore(Controls,Histograms,Phases,restraintDict,rigidbodyDict,parmDict,varyList,
     1794            #      calcControls,pawleyLookup,ifPrint,printFile,dlg)
     1795            G2strMain.Refine(self.filename, makeBack=makeBack)
     1796        else:
     1797            self._seqrefine()
     1798        self.reload() # get file from GPX
     1799
     1800    def _seqrefine(self):
     1801        '''Perform a sequential refinement.
     1802        '''
     1803
     1804        self.data['Controls']['data']['ShowCell'] = True
     1805        # add to tree item to project, if not present
     1806        if 'Sequential results' not in self.data:
     1807            self.data['Sequential results'] = {'data':{}}
     1808            self.names.append(['Sequential results'])
     1809        self.index_ids()    # index_ids will automatically save the project
     1810        #GSASIIpath.IPyBreak_base()
     1811
     1812        # check that constraints are OK
     1813        errmsg, warnmsg = G2strIO.ReadCheckConstraints(self.filename)
     1814        if errmsg:
     1815            print('Refinement error',errmsg)
     1816            raise Exception('Constraint error')
     1817        if warnmsg:
     1818            print(u'Conflict between refinment flag settings and constraints:\n'+
     1819                  warnmsg+u'\nRefinement not possible')
     1820            raise Exception('Constraint error')
     1821        OK,Msg = G2strMain.SeqRefine(self.filename,None)
    17411822
    17421823    def histogram(self, histname):
     
    17481829
    17491830        .. seealso::
    1750             :meth:`G2Project.histograms`
    1751             :meth:`G2Project.phase`
    1752             :meth:`G2Project.phases`
     1831            :meth:`~G2Project.histograms`
     1832            :meth:`~G2Project.phase`
     1833            :meth:`~G2Project.phases`
    17531834        """
    17541835        if isinstance(histname, G2PwdrData):
    17551836            if histname.proj == self:
    17561837                return histname
     1838            else:
     1839                raise Exception('Histogram object (G2PwdrData) is not in current project')
    17571840        if histname in self.data:
    17581841            return G2PwdrData(self.data[histname], self)
     
    17781861
    17791862        .. seealso::
    1780             :meth:`G2Project.histogram`
    1781             :meth:`G2Project.phase`
    1782             :meth:`G2Project.phases`
     1863            :meth:`~G2Project.histogram`
     1864            :meth:`~G2Project.phase`
     1865            :meth:`~G2Project.phases`
    17831866        """
    17841867        output = []
     
    18061889
    18071890        .. seealso::
    1808             :meth:`G2Project.histograms`
    1809             :meth:`G2Project.phase`
    1810             :meth:`G2Project.phases`
     1891            :meth:`~G2Project.histograms`
     1892            :meth:`~G2Project.phase`
     1893            :meth:`~G2Project.phases`
    18111894            """
    18121895        if isinstance(phasename, G2Phase):
     
    18341917
    18351918        .. seealso::
    1836             :meth:`G2Project.histogram`
    1837             :meth:`G2Project.histograms`
    1838             :meth:`G2Project.phase`
     1919            :meth:`~G2Project.histogram`
     1920            :meth:`~G2Project.histograms`
     1921            :meth:`~G2Project.phase`
    18391922            """
    18401923        for obj in self.names:
     
    18591942
    18601943        .. seealso::
    1861             :meth:`G2Project.images`
     1944            :meth:`~G2Project.images`
    18621945        """
    18631946        if isinstance(imageRef, G2Image):
     
    20562139            phases = [phase]
    20572140
    2058         # TODO: HAP parameters:
    2059         #   Babinet
    2060         #   Extinction
    2061         #   HStrain
    2062         #   Mustrain
    2063         #   Pref. Ori
    2064         #   Size
    2065 
    20662141        pwdr_set = {}
    20672142        phase_set = {}
     
    21072182
    21082183    def index_ids(self):
    2109         import GSASIIstrIO as G2strIO
    21102184        self.save()
    21112185        return G2strIO.GetUsedHistogramsAndPhases(self.filename)
     
    21412215    def make_var_obj(self, phase=None, hist=None, varname=None, atomId=None,
    21422216                     reloadIdx=True):
    2143         """Wrapper to create a G2VarObj. Takes either a string representaiton ("p:h:name:a")
     2217        """Wrapper to create a G2VarObj. Takes either a string representation ("p:h:name:a")
    21442218        or individual names of phase, histogram, varname, and atomId.
    21452219
     
    23002374            objlist.append(G2Image(self.data[TreeName], TreeName, self))
    23012375        return objlist
    2302 
     2376   
     2377    def get_Controls(self, control):
     2378        '''Return project controls settings
     2379
     2380        :param str control: the item to be returned. See below for allowed values.
     2381        :returns: The value for the control.
     2382
     2383        Allowed values for parameter control:
     2384
     2385            * cycles: the maximum number of cycles (returns int)
     2386            * sequential: the histograms used for a sequential refinement as a list
     2387              of histogram names or an empty list when in non-sequential mode.
     2388            * seqCopy: returns True or False. True indicates that results from
     2389              each sequential fit are used as the starting point for the next
     2390              histogram.
     2391            * Anything else returns the value in the Controls dict, if present. An
     2392              exception is raised if the control value is not present.
     2393
     2394        .. seealso::
     2395            :meth:`set_Controls`
     2396        '''
     2397        if control == 'cycles':
     2398            return self.data['Controls']['data']['max cyc']
     2399        elif control == 'sequential':
     2400            return self.data['Controls']['data']['Seq Data']
     2401        elif control in self.data['Controls']['data']:
     2402            return self.data['Controls']['data'][control]
     2403        elif control == 'seqCopy':
     2404            self.data['Controls']['data']['Copy2Next'] = bool(value)
     2405        else:
     2406            print('Defined Controls:',self.data['Controls']['data'].keys())
     2407            raise Exception('{} is an invalid control value'.format(control))
     2408       
     2409    def set_Controls(self, control, value):
     2410        '''Set project controls
     2411
     2412        :param str control: the item to be set. See below for allowed values.
     2413        :param value: the value to be set.
     2414
     2415        Allowed values for parameter control:
     2416
     2417            * cycles: sets the maximum number of cycles (value must be int)
     2418            * sequential: sets the histograms to be used for a sequential refinement.
     2419              Use an empty list to turn off sequential fitting.
     2420              The values in the list may be the name of the histogram (a str), or
     2421              a ranId or index (int values), see :meth:`histogram`.
     2422            * seqCopy: when True, the results from each sequential fit are used as
     2423              the starting point for the next. After each fit is is set to False.
     2424              Ignored for non-sequential fits.
     2425
     2426        .. seealso::
     2427            :meth:`get_Controls`
     2428        '''
     2429        if control == 'cycles':
     2430            self.data['Controls']['data']['max cyc'] = int(value)
     2431        elif control == 'seqCopy':
     2432            self.data['Controls']['data']['Copy2Next'] = bool(value)
     2433        elif control == 'sequential':
     2434            histlist = []
     2435            for i,j in enumerate(value):
     2436                h = self.histogram(j)
     2437                if h:
     2438                    histlist.append(h.name)
     2439                else:
     2440                    raise Exception('item #{} ({}) is an invalid histogram value'
     2441                                        .format(i,j))
     2442            self.data['Controls']['data']['Seq Data'] = histlist
     2443        else:
     2444            raise Exception('{} is an invalid control value'.format(control))
     2445       
     2446    def copyHistParms(self,sourcehist,targethistlist='all',modelist='all'):
     2447        '''Copy histogram information from one histogram to others
     2448
     2449        :param sourcehist: is a histogram object (:class:`G2PwdrData`) or
     2450            a histogram name or the index number of the histogram
     2451        :param list targethistlist: a list of histograms where each item in the
     2452            list can be a histogram object (:class:`G2PwdrData`),
     2453            a histogram name or the index number of the histogram.
     2454            if the string 'all' (default value), then all histograms in
     2455            the project are used.
     2456        :param list modelist: May be a list of sections to copy, which may
     2457           include 'Background', 'Instrument Parameters', 'Limits' and
     2458           'Sample Parameters' (items may be shortened to uniqueness and
     2459           capitalization is ignored, so ['b','i','L','s'] will work.)
     2460           The default value, 'all' causes the listed sections to
     2461
     2462        '''
     2463        sections = ('Background','Instrument Parameters','Limits',
     2464                        'Sample Parameters')
     2465        hist_in = self.histogram(sourcehist)
     2466        if not hist_in:
     2467            raise Exception('{} is not a valid histogram'.format(sourcehist))
     2468        if targethistlist == "all":
     2469            targethistlist = self.histograms()
     2470        if 'all' in modelist:
     2471            copysections = sections
     2472        else:
     2473            copysections = set()
     2474            for s in sections:
     2475                for m in modelist:
     2476                    if s.lower().startswith(m.lower()):
     2477                        copysections.add(s)
     2478        for h in targethistlist:
     2479            hist_out = self.histogram(h)
     2480            if not hist_out:
     2481                raise Exception('{} is not a valid histogram'.format(h))
     2482            for key in copysections:
     2483                hist_out[key] = copy.deepcopy(hist_in[key])
     2484       
    23032485class G2AtomRecord(G2ObjectWrapper):
    23042486    """Wrapper for an atom record. Has convenient accessors via @property.
     
    24002582            assert len(value) == 6
    24012583            self.data[self.cia+2:self.cia+8] = [float(v) for v in value]
    2402 
    24032584
    24042585class G2PwdrData(G2ObjectWrapper):
     
    26512832
    26522833    def set_refinements(self, refs):
    2653         """Sets the histogram refinement parameter 'key' to the specification 'value'
    2654 
    2655         :param dict refs: A dictionary of the parameters to be set. See
    2656                           :ref:`Histogram_parameters_table` for a description of
     2834        """Sets the histogram refinement parameter 'key' to the specification 'value'.
     2835
     2836        :param dict refs: A dictionary of the parameters to be set. See the
     2837                          :ref:`Histogram_parameters_table` table for a description of
    26572838                          what these dictionaries should be.
    26582839
     
    27342915        """Clears the refinement parameter 'key' and its associated value.
    27352916
    2736         :param dict refs: A dictionary of parameters to clear."""
     2917        :param dict refs: A dictionary of parameters to clear.
     2918          See the :ref:`Histogram_parameters_table` table for what can be specified.
     2919        """
    27372920        for key, value in refs.items():
    27382921            if key == 'Limits':
     
    29263109
    29273110    def atoms(self):
    2928         """Returns a list of atoms present in the phase.
     3111        """Returns a list of atoms present in the current phase.
    29293112
    29303113        :returns: A list of :class:`G2AtomRecord` objects.
    29313114
    29323115        .. seealso::
    2933             :meth:`G2Phase.atom`
     3116            :meth:`~G2Phase.atom`
    29343117            :class:`G2AtomRecord`
    29353118        """
     
    29423125
    29433126    def histograms(self):
     3127        '''Returns a list of histogram names associated with the current phase.
     3128        '''
    29443129        output = []
    29453130        for hname in self.data.get('Histograms', {}).keys():
     
    29663151
    29673152        .. seealso::
    2968            :meth:`G2Phase.get_cell_and_esd`
     3153           :meth:`~G2Phase.get_cell_and_esd`
    29693154
    29703155        """
     
    29823167
    29833168        .. seealso::
    2984            :meth:`G2Phase.get_cell`
     3169           :meth:`~G2Phase.get_cell`
    29853170
    29863171        """
    29873172        # translated from GSASIIstrIO.ExportBaseclass.GetCell
    2988         import GSASIIstrIO as G2stIO
    29893173        import GSASIIlattice as G2lat
    29903174        import GSASIImapvars as G2mv
     
    30043188                                                  parmDict))
    30053189
    3006             A, sigA = G2stIO.cellFill(pfx, sgdata, parmDict, sigDict)
    3007             cellSig = G2stIO.getCellEsd(pfx, sgdata, A, self.proj['Covariance']['data'])
     3190            A, sigA = G2strIO.cellFill(pfx, sgdata, parmDict, sigDict)
     3191            cellSig = G2strIO.getCellEsd(pfx, sgdata, A, self.proj['Covariance']['data'])
    30083192            cellList = G2lat.A2cell(A) + (G2lat.calc_V(A),)
    30093193            cellDict, cellSigDict = {}, {}
     
    31023286
    31033287    def set_refinements(self, refs):
    3104         """Sets the refinement parameter 'key' to the specification 'value'
    3105 
    3106         :param dict refs: A dictionary of the parameters to be set. See
    3107                           :ref:`Phase_parameters_table` for a description of
     3288        """Sets the phase refinement parameter 'key' to the specification 'value'
     3289
     3290        :param dict refs: A dictionary of the parameters to be set. See the
     3291                          :ref:`Phase_parameters_table` table for a description of
    31083292                          this dictionary.
    31093293
     
    31363320        """Clears a given set of parameters.
    31373321
    3138         :param dict refs: The parameters to clear"""
     3322        :param dict refs: The parameters to clear.
     3323          See the :ref:`Phase_parameters_table` table for what can be specified.
     3324        """
    31393325        for key, value in refs.items():
    31403326            if key == "Cell":
     
    31583344    def set_HAP_refinements(self, refs, histograms='all'):
    31593345        """Sets the given HAP refinement parameters between this phase and
    3160         the given histograms
     3346        the given histograms.
    31613347
    31623348        :param dict refs: A dictionary of the parameters to be set. See
    3163                           :ref:`HAP_parameters_table` for a description of this
     3349                          the :ref:`HAP_parameters_table` table for a description of this
    31643350                          dictionary.
    31653351        :param histograms: Either 'all' (default) or a list of the histograms
     
    31833369            return
    31843370        for key, val in refs.items():
    3185             for h in histograms:
    3186                 if key == 'Babinet':
    3187                     try:
    3188                         sets = list(val)
    3189                     except ValueError:
    3190                         sets = ['BabA', 'BabU']
    3191                     for param in sets:
    3192                         if param not in ['BabA', 'BabU']:
    3193                             raise ValueError("Not sure what to do with" + param)
    3194                         for hist in histograms:
    3195                             hist['Babinet'][param][1] = True
    3196                 elif key == 'Extinction':
     3371            if key == 'Babinet':
     3372                try:
     3373                    sets = list(val)
     3374                except ValueError:
     3375                    sets = ['BabA', 'BabU']
     3376                for param in sets:
     3377                    if param not in ['BabA', 'BabU']:
     3378                        raise ValueError("Not sure what to do with" + param)
    31973379                    for h in histograms:
    3198                         h['Extinction'][1] = bool(val)
    3199                 elif key == 'HStrain':
     3380                        h['Babinet'][param][1] = True
     3381            elif key == 'Extinction':
     3382                for h in histograms:
     3383                    h['Extinction'][1] = bool(val)
     3384            elif key == 'HStrain':
     3385                if isinstance(val,list) or isinstance(val,tuple):
     3386                    for h in histograms:
     3387                        if len(h['HStrain'][1]) != len(val):
     3388                            raise Exception('Need {} HStrain terms for phase {}'
     3389                                .format(len(h['HStrain'][1]),self.name))
     3390                        for i,v in enumerate(val):
     3391                            h['HStrain'][1][i] = bool(v)
     3392                else:
    32003393                    for h in histograms:
    32013394                        h['HStrain'][1] = [bool(val) for p in h['HStrain'][1]]
    3202                 elif key == 'Mustrain':
    3203                     for h in histograms:
    3204                         mustrain = h['Mustrain']
    3205                         newType = None
    3206                         direction = None
    3207                         if isinstance(val, strtypes):
    3208                             if val in ['isotropic', 'uniaxial', 'generalized']:
    3209                                 newType = val
     3395            elif key == 'Mustrain':
     3396                for h in histograms:
     3397                    mustrain = h['Mustrain']
     3398                    newType = None
     3399                    direction = None
     3400                    if isinstance(val, strtypes):
     3401                        if val in ['isotropic', 'uniaxial', 'generalized']:
     3402                            newType = val
     3403                        else:
     3404                            raise ValueError("Not a Mustrain type: " + val)
     3405                    elif isinstance(val, dict):
     3406                        newType = val.get('type', None)
     3407                        direction = val.get('direction', None)
     3408
     3409                    if newType:
     3410                        mustrain[0] = newType
     3411                        if newType == 'isotropic':
     3412                            mustrain[2][0] = True == val.get('refine',False)
     3413                            mustrain[5] = [False for p in mustrain[4]]
     3414                        elif newType == 'uniaxial':
     3415                            if 'refine' in val:
     3416                                mustrain[2][0] = False
     3417                                types = val['refine']
     3418                                if isinstance(types, strtypes):
     3419                                    types = [types]
     3420                                elif isinstance(types, bool):
     3421                                    mustrain[2][1] = types
     3422                                    mustrain[2][2] = types
     3423                                    types = []
     3424                                else:
     3425                                    raise ValueError("Not sure what to do with: "
     3426                                                     + str(types))
    32103427                            else:
    3211                                 raise ValueError("Not a Mustrain type: " + val)
    3212                         elif isinstance(val, dict):
    3213                             newType = val.get('type', None)
    3214                             direction = val.get('direction', None)
    3215 
    3216                         if newType:
    3217                             mustrain[0] = newType
    3218                             if newType == 'isotropic':
    3219                                 mustrain[2][0] = True == val.get('refine',False)
    3220                                 mustrain[5] = [False for p in mustrain[4]]
    3221                             elif newType == 'uniaxial':
    3222                                 if 'refine' in val:
    3223                                     mustrain[2][0] = False
    3224                                     types = val['refine']
    3225                                     if isinstance(types, strtypes):
    3226                                         types = [types]
    3227                                     elif isinstance(types, bool):
    3228                                         mustrain[2][1] = types
    3229                                         mustrain[2][2] = types
    3230                                         types = []
    3231                                     else:
    3232                                         raise ValueError("Not sure what to do with: "
    3233                                                          + str(types))
     3428                                types = []
     3429
     3430                            for unitype in types:
     3431                                if unitype == 'equatorial':
     3432                                    mustrain[2][0] = True
     3433                                elif unitype == 'axial':
     3434                                    mustrain[2][1] = True
    32343435                                else:
    3235                                     types = []
    3236 
    3237                                 for unitype in types:
    3238                                     if unitype == 'equatorial':
    3239                                         mustrain[2][0] = True
    3240                                     elif unitype == 'axial':
    3241                                         mustrain[2][1] = True
    3242                                     else:
    3243                                         msg = 'Invalid uniaxial mustrain type'
    3244                                         raise ValueError(msg + ': ' + unitype)
    3245                             else:  # newtype == 'generalized'
    3246                                 mustrain[2] = [False for p in mustrain[1]]
    3247                                 if 'refine' in val:
    3248                                     mustrain[5] = [True == val['refine']]*len(mustrain[5])
    3249 
    3250                         if direction:
    3251                             if len(direction) != 3:
    3252                                 raise ValueError("Expected hkl, found", direction)
    3253                             direction = [int(n) for n in direction]
    3254                             mustrain[3] = direction
    3255                 elif key == 'Size':
    3256                     newSize = None
    3257                     if 'value' in val:
    3258                         newSize = float(val['value'])
    3259                     for h in histograms:
    3260                         size = h['Size']
    3261                         newType = None
    3262                         direction = None
    3263                         if isinstance(val, strtypes):
    3264                             if val in ['isotropic', 'uniaxial', 'ellipsoidal']:
    3265                                 newType = val
    3266                             else:
    3267                                 raise ValueError("Not a valid Size type: " + val)
    3268                         elif isinstance(val, dict):
    3269                             newType = val.get('type', None)
    3270                             direction = val.get('direction', None)
    3271 
    3272                         if newType:
    3273                             size[0] = newType
    3274                             refine = True == val.get('refine')
    3275                             if newType == 'isotropic' and refine is not None:
    3276                                 size[2][0] = bool(refine)
    3277                                 if newSize: size[1][0] = newSize
    3278                             elif newType == 'uniaxial' and refine is not None:
    3279                                 size[2][1] = bool(refine)
    3280                                 size[2][2] = bool(refine)
    3281                                 if newSize: size[1][1] = size[1][2] =newSize
    3282                             elif newType == 'ellipsoidal' and refine is not None:
    3283                                 size[5] = [bool(refine) for p in size[5]]
    3284                                 if newSize: size[4] = [newSize for p in size[4]]
    3285 
    3286                         if direction:
    3287                             if len(direction) != 3:
    3288                                 raise ValueError("Expected hkl, found", direction)
    3289                             direction = [int(n) for n in direction]
    3290                             size[3] = direction
    3291                 elif key == 'Pref.Ori.':
    3292                     for h in histograms:
    3293                         h['Pref.Ori.'][2] = bool(val)
    3294                 elif key == 'Show':
    3295                     for h in histograms:
    3296                         h['Show'] = bool(val)
    3297                 elif key == 'Use':
    3298                     for h in histograms:
    3299                         h['Use'] = bool(val)
    3300                 elif key == 'Scale':
    3301                     for h in histograms:
    3302                         h['Scale'][1] = bool(val)
    3303                 else:
    3304                     print(u'Unknown HAP key: '+key)
    3305 
     3436                                    msg = 'Invalid uniaxial mustrain type'
     3437                                    raise ValueError(msg + ': ' + unitype)
     3438                        else:  # newtype == 'generalized'
     3439                            mustrain[2] = [False for p in mustrain[1]]
     3440                            if 'refine' in val:
     3441                                mustrain[5] = [True == val['refine']]*len(mustrain[5])
     3442
     3443                    if direction:
     3444                        if len(direction) != 3:
     3445                            raise ValueError("Expected hkl, found", direction)
     3446                        direction = [int(n) for n in direction]
     3447                        mustrain[3] = direction
     3448            elif key == 'Size':
     3449                newSize = None
     3450                if 'value' in val:
     3451                    newSize = float(val['value'])
     3452                for h in histograms:
     3453                    size = h['Size']
     3454                    newType = None
     3455                    direction = None
     3456                    if isinstance(val, strtypes):
     3457                        if val in ['isotropic', 'uniaxial', 'ellipsoidal']:
     3458                            newType = val
     3459                        else:
     3460                            raise ValueError("Not a valid Size type: " + val)
     3461                    elif isinstance(val, dict):
     3462                        newType = val.get('type', None)
     3463                        direction = val.get('direction', None)
     3464
     3465                    if newType:
     3466                        size[0] = newType
     3467                        refine = True == val.get('refine')
     3468                        if newType == 'isotropic' and refine is not None:
     3469                            size[2][0] = bool(refine)
     3470                            if newSize: size[1][0] = newSize
     3471                        elif newType == 'uniaxial' and refine is not None:
     3472                            size[2][1] = bool(refine)
     3473                            size[2][2] = bool(refine)
     3474                            if newSize: size[1][1] = size[1][2] =newSize
     3475                        elif newType == 'ellipsoidal' and refine is not None:
     3476                            size[5] = [bool(refine) for p in size[5]]
     3477                            if newSize: size[4] = [newSize for p in size[4]]
     3478
     3479                    if direction:
     3480                        if len(direction) != 3:
     3481                            raise ValueError("Expected hkl, found", direction)
     3482                        direction = [int(n) for n in direction]
     3483                        size[3] = direction
     3484            elif key == 'Pref.Ori.':
     3485                for h in histograms:
     3486                    h['Pref.Ori.'][2] = bool(val)
     3487            elif key == 'Show':
     3488                for h in histograms:
     3489                    h['Show'] = bool(val)
     3490            elif key == 'Use':
     3491                for h in histograms:
     3492                    h['Use'] = bool(val)
     3493            elif key == 'Scale':
     3494                for h in histograms:
     3495                    h['Scale'][1] = bool(val)
     3496            else:
     3497                print(u'Unknown HAP key: '+key)
     3498
     3499    def _decodeHist(self,hist):
     3500        '''Convert a histogram reference to a histogram name string
     3501        '''
     3502        if isinstance(hist, G2PwdrData):
     3503            return hist.name
     3504        elif hist in self.data['Histograms']:
     3505            return hist
     3506        elif type(hist) is int:
     3507            return self.proj.histograms()[hist].name
     3508        else:
     3509            raise G2ScriptException("Invalid histogram reference: "+str(hist))
     3510       
    33063511    def getHAPvalues(self, histname):
    33073512        """Returns a dict with HAP values for the selected histogram
     
    33123517        :returns: HAP value dict
    33133518        """
    3314         if isinstance(histname, G2PwdrData):
    3315             histname = histname.name
    3316         elif histname in self.data['Histograms']:
    3317             pass
    3318         elif type(histname) is int:
    3319             histname = self.proj.histograms()[histname].name
    3320         else:
    3321             raise G2ScriptException("Invalid histogram reference: "+str(histname))
    3322         return self.data['Histograms'][histname]
     3519        return self.data['Histograms'][self._decodeHist(histname)]
     3520
     3521    def copyHAPvalues(self, sourcehist, targethistlist, skip=[]):
     3522        """Returns a dict with HAP values for the selected histogram
     3523
     3524        :param sourcehist: is a histogram object (:class:`G2PwdrData`) or
     3525            a histogram name or the index number of the histogram
     3526        :param list targethistlist: a list of histograms where each item in the
     3527            list can be a histogram object (:class:`G2PwdrData`),
     3528            a histogram name or the index number of the histogram.
     3529            if the string 'all', then all histograms in the phase are used.
     3530        :param list skip: items in the HAP dict that should not be
     3531            copied. The default is an empty list, which causes all items
     3532            to be copied. To see a list of items in the dict, use
     3533            :meth:`getHAPvalues` or use an invalid item, such as '?'.
     3534        """
     3535        sourcehist = self._decodeHist(sourcehist)
     3536        if targethistlist == 'all':
     3537            targethistlist = list(self.data['Histograms'].keys())
     3538       
     3539        copydict = copy.deepcopy(self.data['Histograms'][sourcehist])
     3540        for item in skip:
     3541            if item in copydict:
     3542                del copydict[item]
     3543            else:
     3544                print('items in HAP dict are: {}'.format(
     3545                    list(self.data['Histograms'][sourcehist])))
     3546                raise Exception('HAP dict entry {} invalid'.format(item))
     3547        for h in targethistlist:
     3548            h = self._decodeHist(h)
     3549            self.data['Histograms'][h].update(copydict)
     3550           
     3551        #GSASIIpath.IPyBreak_base()
    33233552                   
    33243553    def clear_HAP_refinements(self, refs, histograms='all'):
    33253554        """Clears the given HAP refinement parameters between this phase and
    3326         the given histograms
     3555        the given histograms.
    33273556
    33283557        :param dict refs: A dictionary of the parameters to be cleared.
     3558            See the the :ref:`HAP_parameters_table` table for what can be specified.
    33293559        :param histograms: Either 'all' (default) or a list of the histograms
    33303560            whose HAP parameters will be cleared with this phase. Histogram and
     
    40254255
    40264256
    4027 commandhelp["seqrefine"] = "Not implemented. Placeholder for eventual sequential refinement implementation"
    4028 def seqrefine(args):
    4029     """Future implementation for the seqrefine command-line subcommand """
    4030     raise NotImplementedError("seqrefine is not yet implemented")
    4031 
    4032 
    40334257commandhelp["export"] = "Export phase as CIF"
    40344258def export(args):
     
    41374361                                      nargs='?')]),
    41384362
    4139                "seqrefine": (seqrefine, []),
    41404363               "export": (export, [_args_kwargs('gpxfile',
    41414364                                                help='the project file from which to export'),
     
    41584381        * dump, see :func:`dump`
    41594382        * refine, see :func:`refine`
    4160         * seqrefine, see :func:`seqrefine`
    41614383        * export, :func:`export`
    41624384        * browse, see :func:`IPyBrowse`
     
    41674389        :func:`dump`
    41684390        :func:`refine`
    4169         :func:`seqrefine`
    41704391        :func:`export`
    41714392        :func:`IPyBrowse`
  • trunk/GSASIIstrIO.py

    r3814 r3849  
    611611def GetSeqResult(GPXfile):
    612612    '''
    613     Needs doc string
     613    Returns the sequential results table information from a GPX file.
     614    Called at the beginning of :meth:`GSASIIstrMain.SeqRefine`
    614615   
    615616    :param str GPXfile: full .gpx file name
     617    :returns: a dict containing the sequential results table
    616618    '''
    617619    fl = open(GPXfile,'rb')
     
    630632def SetSeqResult(GPXfile,Histograms,SeqResult):
    631633    '''
    632     Needs doc string
    633    
     634    Places the sequential results information into a GPX file
     635    after a refinement has been completed.
     636    Called at the end of :meth:`GSASIIstrMain.SeqRefine`
     637
    634638    :param str GPXfile: full .gpx file name
    635639    '''
Note: See TracChangeset for help on using the changeset viewer.