Ignore:
Timestamp:
Aug 16, 2017 4:16:55 PM (4 years ago)
Author:
odonnell
Message:

CIF export. changelist:

  • Start using argparse module in GSASIIscriptable.py
  • G2Phase now has export_CIF method
  • GSASIIscriptable export method now works
  • refactoring of exports/G2export_CIF.py to reduce code duplication
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIscriptable.py

    r3009 r3011  
    3333from __future__ import division, print_function # needed?
    3434import os.path as ospath
     35import datetime as dt
    3536import sys
    3637import cPickle
     
    377378    generalData['Mass'] = G2mth.getMass(generalData)
    378379
     380
     381############################################
     382############ CIF export helpers ############
     383############################################
     384## These functions are translated from
     385## exports/G2export_CIF.py
     386## They are used in G2Phase.export_CIF
     387
     388
     389
    379390def make_empty_project(author=None, filename=None):
    380391    """Creates an dictionary in the style of GSASIIscriptable, for an empty
     
    14851496        return G2obj.PhaseRanIdLookup[self.ranId]
    14861497
    1487     def cell_dict(self):
     1498    def get_cell(self):
    14881499        """Returns a dictionary of the cell parameters, with keys:
    1489             'a', 'b', 'c', 'alpha', 'beta', 'gamma', 'vol'
     1500            'length_a', 'length_b', 'length_c', 'angle_alpha', 'angle_beta', 'angle_gamma', 'volume'
    14901501
    14911502        :returns: a dict"""
    14921503        cell = self['General']['Cell']
    1493         return {'a': cell[1], 'b': cell[2], 'c': cell[3],
    1494                 'alpha': cell[4], 'beta': cell[5], 'gamma': cell[6],
    1495                 'vol': cell[7]}
     1504        return {'length_a': cell[1], 'length_b': cell[2], 'length_c': cell[3],
     1505                'angle_alpha': cell[4], 'angle_beta': cell[5], 'angle_gamma': cell[6],
     1506                'volume': cell[7]}
     1507
     1508    def export_CIF(self, outputname, quickmode=True):
     1509        """Write this phase to a .cif file named outputname
     1510
     1511        :param str outputname: The name of the .cif file to write to
     1512        :param bool quickmode: Currently ignored. Carryover from exports.G2export_CIF"""
     1513        # This code is all taken from exports/G2export_CIF.py
     1514        # Functions copied have the same names
     1515        import GSASIImath as G2mth
     1516        import GSASIImapvars as G2mv
     1517        from exports import G2export_CIF as cif
     1518
     1519        CIFdate = dt.datetime.strftime(dt.datetime.now(),"%Y-%m-%dT%H:%M")
     1520        CIFname = os.path.splitext(self.proj.filename)[0]
     1521        CIFname = os.path.split(CIFname)[1]
     1522        CIFname = ''.join([c if ord(c) < 128 else ''
     1523                           for c in CIFname.replace(' ', '_')])
     1524        try:
     1525            author = self.proj['Controls'].get('Author','').strip()
     1526        except KeyError:
     1527            pass
     1528        oneblock = True
     1529
     1530        covDict = self.proj['Covariance']
     1531        parmDict = dict(zip(covDict.get('varyList',[]),
     1532                            covDict.get('variables',[])))
     1533        sigDict = dict(zip(covDict.get('varyList',[]),
     1534                           covDict.get('sig',[])))
     1535
     1536        if covDict.get('covMatrix') is not None:
     1537            sigDict.update(G2mv.ComputeDepESD(covDict['covMatrix'],
     1538                                              covDict['varyList'],
     1539                                              parmDict))
     1540
     1541        with open(outputname, 'w') as fp:
     1542            fp.write(' \n' + 70*'#' + '\n')
     1543            cif.WriteCIFitem(fp, 'data_' + CIFname)
     1544            # from exports.G2export_CIF.WritePhaseInfo
     1545            cif.WriteCIFitem(fp, '\n# phase info for '+str(self.name) + ' follows')
     1546            cif.WriteCIFitem(fp, '_pd_phase_name', self.name)
     1547            # TODO get esds
     1548            cellDict = self.get_cell()
     1549            defsigL = 3*[-0.00001] + 3*[-0.001] + [-0.01] # significance to use when no sigma
     1550            names = ['length_a','length_b','length_c',
     1551                     'angle_alpha','angle_beta ','angle_gamma',
     1552                     'volume']
     1553            for key, val in cellDict.items():
     1554                cif.WriteCIFitem(fp, '_cell_' + key, G2mth.ValEsd(val))
     1555
     1556            cif.WriteCIFitem(fp, '_symmetry_cell_setting',
     1557                         self['General']['SGData']['SGSys'])
     1558
     1559            spacegroup = self['General']['SGData']['SpGrp'].strip()
     1560            # regularize capitalization and remove trailing H/R
     1561            spacegroup = spacegroup[0].upper() + spacegroup[1:].lower().rstrip('rh ')
     1562            cif.WriteCIFitem(fp, '_symmetry_space_group_name_H-M', spacegroup)
     1563
     1564            # generate symmetry operations including centering and center of symmetry
     1565            SymOpList, offsetList, symOpList, G2oprList, G2opcodes = G2spc.AllOps(
     1566                self['General']['SGData'])
     1567            cif.WriteCIFitem(fp, 'loop_\n    _space_group_symop_id\n    _space_group_symop_operation_xyz')
     1568            for i, op in enumerate(SymOpList,start=1):
     1569                cif.WriteCIFitem(fp, '   {:3d}  {:}'.format(i,op.lower()))
     1570
     1571            # TODO skipped histograms, exports/G2export_CIF.py:880
     1572
     1573            # report atom params
     1574            if self['General']['Type'] in ['nuclear','macromolecular']:        #this needs macromolecular variant, etc!
     1575                cif.WriteAtomsNuclear(fp, self.data, self.name, parmDict, sigDict, [])
     1576                # self._WriteAtomsNuclear(fp, parmDict, sigDict)
     1577            else:
     1578                raise Exception,"no export for "+str(self['General']['Type'])+" coordinates implemented"
     1579            # report cell contents
     1580            cif.WriteComposition(fp, self.data, self.name, parmDict)
     1581            if not quickmode and self['General']['Type'] == 'nuclear':      # report distances and angles
     1582                # WriteDistances(fp,self.name,SymOpList,offsetList,symOpList,G2oprList)
     1583                raise NotImplementedError("only quickmode currently supported")
     1584            if 'Map' in self['General'] and 'minmax' in self['General']['Map']:
     1585                cif.WriteCIFitem(fp,'\n# Difference density results')
     1586                MinMax = self['General']['Map']['minmax']
     1587                cif.WriteCIFitem(fp,'_refine_diff_density_max',G2mth.ValEsd(MinMax[0],-0.009))
     1588                cif.WriteCIFitem(fp,'_refine_diff_density_min',G2mth.ValEsd(MinMax[1],-0.009))
     1589
    14961590
    14971591    def set_refinements(self, refs):
     
    16821776
    16831777
     1778# TODO SUBPARSERS
     1779
    16841780def create(*args):
    16851781    """The create subcommand.
    16861782
    16871783    Should be passed all the command-line arguments after `create`"""
    1688     proj = G2Project(filename=args[0])
     1784    import argparse
     1785    parser = argparse.ArgumentParser(prog=' '.join([sys.argv[0], sys.argv[1]]))
     1786    parser.add_argument('filename',
     1787                        help='the project file to create. should end in .gpx')
     1788    parser.add_argument('-g', '--histograms', nargs='+',
     1789                        help='list of histograms to add')
     1790    parser.add_argument('-p', '--phases', nargs='+',
     1791                        help='list of phases to add')
     1792    results = parser.parse_args(args)
     1793
     1794    proj = G2Project(filename=filename)
    16891795
    16901796    isPhase = False
     
    17241830def dump(*args):
    17251831    """The dump subcommand"""
    1726     raw = True
    1727     histograms = False
    1728     phases = False
    1729     filenames = []
    1730     for arg in args:
    1731         if arg in ['-h', '--histograms']:
    1732             histograms = True
    1733             raw = False
    1734         elif arg in ['-p', '--phases']:
    1735             phases = True
    1736             raw = False
    1737         elif arg in ['-r', '--raw']:
    1738             raw = True
    1739         else:
    1740             filenames.append(arg)
    1741     if raw:
     1832    import argparse
     1833    parser = argparse.ArgumentParser(prog=' '.join([sys.argv[0], sys.argv[1]]))
     1834    parser.add_argument('-g', '--histograms', action='store_true',
     1835                        help='list histograms in files, overrides --raw')
     1836    parser.add_argument('-p', '--phases', action='store_true',
     1837                        help='list phases in files, overrides --raw')
     1838    parser.add_argument('-r', '--raw', action='store_true',
     1839                        help='dump raw file contents')
     1840    parser.add_argument('files', nargs='*')
     1841    results = parser.parse_args(args)
     1842
     1843    if not results.histograms and not results.phases:
     1844        results.raw = True
     1845    if results.raw:
    17421846        import IPython.lib.pretty as pretty
    1743     for fname in filenames:
    1744         if raw:
     1847
     1848    for fname in results.files:
     1849        if results.raw:
    17451850            proj, nameList = LoadDictFromProjFile(fname)
    17461851            print("file:", fname)
     
    17511856        else:
    17521857            proj = G2Project(fname)
    1753             if histograms:
     1858            if results.histograms:
    17541859                hists = proj.histograms()
    17551860                for h in hists:
    17561861                    print(fname, "hist", h.id, h.name)
    1757             if phases:
     1862            if results.phases:
    17581863                phase_list = proj.phases()
    17591864                for p in phase_list:
     
    17761881    """The refine subcommand"""
    17771882    proj = G2Project(args[0])
    1778     proj.refine()
     1883    if len(args) == 1:
     1884        proj.refine()
     1885    elif len(args) == 2:
     1886        import json
     1887        with open(args[1]) as refs:
     1888            refs = json.load(refs)
     1889        proj.do_refinements(refs['refinements'])
     1890    else:
     1891        print("Refine not sure what to do with args:", args)
    17791892
    17801893
     
    17871900    """The export subcommand"""
    17881901    # Export CIF or Structure or ...
    1789     raise NotImplementedError("export is not yet implemented")
     1902    gpxfile, phase, exportfile = args
     1903    proj = G2Project(gpxfile)
     1904    phase = proj.phase(phase)
     1905    phase.export_CIF(exportfile)
    17901906
    17911907
     
    17991915
    18001916def main():
    1801     '''TODO: the command-line options need some thought
     1917    '''The command line interface for GSASIIscriptable.
     1918
     1919    Executes one of the following subcommands:
     1920
     1921        * :func:`create`
     1922        * :func:`dump`
     1923        * :func:`refine`
     1924        * :func:`seqrefine`
     1925        * :func:`export`
     1926        * :func:`browse`
     1927
     1928    .. seealso::
     1929        :func:`create`
     1930        :func:`dump`
     1931        :func:`refine`
     1932        :func:`seqrefine`
     1933        :func:`export`
     1934        :func:`browse`
    18021935    '''
    1803     argv = sys.argv
    1804     if len(argv) > 1 and argv[1] in subcommands:
    1805         subcommands[argv[1]](*argv[2:])
    1806     elif len(argv) == 1 or argv[1] in ('help', '--help', '-h'):
    1807         # TODO print usage
    1808         subcommand_names = ' | '.join(sorted(subcommands.keys()))
    1809         print("USAGE: {} [ {} ] ...".format(argv[0], subcommand_names))
    1810     else:
    1811         print("Unknown subcommand: {}".format(argv[1]))
    1812         print("Available subcommands:")
    1813         for name in sorted(subcommands.keys()):
    1814             print("\t{}".format(name))
    1815         sys.exit(-1)
     1936    import argparse
     1937    parser = argparse.ArgumentParser()
     1938    parser.add_argument('subcommand', choices=sorted(subcommands.keys()),
     1939                        help='The subcommand to be executed')
     1940
     1941    result = parser.parse_args(sys.argv[1:2])
     1942    sub = result.subcommand
     1943    subcommands[sub](*sys.argv[2:])
     1944
     1945    # argv = sys.argv
     1946    # if len(argv) > 1 and argv[1] in subcommands:
     1947    #     subcommands[argv[1]](*argv[2:])
     1948    # elif len(argv) == 1 or argv[1] in ('help', '--help', '-h'):
     1949    #     # TODO print usage
     1950    #     subcommand_names = ' | '.join(sorted(subcommands.keys()))
     1951    #     print("USAGE: {} [ {} ] ...".format(argv[0], subcommand_names))
     1952    # else:
     1953    #     print("Unknown subcommand: {}".format(argv[1]))
     1954    #     print("Available subcommands:")
     1955    #     for name in sorted(subcommands.keys()):
     1956    #         print("\t{}".format(name))
     1957    #     sys.exit(-1)
     1958    # sys.exit(0)
     1959
    18161960    # arg = sys.argv
    18171961    # print(arg)
Note: See TracChangeset for help on using the changeset viewer.