Ignore:
Timestamp:
Nov 21, 2020 2:15:49 PM (12 months ago)
Author:
toby
Message:

extensive Origin 1->2 updates; merge SetupGeneral? into a single routine in G2Elem; read sym ops from CIF; fix sites sym/mult after cood xform

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIctrlGUI.py

    r4654 r4659  
    169169import GSASIIobj as G2obj
    170170import GSASIIfiles as G2fil
     171import GSASIIElem as G2elem
    171172import GSASIIscriptable as G2sc
    172173import GSASIIpwd as G2pwd
    173174import GSASIIlattice as G2lat
     175import GSASIImath as G2mth
     176import GSASIIstrMain as G2stMn
    174177if sys.version_info[0] >= 3:
    175178    unicode = str
     
    70097012    AutoLoadWindow = dlg # save window reference
    70107013
     7014################################################################################
     7015# Deal with Origin 1/2 ambiguities
     7016################################################################################
     7017def ChooseOrigin(G2frame,rd):   
     7018    # make copy of Phase but shift atoms Origin 1->2
     7019    O2Phase = copy.deepcopy(rd.Phase)
     7020    # make copy of atoms, shift to alternate origin
     7021    T = G2spc.spg2origins[rd.Phase['General']['SGData']['SpGrp']]
     7022    O2atoms = O2Phase['Atoms']
     7023    cx,ct,cs,cia = rd.Phase['General']['AtomPtrs']
     7024    SGData = rd.Phase['General']['SGData']
     7025    for atom in O2atoms:
     7026        for i in [0,1,2]:
     7027            atom[cx+i] += T[i]
     7028            atom[cs:cs+2] = G2spc.SytSym(atom[3:6],SGData)[0:2] # update symmetry & mult
     7029    #get density & distances
     7030    DisAglData = {}
     7031    DisAglData['SGData'] = rd.Phase['General']['SGData']
     7032    DisAglData['Cell'] = rd.Phase['General']['Cell'][1:] #+ volume
     7033    DisAglCtls = {'Factors': [0.85, 0],
     7034                 'BondRadii': [], 'AngleRadii': [], 'AtomTypes': []}
     7035    for atom in rd.Phase['Atoms']:
     7036        DisAglCtls['BondRadii'].append(1.5)
     7037        DisAglCtls['AngleRadii'].append(0)
     7038        DisAglCtls['AtomTypes'].append(atom[ct])
     7039    txt = ''
     7040    for i,phObj in enumerate([rd.Phase,O2Phase]):
     7041        if i:
     7042            txt += "\n\nWith origin shift applied\n"
     7043        else:
     7044            txt += "\nWith original origin\n"
     7045        cellContents = {}
     7046        for atom in phObj['Atoms']:
     7047            if atom[ct] in cellContents:
     7048                cellContents[atom[ct]] += atom[cs+1]
     7049            else:
     7050                cellContents[atom[ct]] = atom[cs+1]
     7051        txt += '   Unit cell Contents: '
     7052        for i,k in enumerate(cellContents):
     7053            if i: txt += ', '
     7054            txt += '{}*{}'.format(cellContents[k],k)
     7055        G2elem.SetupGeneral(phObj,G2frame.dirname)
     7056        den,_ = G2mth.getDensity(phObj['General'])
     7057        txt += "\n   Density {:.2f} g/cc\n".format(den)
     7058                   
     7059        DisAglData['OrigAtoms'] = DisAglData['TargAtoms'] = [
     7060                        [i,]+atom[ct-1:ct+1]+atom[cx:cx+3] for
     7061                        i,atom in enumerate(phObj['Atoms'])]
     7062        lbl,dis,angle = G2stMn.RetDistAngle(DisAglCtls,DisAglData)
     7063        # get unique distances
     7064        minDis = {}
     7065        for i in dis:
     7066            for j,o,s,d,e in dis[i]:
     7067                key = '-'.join(sorted([lbl[i],lbl[j]]))
     7068                if key not in minDis:
     7069                    minDis[key] = d
     7070                elif d < minDis[key]:
     7071                    minDis[key] = d
     7072        thirdShortest = sorted([minDis[k] for k in minDis])[:3][-1]
     7073        shortTxt = ''
     7074        for k in minDis:
     7075            if minDis[k] <= thirdShortest:
     7076                if shortTxt: shortTxt += ', '
     7077                shortTxt += "{}: {:.2f}".format(k,minDis[k])
     7078        txt += "   Shortest distances are "+shortTxt
     7079
     7080    # do we know if there is a center of symmetry at origin?
     7081    centro = None
     7082    if 'xyz' in rd.SymOps:
     7083        centro = False
     7084        if '-x,-y,-z' in [i.replace(' ','').lower() for i in rd.SymOps['xyz']]:
     7085            centro = True
     7086           
     7087    msg = 'Be careful here. This space group has two origin settings. GSAS-II requires the origin to be placed at a center of symmetry (Origin 2). You must choose the correct option below or all subsequent results will be *wrong*. For more info, press the help button (bottom right).\n'
     7088    if centro:
     7089        msg += '\nThere is an -x,-y,-z symmetry op in the file input, so this is likely already in Origin 2.\n'
     7090    elif centro is None:
     7091        msg += '\nNo symmetry operations read from the input file; you must decide what to do. You are recommended to review a plot of the structure to make sure the symmetry is correct.\n'
     7092    else:
     7093        msg += '\nSymmetry operations in the input file do not contain -x,-y,-z, indicating an origin shift is likely needed.\n'
     7094
     7095    msg += '\nNote that computations below, made from the coordinates, may help determine the correct origin choice:'
     7096
     7097    width = 600
     7098    dlg = wx.Dialog(G2frame,wx.ID_ANY,'Warning: Shift origin?',
     7099                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE,
     7100                size=(width,-1))
     7101    dlg.CenterOnParent()
     7102    mainSizer = wx.BoxSizer(wx.VERTICAL)
     7103    txtbox = wx.StaticText(dlg,wx.ID_ANY,msg)
     7104    txtbox.Wrap(width-10)
     7105    mainSizer.Add(txtbox,0)
     7106    mainSizer.Add((5,5))
     7107    txtbox = wx.StaticText(dlg,wx.ID_ANY,txt)
     7108    mainSizer.Add(txtbox,0,wx.ALIGN_CENTER,1)
     7109    mainSizer.Add((10,10))
     7110
     7111    O1Btn = wx.Button(dlg,wx.ID_ANY,"Shift to Origin 2")
     7112    O1Btn.Bind(wx.EVT_BUTTON, lambda x: dlg.EndModal(wx.ID_OK))
     7113    O2Btn = wx.Button(dlg,wx.ID_ANY,"Keep current coordinates")
     7114    O2Btn.Bind(wx.EVT_BUTTON, lambda x: dlg.EndModal(wx.ID_YES))
     7115    if centro:
     7116        O2Btn.SetDefault()
     7117    elif centro is not None:
     7118        O1Btn.SetDefault()
     7119    btnSizer = wx.BoxSizer(wx.HORIZONTAL)
     7120    btnSizer.Add((20,20),1)
     7121    btnSizer.Add(O1Btn)
     7122    btnSizer.Add((10,10),0)
     7123    btnSizer.Add(O2Btn)
     7124    btnSizer.Add((20,20),1)
     7125    btnSizer.Add(HelpButton(dlg,helpIndex='Origin1'),0,wx.RIGHT,5)
     7126    mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
     7127    dlg.SetSizer(mainSizer)
     7128    dlg.Fit()
     7129    ans = dlg.ShowModal()
     7130    if ans == wx.ID_OK:
     7131        dlg.Destroy()
     7132        return O2Phase
     7133    elif ans == wx.ID_YES:
     7134        dlg.Destroy()
     7135        return rd.Phase
     7136    else:
     7137        dlg.Destroy()
     7138        return None
    70117139
    70127140if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.