Changeset 1529


Ignore:
Timestamp:
Oct 17, 2014 2:46:23 PM (9 years ago)
Author:
vondreele
Message:

revise display of space group info so that operators are in lined up columns
in bot the LS output & the popup window. - new class SGMessageBox (from wx.Dialog!)
G2spc.SGPrint now returns 2 items: Text & Tables
Work on supersymmetry - now better display of operators
operators more complete
use ErrorDialog? for more error messages instead of putting the message on the console

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIgrid.py

    r1524 r1529  
    161161#### GSAS-II class definitions
    162162################################################################################
     163
     164class SGMessageBox(wx.Dialog):
     165    ''' Special version of MessageBox that displays space group & super space group text
     166    in two blocks
     167    '''
     168    def __init__(self,parent,title,text,table,):
     169        wx.Dialog.__init__(self,parent,wx.ID_ANY,title,pos=wx.DefaultPosition,
     170            style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
     171        self.text=text
     172        self.table = table
     173        self.panel = wx.Panel(self)
     174        mainSizer = wx.BoxSizer(wx.VERTICAL)
     175        mainSizer.Add((0,10))
     176        for line in text:
     177            mainSizer.Add(wx.StaticText(self.panel,label='     %s     '%(line)),0,WACV)
     178        tableSizer = wx.FlexGridSizer(0,2,0,0)
     179        for item in self.table:
     180            tableSizer.Add(wx.StaticText(self.panel,label='     %s'%(item.ljust(30))),0,WACV)
     181        mainSizer.Add(tableSizer)
     182        btnsizer = wx.StdDialogButtonSizer()
     183        OKbtn = wx.Button(self.panel, wx.ID_OK)
     184        OKbtn.SetDefault()
     185        btnsizer.AddButton(OKbtn)
     186        btnsizer.Realize()
     187        mainSizer.Add((0,10))
     188        mainSizer.Add(btnsizer,0,wx.ALIGN_CENTER)
     189        self.panel.SetSizer(mainSizer)
     190        self.panel.Fit()
     191        self.Fit()
     192        size = self.GetSize()
     193        self.SetSize([size[0]+20,size[1]])
     194
     195    def Show(self):
     196        '''Use this method after creating the dialog to post it
     197        '''
     198        self.ShowModal()
     199        return
     200       
     201       
    163202
    164203class G2TreeCtrl(wx.TreeCtrl):
  • trunk/GSASIIphsGUI.py

    r1523 r1529  
    129129                generalData['AtomPtrs'] = [6,4,10,12]
    130130        if generalData['Type'] in ['modulated','magnetic',] and 'Super' not in generalData:
    131             generalData['SuperSg'] = ''
    132             generalData['Super'] = 0
    133             generalData['SuperVec'] = [[[0,0,.1],False,4],[[0,0,.1],False,4],[[0,0,.1],False,4]]
     131            generalData['SuperSg'] = '(abg)'
     132            generalData['Super'] = 1
     133            generalData['SuperVec'] = [[[0,0,.1],False,4],[[0,0,.1],False,4],[[0.,0.,.1],False,4]]
     134            generalData['SSGData'] = {}
    134135# end of patches
    135136        cx,ct,cs,cia = generalData['AtomPtrs']
     
    212213                           
    213214            def OnPhaseType(event):
    214                 if not generalData['AtomTypes']:             #can change only if no atoms!
     215                if not len(generalData['AtomTypes']):             #can change only if no atoms!
    215216                    generalData['Type'] = TypeTxt.GetValue()
    216217                    wx.CallAfter(UpdateGeneral)
    217218                else:
     219                    G2frame.ErrorDialog('Phase type change error','Can change phase type only if there are no atoms')
    218220                    TypeTxt.SetValue(generalData['Type'])               
    219221               
     
    233235                    Style = wx.ICON_EXCLAMATION
    234236                else:
    235                     text = G2spc.SGPrint(SGData)
     237                    text,table = G2spc.SGPrint(SGData)
    236238                    generalData['SGData'] = SGData
    237239                    msg = 'Space Group Information'
    238240                    Style = wx.ICON_INFORMATION
    239                 Text = ''
    240                 for line in text:
    241                     Text += line+'\n'
    242                 wx.MessageBox(Text,caption=msg,style=Style)
     241                G2gd.SGMessageBox(General,msg,text,table).Show()
    243242                wx.CallAfter(UpdateGeneral)
    244243               
     
    511510        def ModulatedSizer(name):
    512511           
    513             def OnSuperGp(event):   #need a check on supersymmetry group rules here!
     512            def OnSuperGp(event):
    514513                SSymbol = superGp.GetValue()
    515                 SSGData = G2spc.SSpcGroup(generalData['SGData'],SSymbol)
    516                 generalData['SuperSg'] = SSymbol
     514                E,SSGData = G2spc.SSpcGroup(generalData['SGData'],SSymbol)
     515                if E:
     516                    text = [E+'\nSuperspace Group set to previous']
     517                    superGp.SetValue(generalData['SuperSg'])
     518                    msg = 'Superspace Group Error'
     519                    Style = wx.ICON_EXCLAMATION
     520                else:
     521                    Vec = generalData['SuperVec'][0][0]     #(3+1) only
     522                    Vec = G2spc.SSGModCheck(Vec,SSGData)
     523                    generalData['SuperVec'][0][0] = Vec
     524                    text,table = G2spc.SSGPrint(generalData['SGData'],SSGData)
     525                    generalData['SSGData'] = SSGData
     526                    generalData['SuperSg'] = SSymbol
     527                    msg = 'Superspace Group Information'
     528                    Style = wx.ICON_INFORMATION
     529                G2gd.SGMessageBox(General,msg,text,table).Show()
     530                wx.CallAfter(UpdateGeneral)               
    517531           
    518532            def OnDim(event):
     
    526540                try:
    527541                    Vec = [float(vec[i]) for i in range(3)]
     542                    Vec = G2spc.SSGModCheck(Vec,generalData['SSGData'])
    528543                except (ValueError,IndexError):
    529544                    Vec = generalData['SuperVec'][ind][0]
    530545                if not np.any(np.array(Vec)):
    531546                    Vec = generalData['SuperVec'][ind][0]
    532                 generalData['modVects'][ind][0] = Vec
     547                generalData['SuperVec'][ind][0] = Vec
    533548                h,k,l = Vec
    534549                Obj.SetValue('%.3f %.3f %.3f'%(h,k,l))
     
    557572            superGp = wx.TextCtrl(General,value=generalData['SuperSg'],style=wx.TE_PROCESS_ENTER)
    558573            superGp.Bind(wx.EVT_TEXT_ENTER,OnSuperGp)       
    559             superGp.Bind(wx.EVT_KILL_FOCUS,OnSuperGp)
    560574            dimSizer.Add(superGp,0,WACV)
    561575            modSizer.Add(dimSizer)
     
    11801194                elif event.AltDown() or (event.ShiftDown() and event.ControlDown()):
    11811195                    if atomData[r][-1] in rbAtmDict:
    1182                         G2frame.dataFrame.SetStatusText('**** ERROR - atom is in a rigid body and can not be moved ****')
     1196                        G2frame.ErrorDialog('Atom move error','Atoms in rigid bodies can not be moved')
    11831197                        Atoms.frm = -1
    11841198                        Atoms.ClearSelection()
     
    13851399        indx = Atoms.GetSelectedRows()
    13861400        if len(indx) != 1:
    1387             print '**** ERROR - only one atom can be moved ****'
     1401            G2frame.ErrorDialog('Atom move error','Only one atom can be moved')
    13881402        elif atomData[indx[0]][-1] in rbAtmDict:
    1389             print '**** ERROR - Atoms in rigid bodies can not be moved ****'
     1403            G2frame.ErrorDialog('Atom move error','Atoms in rigid bodies can not be moved')
    13901404        else:
    13911405            atomData[indx[0]][cx:cx+3] = [x,y,z]
  • trunk/GSASIIspc.py

    r1515 r1529  
    4444       
    4545             * 'SpGrp': space group symbol, slightly cleaned up
    46              * 'Laue':  one of '-1', '2/m', 'mmm', '4/m', '4/mmm', '3R',
     46             * 'SGLaue':  one of '-1', '2/m', 'mmm', '4/m', '4/mmm', '3R',
    4747               '3mR', '3', '3m1', '31m', '6/m', '6/mmm', 'm3', 'm3m'
    4848             * 'SGInv': boolean; True if centrosymmetric, False if not
     
    5555             * 'SGPolax': one of '', 'x', 'y', 'x y', 'z', 'x z', 'y z',
    5656               'xyz', '111' for arbitrary axes
     57             * 'SGPtGrp': one of 32 point group symbols (with some permutations)
     58                - filled by SGPtGroup - is external (KE) part of supersymmetry point group
     59             * 'SSGKl': default internal (Kl) part of supersymmetry point group; modified
     60             in supersymmetry stuff depending on chosen modulation vector for Mono & Ortho
    5761
    5862    """
     
    6266    SysSym = ('triclinic','monoclinic','orthorhombic','tetragonal','rhombohedral','trigonal','hexagonal','cubic')
    6367    SGData = {}
     68    SGInfo = pyspg.sgforpy(SGSymbol)
    6469    SGData['SpGrp'] = SGSymbol.strip().lower().capitalize()
    65     SGInfo = pyspg.sgforpy(SGSymbol)
    6670    SGData['SGLaue'] = LaueSym[SGInfo[0]-1]
    6771    SGData['SGInv'] = bool(SGInfo[1])
     
    104108        SGData['SGSys'] = SysSym[7]
    105109    SGData['SGPolax'] = SGpolar(SGData)
     110    SGData['SGPtGrp'],SGData['SSGKl'] = SGPtGroup(SGData)
    106111    return SGInfo[8],SGData
    107112
     
    162167    return POL[NPol]
    163168   
     169def SGPtGroup(SGData):
     170    '''
     171    Determine point group of the space group - done after space group symbol has
     172    been evaluated by SpcGroup. Only short symbols are allowed
     173   
     174    :param SGData: from :func SpcGroup
     175    returns SSGPtGrp & SSGKl (only defaults for Mono & Ortho)
     176    '''
     177    Flds = SGData['SpGrp'].split(' ')
     178    if SGData['SGLaue'] == '-1':    #triclinic
     179        if '-' in Flds[1]:
     180            return '-1',[-1,]
     181        else:
     182            return '1',[1,]
     183    elif SGData['SGLaue'] == '2/m': #monoclinic - default for 2D modulation vector
     184        if '/' in SGData['SpGrp']:
     185            return '2/m',[-1,1]
     186        elif '2' in SGData['SpGrp']:
     187            return '2',[-1,]
     188        else:
     189            return 'm',[1,]
     190    elif SGData['SGLaue'] == 'mmm': #orthorhombic
     191        if SGData['SpGrp'].count('2') == 3:
     192            return '222',[1,1,1]
     193        elif SGData['SpGrp'].count('2') == 1:
     194            if SGData['SGPolax'] == 'x':
     195                return '2mm',[1,1,1]
     196            elif SGData['SGPolax'] == 'y':
     197                return 'm2m',[1,1,1]
     198            elif SGData['SGPolax'] == 'z':
     199                return 'mm2',[1,1,1]
     200        else:
     201            return 'mmm',[1,1,-1]
     202    elif SGData['SGLaue'] == '4/m': #tetragonal
     203        if '/' in SGData['SpGrp']:
     204            return '4/m',[1,-1]
     205        elif '-' in Flds[1]:
     206            return '-4',[-1,]
     207        else:
     208            return '4',[1,]
     209    elif SGData['SGLaue'] == '4/mmm':
     210        if '/' in SGData['SpGrp']:
     211            return '4/mmm',[1,-1,1,1]
     212        elif '-' in Flds[1]:
     213            if '2' in Flds[2]:
     214                return '-42m',[-1,-1,1]
     215            else:
     216                return '-4m2',[-1,1,-1]             
     217        elif '2' in Flds[2:]:
     218            return '422',[1,-1,-1]
     219        else:
     220            return '4mm',[1,1,1]
     221    elif SGData['SGLaue'] in ['3','3R']:  #trigonal/rhombohedral
     222        if '-' in Flds[1]:
     223            return '-3',[-1,]
     224        else:
     225            return '3',[1,]
     226    elif SGData['SGLaue'] == '3mR' and 'R' in Flds[0]:
     227        if '2' in Flds[2]:
     228            return '32',[1,-1]
     229        elif '-' in Flds[1]:
     230            return '-3m',[-1,1]
     231        else:
     232            return '3m',[1,1]
     233    elif SGData['SGLaue'] == '3m1':
     234        if '2' in Flds[2]:
     235            return '321',[1,-1,1]
     236        elif '-' in Flds[1]:
     237            return '-3m1',[-1,1,1]
     238        else:
     239            return '3m1',[1,1,1]
     240    elif SGData['SGLaue'] == '31m':
     241        if '2' in Flds[3]:
     242            return '312',[1,1,-1]
     243        elif '-' in Flds[1]:
     244            return '-31m',[-1,1,1]
     245        else:
     246            return '31m',[1,1,1]
     247    elif SGData['SGLaue'] == '6/m': #hexagonal
     248        if '/' in SGData['SpGrp']:
     249            return '6/m',[1,-1]
     250        elif '-' in SGData['SpGrp']:
     251            return '-6',[-1,]
     252        else:
     253            return '6',[1,]
     254    elif SGData['SGLaue'] == '6/mmm':
     255        if '/' in SGData['SpGrp']:
     256            return '6/mmm',[1,-1,1,1]
     257        elif '-' in Flds[1]:
     258            if '2' in Flds[2]:
     259                return '-62m',[-1,-1,1]
     260            else:
     261                return '-6m2',[-1,1,-1]                 
     262        elif '2' in Flds[2:]:
     263            return '622',[1,-1,-1]
     264        else:
     265            return '6mm',[1,1,1]   
     266    elif SGData['SGLaue'] == 'm3':      #cubic - no (3+1) supersymmetry
     267        if '2' in Flds[1]:
     268            return '23',[]
     269        else: 
     270            return 'm3',[]
     271    elif SGData['SGLaue'] == 'm3m':
     272        if '4' in Flds[1]:
     273            if '-' in Flds[1]:
     274                return '-43m',[]
     275            else:
     276                return '432',[]
     277        else:
     278            return 'm-3m',[]
     279   
    164280def SGPrint(SGData):
    165281    '''
     
    169285    :returns:
    170286        SGText - list of strings with the space group details
     287        SGTable - list of strings for each of the operations
    171288    '''
    172289    Mult = len(SGData['SGCen'])*len(SGData['SGOps'])*(int(SGData['SGInv'])+1)
     
    179296        SGText.append(' The lattice is '+CentStr+' '+SGData['SGLatt']+'-centered '+SGData['SGSys'].lower())
    180297    else:
    181         SGText.append(' The lattice is '+CentStr+' '+'primitive '+SGData['SGSys'].lower())       
     298        SGText.append(' The lattice is '+CentStr+' '+'primitive '+SGData['SGSys'].lower())
     299    SGText.append(' The Laue symmetry is '+SGData['SGLaue'])
     300    SGText.append(' The lattice point group is '+SGData['SGPtGrp'])
    182301    SGText.append(' Multiplicity of a general site is '+str(Mult))
    183     SGText.append(' The Laue symmetry is '+SGData['SGLaue'])
    184302    if SGData['SGUniq'] in ['a','b','c']:
    185303        SGText.append(' The unique monoclinic axis is '+SGData['SGUniq'])
     
    187305        SGText.append(' The inversion center is located at 0,0,0')
    188306    if SGData['SGPolax']:
    189         SGText.append(' The location of the origin is arbitrary in '+SGData['SGPolax'])
    190     SGText.append('\n'+' The equivalent positions are:')
    191     if SGData['SGLatt'] != 'P':
    192         SGText.append('\n ('+Latt2text(SGData['SGLatt'])+')+\n')
    193     Ncol = 2
    194     line = ' '
    195     col = 0
    196     for iop,[M,T] in enumerate(SGData['SGOps']):
    197         OPtxt = MT2text(M,T)
    198         Fld = '(%2i) '%(iop+1)+OPtxt+'\t'
    199         line += Fld
    200         if '/' not in Fld:
    201             line += '\t'
    202         col += 1
    203         if col == Ncol:
    204             SGText.append(line)       
    205             line = ' '
    206             col = 0
    207     SGText.append(line)       
    208     return SGText
     307        SGText.append(' The location of the origin is arbitrary in '+SGData['SGPolax']+'\n')
     308    if SGData['SGLatt'] == 'P':
     309        SGText.append(' The equivalent positions are:\n')
     310    else:   
     311        SGText.append(' The equivalent positions are:')
     312        SGText.append(' ('+Latt2text(SGData['SGLatt'])+')+\n')
     313    SGTable = []
     314    for i,[M,T] in enumerate(SGData['SGOps']):
     315        SGTable.append('(%2d) %s'%(i+1,MT2text(M,T)))
     316    return SGText,SGTable
    209317
    210318def AllOps(SGData):
     
    268376        if IK:
    269377            if IJ < 3:
    270                 Fld += TRA[IK]+XYZ[IJ]
     378                Fld += (TRA[IK]+XYZ[IJ]).rjust(5)
    271379            else:
    272                 Fld += TRA[IK]+'+'+XYZ[IJ]
     380                Fld += (TRA[IK]+'+'+XYZ[IJ]).rjust(5)
    273381        else:
    274             Fld += XYZ[IJ]
     382            Fld += XYZ[IJ].rjust(5)
    275383        if j != 2: Fld += ', '
    276384    return Fld
     
    312420       * SSGData - is a dict (see :ref:`Superspace Group object<SSGData_table>`) with entries:
    313421       
    314              * 'SpGrp': superspace group symbol extension to space group symbol, accidental spaces removed
    315              * 'LauePtGp':  one of '-1', '2/m', 'mmm', '4/mmm', '-3m', '-31m', '6/mmm'
    316              * 'LaueMod': one of '(abg)', '(ab0)', '(ab1/2)', '(a0g)', (a1/2g)','(0bg)', '(1/2bg)',
    317                '(a00)', '(a01/2)', '(a1/20)', (a1/21/2)', '(a01)', '(a10)',
    318                '(0b0)', '(0b1/2)', '(1/2b0)', (1/2b1/2)', '(0b1)', '(1b0)',
    319                '(00g)', '(01/2g)', '(1/20g)', (1/21/2g)', '(01g)', '(10g)','(1/3/1/3g)'
    320              * 'SGLatt': one of 'P', 'A', 'B', 'C', 'I', 'F', 'R'
    321              * 'SGCen': 4D cell centering vectors [0,0,0,0] at least
    322              * 'SGOps': 4D symmetry operations as [M,T] so that M*x+T = x'
     422             * 'SSpGrp': superspace group symbol extension to space group symbol, accidental spaces removed
     423             * 'SSGCen': 4D cell centering vectors [0,0,0,0] at least
     424             * 'SSGOps': 4D symmetry operations as [M,T] so that M*x+T = x'
    323425
    324426    """
    325427   
    326428    def splitSSsym(SSymbol):
    327         ' Splits supersymmetry symbol into two lists of strings'
     429        '''
     430        Splits supersymmetry symbol into two lists of strings
     431        '''
    328432        modsym,gensym = SSymbol.replace(' ','').split(')')
    329433        nfrac = modsym.count('/')
     
    351455        return modsym,gensym
    352456       
    353     modsym,gensym = splitSSsym(SSymbol)
    354     print modsym,gensym
    355     T = np.zeros(4)
     457    def checkModSym():
     458        '''
     459        Checks to see if proposed modulation form is allowed for Laue group
     460        '''
     461        if LaueId in [0,] and LaueModId in [0,]:
     462            return True
     463        elif LaueId in [1,]:
     464            try:
     465                if modsym.index('1/2') != ['A','B','C'].index(SGData['SGLatt']):
     466                    return False
     467                if 'I'.index(SGData['SGLatt']) and modsym.count('1/2') not in [0,2]:
     468                    return False
     469            except ValueError:
     470                pass
     471            if SGData['SGUniq'] == 'a' and LaueModId in [5,6,7,8,9,]:
     472                return True
     473            elif SGData['SGUniq'] == 'b' and LaueModId in [3,4,13,14,15,]:
     474                return True
     475            elif SGData['SGUniq'] == 'c' and LaueModId in [1,2,19,20,21,]:
     476                return True
     477        elif LaueId in [2,] and LaueModId in [i+7 for i in range(18)]:
     478            try:
     479                if modsym.index('1/2') != ['A','B','C'].index(SGData['SGLatt']):
     480                    return False
     481                if SGData['SGLatt'] in ['I','F',] and modsym.index('1/2'):
     482                    return False
     483            except ValueError:
     484                pass
     485            return True
     486        elif LaueId in [3,4,] and LaueModId in [19,22,]:
     487            try:
     488                if SGData['SGLatt'] == 'I' and modsym.count('1/2'):
     489                    return False
     490            except ValueError:
     491                pass
     492            return True
     493        elif LaueId in [7,8,9,] and LaueModId in [19,25,]:
     494            try:
     495                if SGData['SGLatt'] == 'R' and modsym.index('1/3'):
     496                    return False
     497            except ValueError:
     498                pass
     499            return True
     500        elif LaueId in [10,11,] and LaueModId in [19,]:
     501            return True
     502        return False
     503       
     504    def fixMonoOrtho():
     505        mod = ''.join(modsym).replace('1/2','0').replace('1','0')
     506        if SGData['SGPtGrp'] in ['2','m']:  #OK
     507            if mod in ['a00','0b0','00g']:
     508                return [i*-1 for i in SGData['SSGKl']]
     509            else:
     510                return SGData['SSGKl']
     511        elif SGData['SGPtGrp'] == '2/m':    #OK
     512            if mod in ['a00','0b0','00g']:
     513                return SGData['SSGKl']
     514            else:
     515                return [i*-1 for i in SGData['SSGKl']]
     516        else:   #orthorhombic
     517            if SGData['SGPtGrp'] == '222':
     518                return [1 if i in ['a','b','g'] else -1 for i in mod]
     519            elif SGData['SGPtGrp'] == 'mm2':
     520                if 'g' in mod:
     521                    return [1,1,1]
     522                elif 'b' in mod:
     523                    return [1,-1,-1]
     524                else:
     525                    return [-1,1,-1]
     526            elif SGData['SGPtGrp'] == 'm2m':
     527                if 'b' in mod:
     528                    return [1,1,1]
     529                elif 'g' in mod:
     530                    return [1,-1,-1]
     531                else:
     532                    return [-1,-1,1]               
     533            elif SGData['SGPtGrp'] == '2mm':
     534                if 'a' in mod:
     535                    return [1,1,1]
     536                elif 'b' in mod:
     537                    return [-1,-1,1]
     538                else:
     539                    return [-1,1,-1]
     540            else:
     541                return [-1 if i in ['a','b','g'] else 1 for i in mod]
     542               
     543    def genSSGOps():
     544        SSGOps = SSGData['SSGOps']
     545        SSGKl = SGData['SSGKl']
     546        iFrac = {}
     547        for i,frac in enumerate(SSGData['modSymb']):
     548            if frac in ['1/2','1/3','1/4','1/6','1']:
     549                iFrac[i] = frac
     550# set identity & 1,-1
     551        SSGOps[0][0][3,3] = 1.
     552# monoclinic
     553        if SGData['SGPtGrp'] in ['2','m']:  #OK
     554            SSGOps[1][0][3,3] = SSGKl[0]
     555            for i in iFrac:
     556                if SGData['SGPtGrp'] == '2':
     557                    SSGOps[1][0][3,i] = 1
     558                else:
     559                    SSGOps[1][0][3,i] = -1
     560        elif SGData['SGPtGrp'] == '2/m':    #OK
     561            SSGOps[1][0][3,3] = SSGKl[1]
     562            for i in iFrac:
     563                SSGOps[1][0][3,i] = -1
     564# orthorhombic
     565        elif SGData['SGPtGrp'] in ['222','mm2','m2m','2mm','mmm']:
     566            SSGOps[1][0][3,3] = SSGKl[0]
     567            SSGOps[2][0][3,3] = SSGKl[1]
     568            SSGOps[3][0][3,3] = SSGKl[2]
     569# tetragonal
     570        elif SGData['SGPtGrp'] in ['4','-4',]:
     571            SSGOps[1][0][3,3] = SSGKl[0]
     572            if '1/2' in SSGData['modSymb']:
     573                if SGData['SGPtGrp'] == '-4':
     574                    SSGOps[1][0][3,1] = 1
     575                else:
     576                    SSGOps[1][0][3,1] = -1
     577        elif SGData['SGPtGrp'] in ['4/m',]:
     578            SSGOps[1][0][3,3] = SSGKl[1]
     579            if '1/2' in SSGData['modSymb']:
     580                SSGOps[1][0][3,3] *= -1
     581                SSGOps[1][0][3,1] = -1
     582        elif SGData['SGPtGrp'] in ['422','4mm','-42m','-4m2',]:
     583            SSGOps[1][0][3,3] = SSGKl[1]
     584        elif SGData['SGPtGrp'] in ['4/mmm',]:
     585            SSGOps[1][0][3,3] = SSGKl[1]
     586            if '1/2' in SSGData['modSymb']:
     587                SSGOps[1][0][3,3] *= -1
     588                SSGOps[1][0][3,1] = -1
     589# trigonal
     590        elif SGData['SGPtGrp'] in ['3','-3',]:
     591            SSGOps[1][0][3,3] = SSGKl[0]
     592            if '1/2' in SSGData['modSymb']:
     593                if SGData['SGPtGrp'] == '-6':
     594                    SSGOps[1][0][3,1] = 1
     595                else:
     596                    SSGOps[1][0][3,1] = -1
     597        elif SGData['SGPtGrp'] in ['32','3m','-3m',]:
     598            SSGOps[1][0][3,3] = SSGKl[1]
     599        elif SGData['SGPtGrp'] in ['312','321','3m1','31m','-3m1','-31m',]:
     600            pass
     601# hexagonal
     602        elif SGData['SGPtGrp'] in ['6','-6',]:
     603            SSGOps[1][0][3,3] = SSGKl[0]
     604        elif SGData['SGPtGrp'] in ['6/m',]:
     605            SSGOps[1][0][3,3] = SSGKl[1]
     606        elif SGData['SGPtGrp'] in ['622','6mm','-62m','-62',]:
     607            pass
     608        elif SGData['SGPtGrp'] in ['6/mmm',]:
     609            pass
     610           
     611        if SGData['SGInv']:
     612            SSGfull = SSGOps[:]
     613            for M,V in SSGOps:
     614                Mi = -1*M
     615                SSGfull.append([Mi,V])
     616            SSGOps = SSGfull
     617        if SGData['SGPtGrp'] in ['1','-1']: #triclinic - done
     618            return True,SSGOps
     619        nOps = len(SSGOps)
     620        for i in range(nOps):
     621            for j in range(nOps):
     622                OpC = list(SGProd(SSGOps[j],SSGOps[i]))
     623                OpC[1] %= 1.
     624                for k in range(nOps):
     625                    OpD = SSGOps[k]
     626                    if np.allclose(OpC[0],OpD[0]) and np.allclose(OpC[1],OpD[1]):
     627                        continue
     628                    elif np.allclose(OpC[0][:3,:3],OpD[0][:3,:3]):
     629                        if np.allclose(OpD[0][3],np.zeros(4)):
     630                            SSGOps[k] = OpC
     631                        else:
     632                            return False,None
     633        return True,SSGOps
     634                   
     635    def getTau(genQ):
     636        print 'genQ',genQ
     637        return genQ
     638       
     639    LaueModList = ['abg', 'ab0', 'ab1/2', 'a0g', 'a1/2g','0bg', '1/2bg',
     640               'a00', 'a01/2', 'a1/20', 'a1/21/2', 'a01', 'a10',
     641               '0b0', '0b1/2', '1/2b0', '1/2b1/2', '0b1', '1b0',
     642               '00g', '01/2g', '1/20g', '1/21/2g', '01g', '10g','1/31/3g']
     643    LaueList = ['-1','2/m','mmm','4/m','4/mmm','3R','3mR','3','3m1','31m','6/m','6/mmm','m3','m3m']
     644    GenSymList = ['','s','0s','s0','00s','0s0','s00','s0s','ss0','0ss','q00','0q0','00q','qq0','q0q','0qq',
     645        'q','q0','0q','qqs','s0s0','00ss','s00s','q0q0','q0qs','t','t00','t0','h','h00']
     646    Fracs = {'1/2':0.5,'1/3':1./3,'1':1.0,'0':0.,'s':.5,'t':1./3,'q':.25,'h':1./6,'a':0.,'b':0.,'g':0.}
     647    LaueId = LaueList.index(SGData['SGLaue'])
     648    if LaueId in [12,13,]:
     649        return '(3+1) superlattices not defined for cubic space groups',None
     650    elif LaueId in [5,6,]:
     651        return '(3+1) superlattices not defined for rhombohedral settings - use hexagonal setting',None
     652    try:
     653        modsym,gensym = splitSSsym(SSymbol)
     654    except ValueError:
     655        return 'Error in superspace symbol '+SSymbol,None
     656    if ''.join(gensym) not in GenSymList:
     657        return 'unknown generator symbol '+''.join(gensym),None
     658    LaueModId = LaueModList.index(''.join(modsym))
     659    if not checkModSym():
     660        return 'Modulation '+''.join(modsym)+' not consistent with space group '+SGData['SpGrp'],None
     661    modQ = [Fracs[mod] for mod in modsym]
     662    if LaueId in [1,2]:
     663        SGData['SSGKl'] = fixMonoOrtho()
     664    genQ = [Fracs[mod] for mod in gensym]
     665    if len(gensym) and len(gensym) != len(SGData['SSGKl']):
     666        return 'Wrong number of items in generator symbol '+''.join(gensym),None
     667    genQ = getTau(genQ)
     668    SSGData = {'SSpGrp':SGData['SpGrp']+SSymbol,'modQ':modQ,'modSymb':modsym}
     669    SSCen = np.ones((len(SGData['SGCen']),4))*0.5
     670    for icen,cen in enumerate(SGData['SGCen']):
     671        SSCen[icen,0:3] = cen
     672    SSGData['SSGCen'] = SSCen
     673    SSGData['SSGOps'] = []
    356674    for iop,op in enumerate(SGData['SGOps']):
    357         ssop = np.eye(4)
     675        T = np.zeros(4)
     676        ssop = np.zeros((4,4))
    358677        ssop[:3,:3] = op[0]
    359678        T[:3] = op[1]
    360                    
    361         print SSMT2text(ssop,T)
    362     return None
     679        SSGData['SSGOps'].append([ssop,T])
     680    E,SSGOps = genSSGOps()
     681    if E:
     682        SSGData['SSGOps'] = SSGOps                     
     683        return None,SSGData
     684    else:
     685        return 'Operator conflict - incorrect superspace symbol',None
    363686
    364687def SSGPrint(SGData,SSGData):
     
    370693    :returns:
    371694        SSGText - list of strings with the superspace group details
    372     '''
    373     Mult = len(SGData['SGCen'])*len(SGData['SGOps'])*(int(SGData['SGInv'])+1)
     695        SGTable - list of strings for each of the operations
     696    '''
     697    Mult = len(SSGData['SSGCen'])*len(SSGData['SSGOps'])*(int(SGData['SGInv'])+1)
    374698    SSGText = []
    375699    SSGText.append(' Superspace Group: '+SSGData['SSpGrp'])
     
    378702        CentStr = 'non'+CentStr
    379703    if SGData['SGLatt'] in 'ABCIFR':
    380         SSGText.append(' The lattice is '+CentStr+' '+SSGData['SSGLatt']+'-centered '+SSGData['SSGSys'].lower())
     704        SSGText.append(' The lattice is '+CentStr+' '+SGData['SGLatt']+'-centered '+SGData['SGSys'].lower())
    381705    else:
    382         SGText.append(' The superlattice is '+CentStr+' '+'primitive '+SSGData['SSGSys'].lower())       
     706        SSGText.append(' The superlattice is '+CentStr+' '+'primitive '+SGData['SGSys'].lower())       
     707    SSGText.append(' The Laue symmetry is '+SGData['SGLaue'])
     708    SSGText.append(' The superlattice point group is '+SGData['SGPtGrp']+','+''.join([str(i) for i in SGData['SSGKl']]))
     709    SSGText.append(' The number of super space group generators is '+str(len(SGData['SSGKl'])))
    383710    SSGText.append(' Multiplicity of a general site is '+str(Mult))
    384     SSGText.append(' The Laue symmetry is '+SGData['SGLaue'])
    385711    if SGData['SGUniq'] in ['a','b','c']:
    386712        SSGText.append(' The unique monoclinic axis is '+SGData['SGUniq'])
     
    389715    if SGData['SGPolax']:
    390716        SSGText.append(' The location of the origin is arbitrary in '+SGData['SGPolax'])
    391     SSGText.append('\n'+' The equivalent positions are:')
    392717    if len(SSGData['SSGCen']) > 1:
     718        SSGText.append(' The equivalent positions are:')
    393719        SSGText.append('\n ('+SSLatt2text(SSGData['SSGCen'])+')+\n')
    394     Ncol = 2
    395     line = ' '
    396     col = 0
    397     for iop,[M,T] in enumerate(SSGData['SSGOps']):
    398         OPtxt = SSMT2text(M,T)
    399         Fld = '(%2i) '%(iop+1)+OPtxt+'\t'
    400         line += Fld
    401         if '/' not in Fld:
    402             line += '\t'
    403         col += 1
    404         if col == Ncol:
    405             SSGText.append(line)       
    406             line = ' '
    407             col = 0
    408     SSGText.append(line)       
    409     return SSGText
     720    else:
     721        SSGText.append(' The equivalent positions are:\n')
     722    SSGTable = []
     723    for i,[M,T] in enumerate(SSGData['SSGOps']):
     724        SSGTable.append('(%2d) %s'%(i+1,SSMT2text(M,T)))
     725    return SSGText,SSGTable
     726   
     727def SSGModCheck(Vec,SSGData):
     728    ''' Checks modulation vector compatibility with supersymmetry space group symbol.
     729    Superspace group symbol takes precidence & the vector will be modified accordingly
     730    '''
     731    modQ = SSGData['modQ']
     732    modSymb = SSGData['modSymb']
     733    Vec = [0.1 if (vec == 0.0 and mod in ['a','b','g']) else vec for [vec,mod] in zip(Vec,modSymb)]
     734    return [Q if mod not in ['a','b','g'] and vec != Q else vec for [vec,mod,Q] in zip(Vec,modSymb,modQ)]
    410735
    411736def SSMT2text(M,T):
     
    426751        if IK:
    427752            if IJ[0] == '-':
    428                 Fld += TRA[IK]+IJ
     753                Fld += (TRA[IK]+IJ).rjust(8)
    429754            else:
    430                 Fld += TRA[IK]+'+'+IJ
     755                Fld += (TRA[IK]+'+'+IJ).rjust(8)
    431756        else:
    432             Fld += IJ
     757            Fld += IJ.rjust(8)
    433758        if j != 3: Fld += ', '
    434759    return Fld
     
    437762    "Lattice centering vectors to text"
    438763    lattTxt = ''
    439     for vec in SGCen:
     764    for vec in SSGCen:
     765        lattTxt += ' '
    440766        for item in vec:
    441767            if int(item*12.):
     
    443769            else:
    444770                lattTxt += '0,'
    445         lattTxt[-1] = ';'
    446     return lattTxt[:-1]
     771        lattTxt = lattTxt.rstrip(',')
     772        lattTxt += ';'
     773    lattTxt = lattTxt.rstrip(';').lstrip(' ')
     774    return lattTxt
    447775       
    448776def SSpaceGroup(SGSymbol,SSymbol):
     
    461789    E,B = SSpcGroup(A,SSymbol)   
    462790    if E > 0:
    463         print SGErrors(E)
     791        print E
    464792        return
    465     for l in SGPrint(B):
     793    for l in SSGPrint(B):
    466794        print l
     795       
     796def SGProd(OpA,OpB):
     797    '''
     798    Form space group operator product. OpA & OpB are [M,V] pairs;
     799        both must be of same dimension (3 or 4). Returns [M,V] pair
     800    '''
     801    A,U = OpA
     802    B,V = OpB
     803    M = np.inner(B.T,A)
     804    W = np.inner(B,U)+V
     805    return M.T,W
    467806       
    468807def MoveToUnitCell(xyz):
  • trunk/GSASIIstrIO.py

    r1523 r1529  
    959959        PawleyRef = PhaseData[name].get('Pawley ref',[])
    960960        SGData = General['SGData']
    961         SGtext = G2spc.SGPrint(SGData)
     961        SGtext,SGtable = G2spc.SGPrint(SGData)
    962962        cell = General['Cell']
    963963        A = G2lat.cell2A(cell[1:7])
     
    10671067                print >>pFile,''
    10681068                for line in SGtext: print >>pFile,line
     1069                if len(SGtable):
     1070                    for i,item in enumerate(SGtable[::2]):
     1071                        line = ' %s %s'%(item.ljust(30),SGtable[2*i+1].ljust(30))
     1072                        print >>pFile,line   
     1073                else:
     1074                    print >>pFile,' ( 1)    %s'%(SGtable[0])
    10691075                PrintRBObjects(resRBData,vecRBData)
    10701076                PrintAtoms(General,Atoms)
Note: See TracChangeset for help on using the changeset viewer.