source: trunk/SUBGROUPS.py @ 4365

Last change on this file since 4365 was 4365, checked in by toby, 21 months ago

set keywords & eol on all G2 files

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 12.1 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3*SUBGROUPS: Interface to special GSAS Bilbao SUBGROUPS & k-SUBGROUPSMAG web pages*
4-------------------------------
5
6Extraction of  space subgroups for a given space group and a propagation vector
7from the GSAS version of SUBGROUPS & k-SUBGROUPSMAG web page on the Bilbao Crystallographic server
8
9"""
10########### SVN repository information ###################
11# $Date: 2020-03-12 20:22:30 +0000 (Thu, 12 Mar 2020) $
12# $Author: toby $
13# $Revision: 4365 $
14# $URL: trunk/SUBGROUPS.py $
15# $Id: SUBGROUPS.py 4365 2020-03-12 20:22:30Z toby $
16########### SVN repository information ###################
17from __future__ import division, print_function
18import requests
19import numpy as np
20import numpy.linalg as nl
21import GSASIIspc as G2spc
22import GSASIIpath
23GSASIIpath.SetBinaryPath()
24submagSite = 'https://www.cryst.ehu.es/cgi-bin/cryst/programs/subgrmag1_general_GSAS.pl?'
25
26def GetNonStdSubgroups(SGData, kvec,star=False,landau=False,maximal=False):
27    '''Run Bilboa's SUBGROUPS for a non-standard space group.
28    This requires doing a post to the Bilboa site, which returns all
29    subgroups of the entered space group as the text of a web page
30    with a table containing the space group symbol, the
31    transformation matrix and index for each subgroup.
32
33    :params list kvec: propogation vector as a list of nine string fractions or blank
34    :params SGData: space group object (see :ref:`Space Group object<SGData_table>`)
35
36    :returns: (error,text) error: if True no error or False; where
37      text containts a possible web page text
38    '''
39    print('''
40    For use of SUBGROUPS, please cite:
41      Symmetry-Based Computational Tools for Magnetic Crystallography,
42      J.M. Perez-Mato, S.V. Gallego, E.S. Tasci, L. Elcoro, G. de la Flor, and M.I. Aroyo
43      Annu. Rev. Mater. Res. 2015. 45,217-48.
44      doi: 10.1146/annurev-matsci-070214-021008
45    ''')
46       
47       
48    def getSpGrp(item):
49        return item.replace('<i>','').replace('</i>','').replace('<sub>','').replace('</sub>','')
50   
51    def getMatVec(item):
52        return item.replace('{','[').replace('}',']')
53               
54    starmag = 'no'
55    if star:
56        starmag = 'yes'
57    land = 'no'
58    if landau:
59        land = 'yes'
60    celtodas = 'no'
61    limite = 'spgroup'
62    if maximal:
63        limite = 'maximal'
64    postdict = {'centrosymmetry':'0','crystalsystem':'0','landau':land,
65               'eleccion':'subgrmag1_k','inicio':'nostandard','celtodas':celtodas,
66               'limite':limite,'list':'Submit','listado':'lista','starmagnetica':starmag,
67               'pointgroup':'0','polarity':'0','sub':'1',
68               'super':'','tipog':'gesp','wyckoffstrain':''}
69    text,table = G2spc.SGPrint(SGData)
70    OpList = G2spc.TextOps(text,table,reverse=True)
71#    GenList = G2spc.TextGen(SGData,reverse=True)
72    for item in OpList:
73        item += '\n'
74    sym = ""
75    for i in OpList:
76        if sym: sym += '\n'
77        #if sym: sym += ' ' # use this for testing to generate an error in place of previous
78        sym += i.lower()
79    postdict['generators'] = sym
80    for j in [1,2,3]:
81        if kvec[3*j-3] == ' ':
82            break
83        for i,k in zip(('x','y','z'),kvec[3*j-3:3*j]):
84            postdict['knm%d%s'%(j,i)] = k
85    try:
86        r = requests.get(submagSite,params=postdict)
87    except:     #ConnectionError?
88        page = ''
89        print('connection error - not on internet')
90        return None,None
91    if r.status_code == 200:
92        print('request OK')
93        page = r.text
94        page = page.replace('<font style= "text-decoration: overline;">','<font>-')
95    else:
96        page = ''
97        print('request failed. Reason=',r.reason)
98        return None,None
99    r.close()
100   
101    result = page.replace('&','\n')
102    result = result.split('\n')
103    SPGPs = []
104    MVs = []
105    baseList = []
106    itemList = []
107    superList = []
108    altList = []
109    start = 0
110    for line in result:    #work around bug report from Bilbao
111        start += 1
112        if 'yesz' in line:
113            break
114    for line in result[start:]:
115        if 'GGG' in line:
116            lines = line.split('GGG')
117            line = lines[0]
118            alts = []
119            beg = True
120            for sline in lines:
121                items = sline.split('z')
122                gid = int(items[0])
123                if beg:
124                    baseList.append(gid)
125                    beg = False
126                alts.append(gid)
127                itemList.append(gid)
128                superList.append(getMatVec(items[7]))
129                SPGPs.append(getSpGrp(items[4]))
130                MVs.append([getMatVec(items[5]),getMatVec(items[6])])
131            altList.append(alts)
132            for sline in lines[1:]:
133                altList.append([])
134        else:
135            items = line.split('z')
136            gid = int(items[0])
137            altList.append([gid,])
138            baseList.append(gid)
139            itemList.append(gid)
140            superList.append(getMatVec(items[7]))
141            SPGPs.append(getSpGrp(items[4]))
142            MVs.append([getMatVec(items[5]),getMatVec(items[6])])
143    result = list(zip(SPGPs,MVs,itemList,altList,superList))
144    return result,baseList
145
146def GetNonStdSubgroupsmag(SGData, kvec,star=False,landau=False,maximal=False):
147    '''Run Bilboa's k-Subgroupsmag for a non-standard space group.
148    This requires doing a post to the Bilboa site, which returns all
149    magnetic subgroups of the entered subgroup as the text of a web page
150    with a table containing the BNS magnetic space group symbol, the
151    transformation matrix and index for each subgroup.
152
153    :params list kvec: propogation vector as a list of three numbers
154    :params SGData: space group object (see :ref:`Space Group object<SGData_table>`)
155
156    :returns: (error,text) error: if True no error or False; where
157      text containts a possible web page text
158    '''
159    print('''
160    For use of k-SUBGROUPSMAG, please cite:
161      Symmetry-Based Computational Tools for Magnetic Crystallography,
162      J.M. Perez-Mato, S.V. Gallego, E.S. Tasci, L. Elcoro, G. de la Flor, and M.I. Aroyo
163      Annu. Rev. Mater. Res. 2015. 45,217-48.
164      doi: 10.1146/annurev-matsci-070214-021008
165    ''')
166
167    def getSpGrp(item):
168        return item.replace('<i>','').replace('</i>','').replace('<sub>','').replace('</sub>','')
169   
170    def getBNS(item):
171        spgrp = getSpGrp(item)
172        bns = ''
173        sid = item.find('<sub>')
174        if sid == 8:
175            bns = spgrp[1]
176            spgrp = '%s_%s %s'%(spgrp[0],bns,spgrp[2:])
177        return spgrp,bns
178   
179    def getMatVec(item):
180        return item.replace('{','[').replace('}',']')
181               
182    starmag = 'no'
183    if star:
184        starmag = 'yes'
185    land = 'no'
186    if landau:
187        land = 'yes'
188    celtodas = 'no'
189    limite = 'spgroup'
190    if maximal:
191        limite = 'maximal'
192    postdict = {'centrosymmetry':'0','crystalsystem':'0','landau':land,
193               'eleccion':'subgrmag1_k','inicio':'nostandard','celtodas':celtodas,
194               'limite':limite,'list':'Submit','listado':'lista','starmagnetica':starmag,
195               'pointgroup':'0','polarity':'0','sub':'1.1',
196               'super':'','tipog':'gmag','wyckoffstrain':''}
197    text,table = G2spc.SGPrint(SGData)
198    OpList = G2spc.TextOps(text,table,reverse=True)
199#    OpList = G2spc.TextGen(SGData,reverse=True)
200    for item in OpList:
201        item += '\n'
202    sym = ""
203    for i in OpList:
204        if sym: sym += '\n'
205        #if sym: sym += ' ' # use this for testing to generate an error in place of previous
206        sym += i.lower()
207    postdict['generators'] = sym
208    for j in [1,2,3]:
209        if kvec[3*j-3] == ' ':
210            break
211        for i,k in zip(('x','y','z'),kvec[3*j-3:3*j]):
212            postdict['km%d%s'%(j,i)] = k
213    try:
214        r = requests.get(submagSite,params=postdict)
215    except:     #ConnectionError?
216        page = ''
217        print('connection error - not on internet')
218        return None,None
219    if r.status_code == 200:
220        print('request OK')
221        page = r.text
222        page = page.replace('<font style= "text-decoration: overline;">','<font>-')
223    else:
224        page = ''
225        print('request failed. Reason=',r.reason)
226        return None,None
227    r.close()
228
229    result = page.replace('&','\n')
230    result = result.split('\n')
231    start = 0
232    for line in result:    #work around bug report from Bilbao
233        start += 1
234        if 'yesz' in line:
235            break
236    SPGPs = []
237    BNSs = []
238    MVs = []
239    baseList = []
240    itemList = []
241    superList = []
242    altList = []
243    for line in result[start:]:
244        if 'GGG' in line:
245            lines = line.split('GGG')
246            alts = []
247            beg = True
248            for sline in lines:
249                items = sline.split('z')
250                gid = int(items[0])
251                if beg:
252                    baseList.append(gid)
253                    beg = False
254                alts.append(gid)
255                itemList.append(gid)
256                superList.append(getMatVec(items[7]))
257                spgrp,bns = getBNS(items[4])
258                SPGPs.append(spgrp)
259                BNSs.append(bns)
260                MVs.append([getMatVec(items[5]),getMatVec(items[6])])
261            altList.append(alts)
262            for sline in lines[1:]:
263                altList.append([])
264        else:
265            items = line.split('z')
266            gid = int(items[0])
267            altList.append([gid,])
268            baseList.append(gid)
269            itemList.append(gid)
270            superList.append(getMatVec(items[7]))
271            spgrp,bns = getBNS(items[4])
272            SPGPs.append(spgrp)
273            BNSs.append(bns)
274            MVs.append([getMatVec(items[5]),getMatVec(items[6])])
275    result = list(zip(SPGPs,BNSs,MVs,itemList,altList,superList))
276    return result,baseList
277
278def subBilbaoCheckLattice(spgNum,cell,tol=5):
279    '''submit a unit cell to  Bilbao PseudoLattice
280    '''
281    psSite = "http://www.cryst.ehu.es/cgi-bin/cryst/programs/pseudosym/nph-pseudolattice"
282    cellstr = '+'.join(['{:.5f}'.format(i) for i in cell])
283    datastr = "sgr={:}&cell={:}&tol={:}&submit=Show".format(
284        str(int(spgNum)),cellstr,str(int(tol)))
285    try:
286        r = requests.get(psSite,params=datastr)
287    except:     #ConnectionError?
288        page = ''
289        print('connection error - not on internet')
290        return None
291    if r.status_code == 200:
292        print('request OK')
293        page = r.text
294        page = page.replace('<font style= "text-decoration: overline;">','<font>-')
295    else:
296        page = ''
297        print('request failed. Reason=',r.reason)
298        return None
299    r.close()
300    return page
301
302def parseBilbaoCheckLattice(page):
303    '''find the cell options from the web page returned by Bilbao PseudoLattice
304    '''
305    cellopts = [i for i in page.split('<tr>') if '<td><pre>' in i]
306    found = []
307    for c in cellopts:
308        cells = c.split("pre")[1].split('<')[0].replace('>','').split('\n') # list of cells, 1st is approx
309        try:
310            acell = [float(i) for i in cells[0].split()]
311            xmatA = [c.split('[')[i].split(']')[0].split() for i in (1,2,3)]
312            xmat =  np.array([[eval(i) for i in j] for j in xmatA])
313            cellmat = nl.inv(xmat).T
314        except:
315            print('Error processing cell in',c)
316            continue
317        found.append((acell,cellmat))
318    return found
319
320
321def test():
322    SGData = G2spc.SpcGroup('f d -3 m')[1]
323   
324    print('test SUBGROUPSMAG')           
325    results,baseList = GetNonStdSubgroupsmag(SGData,('0','0','0',' ',' ',' ',' ',' ',' ',' '))
326    print(results)
327    if results:
328        for [spgp,bns,mv,gid,altList,supList] in results:
329            if gid in baseList:
330                print('Space group: %d %s BNS: %s'%(gid,spgp,bns))
331                print('MV',mv)
332                print('altList:',altList)
333                print('superList: ',supList)
334               
335    print('test SUBGROUPS')
336    results,baseList = GetNonStdSubgroups(SGData,('1/3','1/3','1/2',' ',' ',' ',' ',' ',' ',' '))
337    print(results)
338    if results:
339        for [spgp,mv,gid,altList,supList] in results:
340            if gid in baseList:
341                print('Space group: %d %s'%(gid,spgp))
342                print('MV',mv)
343                print('altList:',altList)
344                print('superList: ',supList)
345               
346       
347
348if __name__ == '__main__':
349    # run self-tests
350    selftestquiet = False
351    test()
352    print ("OK")
Note: See TracBrowser for help on using the repository browser.