Changeset 956


Ignore:
Timestamp:
Jun 18, 2013 9:44:58 PM (10 years ago)
Author:
toby
Message:

snapshot of CIF dev

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIIO.py

    r944 r956  
    3535import GSASIIpwdGUI as G2pdG
    3636import GSASIIElem as G2el
     37import GSASIIstrIO as G2stIO
     38import GSASIImapvars as G2mv
    3739import os
    3840import os.path as ospath
     
    15591561            self.longFormatName = formatName
    15601562        self.OverallParms = {}
    1561         self.GroupedParms = {}
     1563        self.Phases = {}
     1564        self.Histograms = {}
     1565
     1566    def loadParmDict(self):
     1567        '''Load the GSAS-II refinable parameters from the tree into a dict (self.parmDict). Update
     1568        refined values to those from the last cycle and set the uncertainties for the
     1569        refined parameters in another dict (self.sigDict).
     1570
     1571        Expands the parm & sig dicts to include values derived from constraints.
     1572        '''
     1573        self.parmDict = {}
     1574        self.sigDict = {}
     1575        rigidbodyDict = {}
     1576        covDict = {}
     1577        consDict = {}
     1578        Histograms,Phases = self.G2frame.GetUsedHistogramsAndPhasesfromTree()
     1579        if self.G2frame.PatternTree.IsEmpty(): return # nothing to do
     1580        item, cookie = self.G2frame.PatternTree.GetFirstChild(self.G2frame.root)
     1581        while item:
     1582            name = self.G2frame.PatternTree.GetItemText(item)
     1583            if name == 'Rigid bodies':
     1584                 rigidbodyDict = self.G2frame.PatternTree.GetItemPyData(item)
     1585            elif name == 'Covariance':
     1586                 covDict = self.G2frame.PatternTree.GetItemPyData(item)
     1587            elif name == 'Constraints':
     1588                 consDict = self.G2frame.PatternTree.GetItemPyData(item)
     1589            item, cookie = self.G2frame.PatternTree.GetNextChild(self.G2frame.root, cookie)
     1590        rbVary,rbDict =  G2stIO.GetRigidBodyModels(rigidbodyDict,Print=False)
     1591        self.parmDict.update(rbDict)
     1592        rbIds = rigidbodyDict.get('RBIds',{'Vector':[],'Residue':[]})
     1593        Natoms,atomIndx,phaseVary,phaseDict,pawleyLookup,FFtables,BLtables =  G2stIO.GetPhaseData(
     1594            Phases,RestraintDict=None,rbIds=rbIds,Print=False)
     1595        self.parmDict.update(phaseDict)
     1596        hapVary,hapDict,controlDict =  G2stIO.GetHistogramPhaseData(Phases,Histograms,Print=False)
     1597        self.parmDict.update(hapDict)
     1598        histVary,histDict,controlDict =  G2stIO.GetHistogramData(Histograms,Print=False)
     1599        self.parmDict.update(histDict)
     1600        self.parmDict.update(zip(
     1601            covDict.get('varyList',[]),
     1602            covDict.get('variables',[])))
     1603        self.sigDict = dict(zip(
     1604            covDict.get('varyList',[]),
     1605            covDict.get('sig',[])))
     1606        # expand to include constraints: first compile a list of constraints
     1607        constList = []
     1608        for item in consDict:
     1609            constList += consDict[item]
     1610        constDict,fixedList,ignored = G2stIO.ProcessConstraints(constList)
     1611        # now process the constraints
     1612        G2mv.InitVars()
     1613        varyList = covDict.get('varyList',[])
     1614        try:
     1615            groups,parmlist = G2mv.GroupConstraints(constDict)
     1616            G2mv.GenerateConstraints(groups,parmlist,varyList,constDict,fixedList)
     1617        except:
     1618            # this really should not happen
     1619            print ' *** ERROR - constraints are internally inconsistent ***'
     1620            errmsg, warnmsg = G2mv.CheckConstraints(varyList,constDict,fixedList)
     1621            print 'Errors',errmsg
     1622            if warnmsg: print 'Warnings',warnmsg
     1623            raise Exception(' *** CIF creation aborted ***')
     1624        # add the constrained values to the parameter dictionary
     1625        G2mv.Dict2Map(self.parmDict,varyList)
     1626        # and add their uncertainties into the esd dictionary (sigDict)
     1627        if covDict.get('covMatrix') is not None:
     1628            self.sigDict.update(G2mv.ComputeDepESD(covDict['covMatrix'],varyList,self.parmDict))
     1629
    15621630    def loadTree(self):
    1563         '''Load the contents of the data tree into a pair of dicts.
     1631        '''Load the contents of the data tree into a set of dicts
     1632        (self.OverallParms, self.Phases and self.Histogram)
    15641633       
    1565         The childrenless data tree items are overall parameters/controls for the
    1566         entire project and are placed in self.OverallParms
    1567 
    1568         The data tree items with children are either Phase items or are
    1569         data of some sort. Date entries begin with a key, such as
    1570         PWDR, IMG, HKLF,... that identifies the data type.
    1571         * Phase items are placed in self.GroupedParms["Phases"][item]
    1572         * Data items are placed in self.GroupedParms["Phases"][key][item]
    1573 
    1574           Note that there is no overall phase information, only information
    1575           stored for each phase, but there is overall information for each
    1576           data item. The overall data information is stored in
    1577           self.GroupedParms["Phases"][key][None]
    1578        
     1634        * The childrenless data tree items are overall parameters/controls for the
     1635          entire project and are placed in self.OverallParms
     1636        * Phase items are placed in self.Phases
     1637        * Data items are placed in self.Histogram. The key for these data items
     1638          begin with a keyword, such as PWDR, IMG, HKLF,... that identifies the data type.
    15791639        '''
    15801640        self.OverallParms = {}
    1581         self.GroupedParms = {}
    1582         G2frame = self.G2frame
    1583         if G2frame.PatternTree.IsEmpty(): return # nothing to do
    1584         item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
     1641        self.Histograms,self.Phases = self.G2frame.GetUsedHistogramsAndPhasesfromTree()
     1642        if self.G2frame.PatternTree.IsEmpty(): return # nothing to do
     1643        item, cookie = self.G2frame.PatternTree.GetFirstChild(self.G2frame.root)
    15851644        while item:
    1586             name = G2frame.PatternTree.GetItemText(item)
    1587             item2, cookie2 = G2frame.PatternTree.GetFirstChild(item)
    1588             if item2:
    1589                 key = name.split()[0]
    1590                 if name == "Phases":
    1591                     self.GroupedParms[name] = {}
    1592                     d = self.GroupedParms[name]
    1593                 else:
    1594                     if self.GroupedParms.get(key) is None:
    1595                         self.GroupedParms[key] = {}
    1596                     if self.GroupedParms[key].get(name):
    1597                         print("Aborting export: Histogram name repeated"+str(name))
    1598                         return
    1599                     self.GroupedParms[key][name] = {}
    1600                     self.GroupedParms[key][name][None] = G2frame.PatternTree.GetItemPyData(item)
    1601                     d = self.GroupedParms[key][name]
    1602                 while item2:
    1603                     name = G2frame.PatternTree.GetItemText(item2)
    1604                     if d.get(name):
    1605                         print("Aborting export: phase name repeated"+str(name))
    1606                         return
    1607                     d[name] = G2frame.PatternTree.GetItemPyData(item2)
    1608                     item2, cookie2 = G2frame.PatternTree.GetNextChild(item, cookie2)                           
    1609             else:
    1610                 self.OverallParms[name] = G2frame.PatternTree.GetItemPyData(item)
    1611             item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
     1645            name = self.G2frame.PatternTree.GetItemText(item)
     1646            item2, cookie2 = self.G2frame.PatternTree.GetFirstChild(item)
     1647            if not item2:
     1648                self.OverallParms[name] = self.G2frame.PatternTree.GetItemPyData(item)
     1649            item, cookie = self.G2frame.PatternTree.GetNextChild(self.G2frame.root, cookie)
    16121650
    16131651    def dumpTree(self,mode='type'):
     
    16211659        for key in self.OverallParms:
    16221660            print '  ',key,Show(self.OverallParms[key])
    1623         print '\nGrouped'
    1624         for key in self.GroupedParms:
    1625             if key == "Phases":
    1626                 print '  Phases'
    1627                 for key1 in self.GroupedParms[key]:
    1628                     print '    ',key1,Show(self.GroupedParms[key][key1])
    1629             else:
    1630                 print '  ',key,Show(self.GroupedParms[key])
    1631                 for key1 in self.GroupedParms[key]:
    1632                     print '    ',key1,Show(self.GroupedParms[key][key1][None])
    1633                     for key2 in self.GroupedParms[key][key1]:
    1634                         print '      ',key2,Show(self.GroupedParms[key][key1][key2])
    1635 
     1661        print 'Phases'
     1662        for key1 in self.Phases:
     1663            print '    ',key1,Show(self.Phases[key1])
     1664        print 'Histogram'
     1665        for key1 in self.Histograms:
     1666            print '    ',key1,Show(self.Histograms[key1])
     1667            for key2 in self.Histograms[key1]:
     1668                print '      ',key2,Show(self.Histograms[key1][key2])
     1669                   
    16361670######################################################################
    16371671class ImportStructFactor(ImportBaseclass):
  • trunk/GSASIImath.py

    r954 r956  
    4444   
    4545    """
    46     Minimize the sum of squares of a set of equations.
    47 
     46    Minimize the sum of squares of a function (:math:`f`) evaluated on a series of
     47    values (y): :math:`\sum_{y=0}^{N_{obs}} f(y,{args})`
     48   
    4849    ::
    4950   
     
    151152def getVCov(varyNames,varyList,covMatrix):
    152153    '''obtain variance-covariance terms for a set of variables. NB: the varyList
    153     and covMatrix were saved by the last least squares refineemnt so they must match
     154    and covMatrix were saved by the last least squares refinement so they must match.
    154155   
    155156    :param list varyNames: variable names to find v-cov matric for
     
    12771278        if abs(value) > 1:
    12781279            valoff = int(math.log10(abs(value)))
     1280        elif abs(value) > 0:
     1281            valoff = int(math.log10(abs(value))-0.9999999)
    12791282        else:
    1280             valoff = int(math.log10(abs(value))-0.9999999)
     1283            valoff = 0
    12811284    if esd != 0:
    12821285        out = ("{:."+str(valoff+esdoff)+"f}").format(value/10**valoff) # format the value
     
    20012004from numpy import random
    20022005
    2003 __all__ = ['anneal']
     2006#__all__ = ['anneal']
    20042007
    20052008_double_min = numpy.finfo(float).min
  • trunk/GSASIIobj.py

    r948 r956  
    159159                             combination for each element in phase 
    160160  \         Name             phase name (str)
    161   \         SGData           Space group details,
    162                              as defined in :mod:`GSASIIspc` as  :ref:`SGData definition <SGData_table>`
     161  \         SGData           Space group details as a :ref:`space group (SGData) object <SGData_table>`
     162                             as defined in :func:`GSASIIspc.SpcGroup`.
    163163  \         Pawley neg wt    Restraint value for negative Pawley intensities
    164164                             (float)
     
    181181                             interatomic angles (list of floats)
    182182ranId           \            unique random number Id for phase (int)
    183 pId             \            ? (int)
     183pId             \            Phase Id number for current project (int).
    184184Atoms           \            Atoms in phase as a list of lists. The outer list
    185185                             is for each atom, the inner list contains 18
  • trunk/GSASIIspc.py

    r946 r956  
    199199    SGText.append(line)       
    200200    return SGText
     201
     202def AllOps(SGData):
     203    '''
     204    Returns a list of all operators for a space group, including those for centering and a center of symmetry
     205   
     206    :param SGData: from :func:`SpcGroup`
     207    :returns: list of strings of formatted symmetry operators
     208    '''
     209    SGText = []
     210    onebar = (1,)
     211    if SGData['SGInv']:
     212        onebar += (-1,)
     213    for cen in SGData['SGCen']:
     214        for mult in onebar:
     215            for M,T in SGData['SGOps']:
     216                OPtxt = MT2text(mult*M,(mult*T)+cen)
     217                SGText.append(OPtxt.replace(' ',''))
     218    return SGText
     219
    201220   
    202221def MT2text(M,T):
  • trunk/GSASIIstrMain.py

    r955 r956  
    9393    except:
    9494        print ' *** ERROR - your constraints are internally inconsistent ***'
    95         errmsg, warnmsg = G2stIO.CheckConstraints(varyList,constrDict,fixedList)
     95        errmsg, warnmsg = G2mv.CheckConstraints(varyList,constrDict,fixedList)
    9696        print 'Errors',errmsg
    9797        if warnmsg: print 'Warnings',warnmsg
  • trunk/exports/G2cif.py

    r946 r956  
    66import os.path
    77import GSASIIIO as G2IO
     8reload(G2IO)
    89import GSASIIgrid as G2gd
    9 #reload(G2gd)
     10import GSASIIstrIO as G2stIO
     11#import GSASIImapvars as G2mv
     12import GSASIImath as G2mth
     13import GSASIIlattice as G2lat
     14import GSASIIspc as G2spg
     15
     16def getCallerDocString(): # for development
     17    "Return the calling function's doc string"
     18    import inspect as ins
     19    for item in ins.stack()[1][0].f_code.co_consts:
     20        if type(item) is str:
     21            return item
     22    else:
     23        return '?'
     24
    1025class ExportCIF(G2IO.ExportBaseclass):
    1126    def __init__(self,G2frame):
     
    5974            #WriteCIFitem('_refine_ls_shift/su_mean',DAT2)
    6075            WriteCIFitem('_computing_structure_refinement','GSAS-II')
    61             #WriteCIFitem('_refine_ls_number_parameters',DAT1)
    62             #WriteCIFitem('_refine_ls_goodness_of_fit_all',DAT2)
     76            try:
     77                vars = str(len(self.OverallParms['Covariance']['varyList']))
     78            except:
     79                vars = '?'
     80            WriteCIFitem('_refine_ls_number_parameters',vars)
     81            try:
     82                GOF = str(self.OverallParms['Covariance']['Rvals']['GOF'])
     83            except:
     84                GOF = '?'
     85            WriteCIFitem('_refine_ls_goodness_of_fit_all',GOF)
    6386            #WriteCIFitem('_refine_ls_number_restraints',TEXT(1:7))
    6487            # other things to consider reporting
     
    7497            # include an overall profile r-factor, if there is more than one powder histogram
    7598            if self.npowder > 1:
    76                 WriteCIFitem('\n# OVERALL POWDER R-FACTORS')
    77                 #WriteCIFitem('_pd_proc_ls_prof_R_factor',TEXT(11:20))
    78                 #WriteCIFitem('_pd_proc_ls_prof_wR_factor',TEXT(1:10))
     99                WriteCIFitem('\n# OVERALL POWDER R-FACTOR')
     100                try:
     101                    R = str(self.OverallParms['Covariance']['Rvals']['Rwp'])
     102                except:
     103                    R = '?'
     104                WriteCIFitem('_pd_proc_ls_prof_wR_factor',R)
     105                #WriteCIFitem('_pd_proc_ls_prof_R_factor',TEXT(11:20)) # who cares!
    79106            WriteCIFitem('_refine_ls_matrix_type','full')
    80107            #WriteCIFitem('_refine_ls_matrix_type','userblocks')
     
    84111            version for this project. Store this in the GPX file?
    85112            '''
    86             print "TODO: publication info goes here"
     113            print getCallerDocString()
    87114
    88115        def WritePhaseTemplate():
     
    90117            version for this project
    91118            '''
    92             print "TODO: phase template info goes here"
     119            print getCallerDocString()
    93120
    94121        def WritePowderTemplate():
     
    96123            version for this project
    97124            '''
    98             print "TODO: powder histogram template info goes here"
     125            print getCallerDocString()
    99126
    100127        def WriteSnglXtalTemplate():
     
    102129            for this project
    103130            '''
    104             print "TODO: single-crystal histogram template info goes here"
    105 
     131            print getCallerDocString()
     132
     133        def FormatSH(phasedict):
     134            'Format a full spherical harmonics texture description as a string'
     135            # SH Texture
     136            pfx = str(phasedict['pId'])+'::'
     137            s = ""
     138            textureData = phasedict['General']['SH Texture']   
     139            if textureData.get('Order'):
     140                s += "Spherical Harmonics correction. Order = "+str(textureData['Order'])
     141                s += " Model: " + str(textureData['Model']) + "\n    Orientation angles: "
     142                for name in ['omega','chi','phi']:
     143                    aname = pfx+'SH '+name
     144                    s += name + " = "
     145                    sig = self.sigDict.get(aname,-0.09)
     146                    s += G2mth.ValEsd(self.parmDict[aname],sig)
     147                    s += "; "
     148                s += "\n"
     149                s1 = "    Coefficients:  "
     150                for name in textureData['SH Coeff'][1]:
     151                    aname = pfx+name
     152                    if len(s1) > 60:
     153                        s += s1 + "\n"
     154                        s1 = "    "
     155                    s1 += aname + ' = '
     156                    sig = self.sigDict.get(aname,-0.0009)
     157                    s1 += G2mth.ValEsd(self.parmDict[aname],sig)
     158                    s1 += "; "
     159                s += s1
     160            return s
     161
     162        def FormatHAPpo(phasedict):
     163            'return the March-Dollase/SH correction for every histogram in the current phase'
     164            s = ''
     165            for histogram in sorted(phasedict['Histograms']):
     166                Histogram = self.Histograms.get(histogram)
     167                if not Histogram: continue
     168                hapData = phasedict['Histograms'][histogram]
     169                if hapData['Pref.Ori.'][0] == 'MD':
     170                    aname = str(phasedict['pId'])+':'+str(Histogram['hId'])+':MD'
     171                    if self.parmDict.get(aname,1.0) != 1.0: continue
     172                    sig = self.sigDict.get(aname,-0.009)
     173                    if s != "": s += '\n'
     174                    s += 'March-Dollase correction'
     175                    if self.npowder > 1:
     176                        s += ', histogram '+str(Histogram['hId']+1)
     177                    s += ' coef. = ' + G2mth.ValEsd(self.parmDict[aname],sig)
     178                    s += ' axis = ' + str(hapData['Pref.Ori.'][3])
     179                else: # must be SH
     180                    if s != "": s += '\n'
     181                    s += 'Simple spherical harmonic correction'
     182                    if self.npowder > 1:
     183                        s += ', histogram '+str(Histogram['hId']+1)
     184                    s += ' Order = '+str(hapData['Pref.Ori.'][4])+'\n'
     185                    s1 = "    Coefficients:  "
     186                    for item in hapData['Pref.Ori.'][5]:
     187                        print item
     188                        aname = str(phasedict['pId'])+':'+str(Histogram['hId'])+':'+item
     189                        print aname
     190                        if len(s1) > 60:
     191                            s += s1 + "\n"
     192                            s1 = "    "
     193                        s1 += aname + ' = '
     194                        sig = self.sigDict.get(aname,-0.0009)
     195                        s1 += G2mth.ValEsd(self.parmDict[aname],sig)
     196                        s1 += "; "
     197                    s += s1
     198            return s
     199       
     200        def FmtAtomType(sym):
     201            'Reformat a GSAS-II atom type symbol to match CIF rules'
     202            sym = sym.replace('_','') # underscores are not allowed: no isotope designation?
     203            # in CIF oxidation state symbols come after, not before
     204            if '+' in sym:
     205                sym = sym.replace('+','') + '+'
     206            elif '-' in sym:
     207                sym = sym.replace('-','') + '-'
     208            return sym
     209           
     210        def PutInCol(val,wid):
     211            '''Pad a value to >=wid+1 columns by adding spaces at the end. Always
     212            adds at least one space
     213            '''
     214            val = str(val).replace(' ','')
     215            if not val: val = '?'
     216            fmt = '{:' + str(wid) + '} '
     217            return fmt.format(val)
     218
     219        def MakeUniqueLabel(lbl,labellist):
     220            'Make sure that every atom label is unique'
     221            lbl = lbl.strip()
     222            if not lbl: # deal with a blank label
     223                lbl = 'A_1'
     224            if lbl not in labellist:
     225                labellist.append(lbl)
     226                return lbl
     227            i = 1
     228            prefix = lbl
     229            if '_' in lbl:
     230                prefix = lbl[:lbl.rfind('_')]
     231                suffix = lbl[lbl.rfind('_')+1:]
     232                try:
     233                    i = int(suffix)+1
     234                except:
     235                    pass
     236            while prefix+'_'+str(i) in labellist:
     237                i += 1
     238            else:
     239                lbl = prefix+'_'+str(i)
     240                labellist.append(lbl)
     241
     242        def WriteAtomsNuclear(phasenam):
     243            phasedict = self.Phases[phasenam] # pointer to current phase info           
     244            General = phasedict['General']
     245            WriteCIFitem('\n# ATOMIC COORDINATES AND DISPLACEMENT PARAMETERS')
     246            Atoms = phasedict['Atoms']
     247            WriteCIFitem('loop_ '+
     248                         '\n\t_atom_site_label'+
     249                         '\n\t_atom_site_type_symbol'+
     250                         '\n\t_atom_site_fract_x'+
     251                         '\n\t_atom_site_fract_y'+
     252                         '\n\t_atom_site_fract_z'+
     253                         '\n\t_atom_site_occupancy'+
     254                         '\n\t_atom_site_adp_type'+
     255                         '\n\t_atom_site_U_iso_or_equiv'+
     256                         '\n\t_atom_site_symmetry_multiplicity')
     257
     258            varnames = {3:'Ax',4:'Ay',5:'Az',6:'Afrac',
     259                        10:'AUiso',11:'AU11',12:'AU22',13:'AU33',
     260                        14:'AU12',15:'AU13',16:'AU23'}
     261            labellist = []
     262           
     263            pfx = str(phasedict['pId'])+'::'
     264            for i,at in enumerate(Atoms):
     265                print at
     266            for i,at in enumerate(Atoms):
     267                s = " "
     268                s += PutInCol(MakeUniqueLabel(at[0],labellist),6) # label
     269                #s += PutInCol(MakeUniqueLabel('A',labellist),6) # label
     270                s += PutInCol(FmtAtomType(at[1]),6) # type
     271                if at[9] == 'I':
     272                    adp = 'Uiso '
     273                else:
     274                    adp = 'Uani '
     275                    t = 0.0
     276                    for j in (11,12,13):
     277                        var = pfx+varnames[j]+":"+str(i)
     278                        t += self.parmDict.get(var,at[j])
     279                for j in (3,4,5,6,10):
     280                    if j in (3,4,5):
     281                        dig = 11
     282                        sigdig = -0.00009
     283                    else:
     284                        dig = 9
     285                        sigdig = -0.009
     286                    var = pfx+varnames[j]+":"+str(i)
     287                    dvar = pfx+"d"+varnames[j]+":"+str(i)
     288                    if dvar not in self.sigDict:
     289                        dvar = var
     290                    if j == 10 and adp == 'Uani ':
     291                        # compute Uequiv crudely
     292                        t = 0.0
     293                        for k in (11,12,13):
     294                            var = pfx+varnames[j]+":"+str(i)
     295                            t += self.parmDict.get(var,at[k])
     296                        val = t/3.
     297                        sig = sigdig
     298                    else:
     299                        val = self.parmDict.get(var,at[j])
     300                        sig = self.sigDict.get(dvar,sigdig)
     301                    s += PutInCol(G2mth.ValEsd(val,sig),dig)
     302                s += adp
     303                print s
     304       
    106305        def WritePhaseInfo(phasenam):
    107306            # see writepha.for
    108307            print 'TODO: phase info for',phasenam,'goes here'
    109308            # THINK: how to select publication flags for distances/angles?
    110             phasedict = self.GroupedParms['Phases'][phasenam] # pointer to current phase info           
     309            phasedict = self.Phases[phasenam] # pointer to current phase info           
    111310            WriteCIFitem('_pd_phase_name', phasenam)
    112             text = '?'
    113             for lbl in 'a','b','c':
    114                 WriteCIFitem('_cell_length_'+lbl,text)
    115             for lbl in 'alpha','beta ','gamma':
    116                 WriteCIFitem('_cell_angle_'+lbl,text)
    117 
    118             WriteCIFitem('_cell_volume',text)
    119 
    120             #print phasedict['Histograms']
    121 #            for key in phasedict['General']:
    122 #                print key,'=',phasedict['General'][key]
    123 #            print phasedict['pId']
    124 
    125             #NSYS = (1,2,3,4,4,5,5,5,5,5,6,6,7,7)
    126             #SYST = ('','triclinic','monoclinic','orthorhombic','tetragonal','trigonal ','hexagonal','cubic')
    127 
     311            # replace some of these later
     312            #General = phasedict['General']
     313            #SGData = phasedict['General']['SGData']
     314            #cell = General['Cell']
     315            pfx = str(phasedict['pId'])+'::'
     316            #covData = self.OverallParms['Covariance']
     317            A,sigA = G2stIO.cellFill(pfx,phasedict['General']['SGData'],self.parmDict,self.sigDict)
     318            cellSig = G2stIO.getCellEsd(pfx,
     319                                       phasedict['General']['SGData'],A,
     320                                       self.OverallParms['Covariance'])  # returns 7 vals, includes sigVol
     321            cellList = G2lat.A2cell(A) + (G2lat.calc_V(A),)
     322            defsigL = 3*[-0.00001] + 3*[-0.001] + [-0.01] # significance to use when no sigma
     323            names = ['length_a','length_b','length_c',
     324                     'angle_alpha','angle_beta ','angle_gamma',
     325                     'volume']
     326            prevsig = 0
     327            for lbl,defsig,val,sig in zip(names,defsigL,cellList,cellSig):
     328                if sig:
     329                    txt = G2mth.ValEsd(val,sig)
     330                    prevsig = -sig # use this as the significance for next value
     331                else:
     332                    txt = G2mth.ValEsd(val,min(defsig,prevsig),True)
     333                WriteCIFitem('_cell_'+lbl,txt)
     334                   
    128335            WriteCIFitem('_symmetry_cell_setting',
    129336                         phasedict['General']['SGData']['SGSys'])
     
    133340            spacegroup = spacegroup[0].upper() + spacegroup[1:].lower().rstrip('rh ')
    134341            WriteCIFitem('_symmetry_space_group_name_H-M',spacegroup)
     342
    135343            # generate symmetry operations including centering and center of symmetry
    136344            WriteCIFitem('loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz')
     345            for i,op in enumerate(G2spg.AllOps(phasedict['General']['SGData']),start=1):
     346                WriteCIFitem('   {:3d}  {:}'.format(i,op.lower()))
     347
     348            # preferred orientation (always reported by phase)
     349            SH = FormatSH(phasedict)
     350            MD = FormatHAPpo(phasedict)
     351            if SH and MD:
     352                WriteCIFitem('_pd_proc_ls_pref_orient_corr', SH + '\n' + MD)
     353            elif SH or MD:
     354                WriteCIFitem('_pd_proc_ls_pref_orient_corr', SH + MD)
     355            else:
     356                WriteCIFitem('_pd_proc_ls_pref_orient_corr', 'none')
    137357
    138358            # loop over histogram(s) used in this phase
    139             if not oneblock:
     359            if oneblock:
     360                # report all profile information here (include histogram & phase)
     361                # _pd_proc_ls_profile_function
     362                pass
     363            else:
    140364                # pointers to histograms used in this phase
    141365                histlist = []
    142                 for hist in self.GroupedParms['Phases'][phasenam]['Histograms']:
    143                     if self.GroupedParms['Phases'][phasenam]['Histograms'][hist]['Use']:
     366                for hist in self.Phases[phasenam]['Histograms']:
     367                    if self.Phases[phasenam]['Histograms'][hist]['Use']:
    144368                        if phasebyhistDict.get(hist):
    145369                            phasebyhistDict[hist].append(phasenam)
     
    158382                else:
    159383                    WriteCIFitem('loop_  _pd_block_diffractogram_id')
    160                     for hist in histlist:
    161                         WriteCIFitem('',hist)
    162                         # TODO: sample/histogram profile information and other "HAP" info should be
    163                         # reported in this loop, such as
    164                         # _pd_proc_ls_pref_orient_corr
    165                         # _pd_proc_ls_profile_function
    166                         #txt = ' Spherical Harmonic ODF' + '\n spherical harmonic order='+'?'
    167                         #IF ( ISAMSYM.EQ.1 ) THEN
    168                         #txt += '\n No sample symmetry'
    169                 #ELSE IF ( ISAMSYM.EQ.2 ) THEN
    170                 #txt += ' The sample symmetry is: 2/m (shear texture)'
    171                 #ELSE IF ( ISAMSYM.EQ.3 ) THEN
    172                 #txt += ' The sample symmetry is: mmm (rolling texture)'
    173                 #ELSE IF ( ISAMSYM.EQ.0 ) THEN
    174                 #txt += ' The sample symmetry is: cylindrical (fiber texture)'
    175                 #WriteCIFitem('_pd_proc_ls_pref_orient_corr',txt)
     384
     385                # report sample profile information here (phase only)
     386                # _pd_proc_ls_profile_function
     387           
     388            if phasedict['General']['Type'] == 'nuclear':        #this needs macromolecular variant, etc!
     389                WriteAtomsNuclear(phasenam)
    176390            else:
    177                 # report all profile information here (include instrumental)
    178                 # _pd_proc_ls_pref_orient_corr
    179                 # _pd_proc_ls_profile_function
    180                 pass
    181            
    182             WriteCIFitem('\n# ATOMIC COORDINATES AND DISPLACEMENT PARAMETERS')
     391                raise Exception,"no export for mm coordinates implemented"
    183392     
    184             WriteCIFitem('loop_ '+
    185                          '\n\t_atom_site_type_symbol'+
    186                          '\n\t_atom_site_label'+
    187                          '\n\t_atom_site_fract_x'+
    188                          '\n\t_atom_site_fract_y'+
    189                          '\n\t_atom_site_fract_z'+
    190                          '\n\t_atom_site_occupancy'+
    191                          '\n\t_atom_site_thermal_displace_type'+
    192                          '\n\t_atom_site_U_iso_or_equiv'+
    193                          '\n\t_atom_site_symmetry_multiplicity')
     393
     394            raise Exception,'Testing'
    194395
    195396            WriteCIFitem('loop_' + '\n\t_atom_site_aniso_label' +
     
    235436        def WritePowderData(histlbl):
    236437            text = '?'
    237             histblk = self.GroupedParms['PWDR'][histlbl]
     438            histblk = self.Histograms[histlbl]
    238439            print 'TODO: powder here data for',histblk["Sample Parameters"]['InstrName']
    239440            # see wrpowdhist.for & wrreflist.for
     
    364565                         
    365566        def WriteSingleXtalData(histlbl):
    366             histblk = self.GroupedParms['HKLF'][histlbl]
     567            histblk = self.Histograms[histlbl]
    367568            print 'TODO: single xtal here data for',histblk["Instrument Parameters"][0]['InstrName']
    368569            # see wrreflist.for
     
    393594        #============================================================
    394595        # the export process starts here
     596        # create a dict with refined values and their uncertainties
     597        self.loadParmDict()
     598        # also load all of the tree into a set of dicts
    395599        self.loadTree()
    396         # ====== move this later ==================================================
    397         #for key in self.OverallParms['Covariance']:
    398         #    print key
    399         #    print type(self.OverallParms['Covariance'][key])
    400         sigDict = dict(zip(
    401             self.OverallParms['Covariance']['varyList'],
    402             self.OverallParms['Covariance']['sig'])
    403                        )
     600        #self.dumpTree()
     601
    404602        # get restraint info
    405603        #restraintDict = self.OverallParms.get('Restraints',{})
    406         for i in  self.OverallParms['Constraints']:
    407             print i
    408             for j in self.OverallParms['Constraints'][i]:
    409                 print j
    410         return
    411         parmDict = {}
    412         #G2mv.InitVars()
    413         # do constraint processing
    414         #try:
    415         #    groups,parmlist = G2mv.GroupConstraints(constrDict)
    416         #    G2mv.GenerateConstraints(groups,parmlist,varyList,constrDict,fixedList)
    417         #except:
    418         #    import GSASIIstrIO as G2stIO
    419         #    print ' *** ERROR - your constraints are internally inconsistent ***'
    420         #    errmsg, warnmsg = G2stIO.CheckConstraints(varyList,constrDict,fixedList)
    421         #    print 'Errors',errmsg
    422         #    if warnmsg: print 'Warnings',warnmsg
    423         #    raise Exception(' *** CIF creation aborted ***')
    424        
    425         # add the uncertainties into the esd dictionary (sigDict)
    426         #sigDict.update(G2mv.ComputeDepESD(
    427         #    self.OverallParms['Covariance']['covMatrix'],
    428         #    self.OverallParms['Covariance']['varyList'],
    429         #    parmDict))
    430 
    431         return
     604        #for i in  self.OverallParms['Constraints']:
     605        #    print i
     606        #    for j in self.OverallParms['Constraints'][i]:
     607        #        print j
     608        #return
    432609
    433610        self.CIFdate = dt.datetime.strftime(dt.datetime.now(),"%Y-%m-%dT%H:%M")
    434611        # count phases, powder and single crystal histograms
    435         self.nphase = len(self.GroupedParms.get("Phases",[]))
    436         self.npowder = len(self.GroupedParms.get("PWDR",[]))
    437         self.nsingle = len(self.GroupedParms.get("HKLF",[]))
     612        self.nphase = len(self.Phases)
     613        self.npowder = 0
     614        self.nsingle = 0
     615        for hist in self.Histograms:
     616            if hist.startswith("PWDR"):
     617                self.npowder += 1
     618            elif hist.startswith("HKLF"):
     619                self.nsingle += 1
    438620        # is there anything to export?
    439621        if self.nphase + self.npowder + self.nsingle == 0:
     
    464646                return
    465647            elif self.nphase > 1: # quick mode: choose one phase
    466                 choices = sorted(self.GroupedParms['Phases'].keys())
     648                choices = sorted(self.Phases.keys())
    467649                phasenum = G2gd.ItemSelector(choices,self.G2frame)
    468650                if phasenum is None: return
     
    500682            invalid = 0
    501683            key3 = 'InstrName'
    502             for key in self.GroupedParms:
    503                 if key == 'Phases': continue
    504                 for key1 in self.GroupedParms[key]:
    505                     if key == "PWDR":
    506                         key2 = "Sample Parameters"
    507                         d = self.GroupedParms[key][key1][key2]
    508                     elif key == "HKLF":
    509                         key2 = "Instrument Parameters"
    510                         d = self.GroupedParms[key][key1][key2][0]
    511                     else:
    512                         raise Exception,"Unexpected histogram type for CIF: "+str(key)
    513                        
    514                     lbllist.append(key1)
    515                     dictlist.append(d)
    516                     keylist.append(key3)
    517                     instrname = d.get(key3)
    518                     if instrname is None:
    519                         d[key3] = ''
    520                         invalid += 1
    521                     elif instrname.strip() == '':
    522                         invalid += 1
     684            for hist in self.Histograms:
     685                if hist.startswith("PWDR"):
     686                    key2 = "Sample Parameters"
     687                    d = self.Histograms[hist][key2]
     688                elif hist.startswith("HKLF"):
     689                    key2 = "Instrument Parameters"
     690                    d = self.Histograms[hist][key2][0]
     691                   
     692                lbllist.append(hist)
     693                dictlist.append(d)
     694                keylist.append(key3)
     695                instrname = d.get(key3)
     696                if instrname is None:
     697                    d[key3] = ''
     698                    invalid += 1
     699                elif instrname.strip() == '':
     700                    invalid += 1
    523701            if invalid:
    524702                msg = ""
    525                 if invalid > 1: msg = (
     703                if invalid > 3: msg = (
    526704                    "\n\nNote: it may be faster to set the name for\n"
    527705                    "one histogram for each instrument and use the\n"
     
    540718        #======================================================================
    541719        if oneblock:
     720            WriteCIFitem('data_'+self.CIFname)
    542721            if phasenam is None: # if not already selected, select the first phase (should be one)
    543                 phasenam = self.GroupedParms['Phases'].keys()[0]
     722                phasenam = self.Phases.keys()[0]
    544723            #print 'phasenam',phasenam
    545             phaseblk = self.GroupedParms['Phases'][phasenam] # pointer to current phase info
    546             # select data, should only be one set, but take whatever comes 1st
     724            phaseblk = self.Phases[phasenam] # pointer to current phase info
    547725            if not self.quickmode:
    548                 for key in self.GroupedParms:
    549                     if key == 'Phases': continue
    550                     for key1 in self.GroupedParms[key]:
    551                         histblk = self.GroupedParms[key][key1]
    552                         histkey = key1
    553                         histtyp = key
    554                         if key == "PWDR":
    555                             instnam = histblk["Sample Parameters"]['InstrName']
    556                         elif key == "HKLF":
    557                             instnam = histblk["Instrument Parameters"][0]['InstrName']
    558                         break
    559                     break
     726                # select data, should only be one set in oneblock, but take whatever comes 1st
     727                for hist in self.Histograms:
     728                    histblk = self.Histograms[hist]
     729                    if hist.startswith("PWDR"):
     730                        instnam = histblk["Sample Parameters"]['InstrName']
     731                        break # ignore all but 1st data histogram
     732                    elif hist.startswith("HKLF"):
     733                        instnam = histblk["Instrument Parameters"][0]['InstrName']
     734                        break # ignore all but 1st data histogram
    560735                instnam = instnam.replace(' ','')
    561             WriteCIFitem('data_'+self.CIFname)
    562             if not self.quickmode: # publication information
    563736                WriteCIFitem('_pd_block_id',
    564737                             str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
     
    567740                WritePubTemplate()
    568741                WriteOverall()
    569             # report the phase
     742            # report the phase info
    570743            WritePhaseTemplate()
    571744            WritePhaseInfo(phasenam)
    572745            if not self.quickmode:
    573                 if histtyp == "PWDR":
     746                if hist.startswith("PWDR"):
    574747                    WritePowderTemplate()
    575                     WritePowderData(histkey)
    576                 else:
     748                    WritePowderData(hist)
     749                elif hist.startswith("HKLF"):
    577750                    WriteSnglXtalTemplate()
    578                     WriteSingleXtalData(histkey)
     751                    WriteSingleXtalData(hist)
    579752        else:
    580753        #======================================================================
     
    601774                loopprefix = '_pd_phase_block_id'
    602775           
    603             for i,phasenam in enumerate(sorted(self.GroupedParms['Phases'].keys())):
     776            for phasenam in sorted(self.Phases.keys()):
     777                i = self.Phases[phasenam]['pId']
    604778                datablockidDict[phasenam] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
    605                              'phase_'+ str(i+1) + '|' + str(self.shortauthorname))
     779                             'phase_'+ str(i) + '|' + str(self.shortauthorname))
    606780                WriteCIFitem(loopprefix,datablockidDict[phasenam])
    607781            # loop over data blocks
    608             i = 0
    609782            if self.npowder + self.nsingle > 1:
    610783                loopprefix = ''
     
    612785            else:
    613786                loopprefix = '_pd_block_diffractogram_id'
    614             for key in self.GroupedParms:
    615                 if key == 'Phases': continue
    616                 for key1 in self.GroupedParms[key]:
    617                     i += 1
    618                     histblk = self.GroupedParms[key][key1]
    619                     if key == "PWDR":
    620                         instnam = histblk["Sample Parameters"]['InstrName']
    621                     elif key == "HKLF":
    622                         instnam = histblk["Instrument Parameters"][0]['InstrName']
    623                     instnam = instnam.replace(' ','')
    624                     if datablockidDict.get(key1):
    625                         print "Error: histogram name is duplicated: ",key1
    626                         return
    627                     datablockidDict[key1] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
    628                                              str(self.shortauthorname) + "|" +
    629                                              instnam + "_hist_"+str(i))
    630                     WriteCIFitem(loopprefix,datablockidDict[key1])
     787            for hist in self.Histograms:
     788                histblk = self.Histograms[hist]
     789                if hist.startswith("PWDR"):
     790                    instnam = histblk["Sample Parameters"]['InstrName']
     791                elif hist.startswith("HKLF"):
     792                    instnam = histblk["Instrument Parameters"][0]['InstrName']
     793                instnam = instnam.replace(' ','')
     794                i = histblk['hId']
     795                datablockidDict[hist] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
     796                                         str(self.shortauthorname) + "|" +
     797                                         instnam + "_hist_"+str(i))
     798                WriteCIFitem(loopprefix,datablockidDict[hist])
    631799            #============================================================
    632800            # loop over phases, exporting them
    633801            phasebyhistDict = {} # create a cross-reference to phases by histogram
    634             for j,phasenam in enumerate(sorted(self.GroupedParms['Phases'].keys())):
    635                 i = j + 1
     802            for j,phasenam in enumerate(sorted(self.Phases.keys())):
     803                i = self.Phases[phasenam]['pId']
    636804                WriteCIFitem('\ndata_'+self.CIFname+"_phase_"+str(i))
    637805                print "debug, processing ",phasenam
     
    644812            #============================================================
    645813            # loop over histograms, exporting them
    646             i = 0
    647             for key in self.GroupedParms:
    648                 if key == 'Phases': continue
    649                 for key1 in self.GroupedParms[key]:
    650                     i += 1
    651                     histblk = self.GroupedParms[key][key1]
    652                     if key == "PWDR":
    653                         WriteCIFitem('\ndata_'+self.CIFname+"_pwd_"+str(i))
    654                     elif key == "HKLF":
    655                         WriteCIFitem('\ndata_'+self.CIFname+"_sx_"+str(i))
     814            for hist in self.Histograms:
     815                histblk = self.Histograms[hist]
     816                i = histblk['hId']
     817                if hist.startswith("PWDR"):
     818                    WriteCIFitem('\ndata_'+self.CIFname+"_pwd_"+str(i))
     819                    #instnam = histblk["Sample Parameters"]['InstrName']
    656820                    WriteCIFitem('# Information for histogram '+str(i)+': '+
    657                                  key1)
    658                     WriteCIFitem('_pd_block_id',datablockidDict[key1])
    659                     if key == "PWDR":
    660                         WritePowderTemplate()
    661                         WritePowderData(key1)
    662                     else:
    663                         WriteSnglXtalTemplate()
    664                         WriteSingleXtalData(key1)
     821                                 hist)
     822                    WriteCIFitem('_pd_block_id',datablockidDict[hist])
     823                    WritePowderTemplate()
     824                    WritePowderData(key1)
     825                elif hist.startswith("HKLF"):
     826                    WriteCIFitem('\ndata_'+self.CIFname+"_sx_"+str(i))
     827                    #instnam = histblk["Instrument Parameters"][0]['InstrName']
     828                    WriteCIFitem('# Information for histogram '+str(i)+': '+
     829                                 hist)
     830                    WriteCIFitem('_pd_block_id',datablockidDict[hist])
     831                    WriteSnglXtalTemplate()
     832                    WriteSingleXtalData(key1)
    665833
    666834        # TODO: how to report _pd_proc_ls_peak_cutoff?
Note: See TracChangeset for help on using the changeset viewer.