1 | # -*- coding: utf-8 -*- |
---|
2 | """ |
---|
3 | *kSUBGROUPSMAG: Interface to Bilbao k-SUBGROUPSMAG web page* |
---|
4 | ------------------------------- |
---|
5 | |
---|
6 | Extraction of magnetic space groups for a given space group and a propagation vector |
---|
7 | from the k-SUBGROUPSMAG web page on the Bilbao Crystallographic server |
---|
8 | |
---|
9 | """ |
---|
10 | ########### SVN repository information ################### |
---|
11 | # $Date: 2018-07-10 11:41:00 -0500 (Tue, 10 Jul 2018) $ |
---|
12 | # $Author: vondreele $ |
---|
13 | # $Revision: 3465 $ |
---|
14 | # $URL: https://subversion.xray.aps.anl.gov/pyGSAS/trunk/kSUBGROUPSMAG.py $ |
---|
15 | # $Id: kSUBGROUPSMAG.py 3465 2018-07-10 16:41:00Z vondreele $ |
---|
16 | ########### SVN repository information ################### |
---|
17 | from __future__ import division, print_function |
---|
18 | import requests |
---|
19 | try: |
---|
20 | import HTMLParser as HTML |
---|
21 | except ImportError: |
---|
22 | import html.parser as HTML # Python 3 |
---|
23 | import GSASIIspc as G2spc |
---|
24 | import GSASIIpath |
---|
25 | GSASIIpath.SetBinaryPath() |
---|
26 | submagSite = 'http://www.cryst.ehu.es/cgi-bin/cryst/programs/subgrmag1_general.pl' |
---|
27 | |
---|
28 | class TableParser(HTML.HTMLParser): |
---|
29 | def __init__(self): |
---|
30 | HTML.HTMLParser.__init__(self) |
---|
31 | self.spgp = '' |
---|
32 | self.in_sp = False |
---|
33 | self.in_pre = False |
---|
34 | self.in_sub = False |
---|
35 | self.MV = '' |
---|
36 | self.BNS = '' |
---|
37 | self.beg = False |
---|
38 | self.SPGPs = [] |
---|
39 | self.MVs = [] |
---|
40 | self.BNSs = [] |
---|
41 | |
---|
42 | def handle_starttag(self, tag, attrs): |
---|
43 | # print('tag:',tag,self.beg,self.in_sp) |
---|
44 | if tag == 'i' and self.beg: |
---|
45 | if not self.in_sp: |
---|
46 | self.in_sp = True |
---|
47 | self.spgp = '' |
---|
48 | self.BNS = '' |
---|
49 | elif tag == 'pre': |
---|
50 | self.in_pre = True |
---|
51 | self.MV = '' |
---|
52 | elif tag == 'sub': |
---|
53 | self.in_sub = True |
---|
54 | |
---|
55 | def handle_data(self, data): |
---|
56 | if self.in_sp: |
---|
57 | # print('*',data) |
---|
58 | if 'No.' in data: |
---|
59 | self.spgp += data.split('(')[0] #pick up trailing number! |
---|
60 | self.in_sp = False |
---|
61 | self.SPGPs.append(self.spgp) |
---|
62 | self.BNSs.append(self.BNS) |
---|
63 | # print('space group:',self.spgp,' BNS: ',self.BNS) |
---|
64 | else: |
---|
65 | if self.in_sub and len(self.spgp) == 1: |
---|
66 | self.spgp += '_' |
---|
67 | self.spgp += data |
---|
68 | if len(self.spgp) == 3 and '_' in self.spgp: |
---|
69 | self.spgp += ' ' |
---|
70 | self.BNS = data |
---|
71 | if 'P_S' in self.spgp: #fix ambiguous std. symbol for triclinics |
---|
72 | self.spgp.replace('_S','_c') |
---|
73 | self.BNS = 'c' |
---|
74 | # print(self.spgp,self.BNS) |
---|
75 | if self.in_pre: |
---|
76 | self.MV = data |
---|
77 | |
---|
78 | def handle_endtag(self, tag): |
---|
79 | # print (' end tag: %s'%(tag)) |
---|
80 | if tag == 'script': |
---|
81 | self.beg = True |
---|
82 | elif tag == 'pre': |
---|
83 | self.in_pre = False |
---|
84 | self.MVs.append(self.MV.replace('\n',' ')) |
---|
85 | # print('MV:') |
---|
86 | # print(self.MV) |
---|
87 | elif tag == 'sub': |
---|
88 | self.in_sub = False |
---|
89 | |
---|
90 | def GetNonStdSubgroupsmag(SGData, kvec,star=False,landau=False,intermed=False): |
---|
91 | '''Run Bilboa's k-Subgroupsmag for a non-standard space group. |
---|
92 | This requires doing a post to the Bilboa site, which returns all |
---|
93 | magnetic subgroups of the entered subgroup as the text of a web page |
---|
94 | with a table containing the BNS magnetic space group symbol, the |
---|
95 | transformation matrix and index for each subgroup. |
---|
96 | |
---|
97 | :params list kvec: propogation vector as a list of three numbers |
---|
98 | :params SGData: space group object (see :ref:`Space Group object<SGData_table>`) |
---|
99 | |
---|
100 | :returns: (error,text) error: if True no error or False; where |
---|
101 | text containts a possible web page text |
---|
102 | ''' |
---|
103 | print(''' |
---|
104 | For use of k-SUBGROUPSMAG, please cite: |
---|
105 | Symmetry-Based Computational Tools for Magnetic Crystallography, |
---|
106 | J.M. Perez-Mato, S.V. Gallego, E.S. Tasci, L. Elcoro, G. de la Flor, and M.I. Aroyo |
---|
107 | Annu. Rev. Mater. Res. 2015. 45,217-48. |
---|
108 | doi: 10.1146/annurev-matsci-070214-021008 |
---|
109 | ''') |
---|
110 | starmag = 'no' |
---|
111 | if star: |
---|
112 | starmag = 'yes' |
---|
113 | land = 'no' |
---|
114 | if landau: |
---|
115 | land = 'yes' |
---|
116 | celtodas = 'no' |
---|
117 | if intermed: |
---|
118 | celtodas = 'yes' |
---|
119 | postdict = {'centrosymmetry':'0','crystalsystem':'0','landau':land, |
---|
120 | 'eleccion':'subgrmag1_k','inicio':'nostandard','celtodas':celtodas, |
---|
121 | 'limite':'spgroup','list':'Submit','listado':'lista','starmagnetica':starmag, |
---|
122 | 'pointgroup':'0','polarity':'0','sub':'1.1', |
---|
123 | 'super':'','tipog':'gmag','wyckoffstrain':''} |
---|
124 | text,table = G2spc.SGPrint(SGData) |
---|
125 | OpList = G2spc.TextOps(text,table,reverse=True) |
---|
126 | # GenList = G2spc.TextGen(SGData,reverse=True) |
---|
127 | for item in OpList: |
---|
128 | item += '\n' |
---|
129 | sym = "" |
---|
130 | for i in OpList: |
---|
131 | if sym: sym += '\n' |
---|
132 | #if sym: sym += ' ' # use this for testing to generate an error in place of previous |
---|
133 | sym += i.lower() |
---|
134 | postdict['generators'] = sym |
---|
135 | for j in [1,2,3]: |
---|
136 | if kvec[3*j-3] == ' ': |
---|
137 | break |
---|
138 | for i,k in zip(('x','y','z'),kvec[3*j-3:3*j]): |
---|
139 | postdict['km%d%s'%(j,i)] = k |
---|
140 | try: |
---|
141 | r = requests.post(submagSite,postdict) |
---|
142 | except: #ConnectionError? |
---|
143 | page = '' |
---|
144 | print('connection error - not on internet') |
---|
145 | return None |
---|
146 | if r.status_code == 200: |
---|
147 | print('request OK') |
---|
148 | page = r.text |
---|
149 | page = page.replace('<font style= "text-decoration: overline;">','<font>-') |
---|
150 | else: |
---|
151 | page = '' |
---|
152 | print('request failed. Reason=',r.reason) |
---|
153 | return None |
---|
154 | r.close() |
---|
155 | |
---|
156 | p = TableParser() |
---|
157 | p.feed(page) |
---|
158 | result = list(zip(p.SPGPs,p.BNSs,p.MVs)) |
---|
159 | return result |
---|
160 | |
---|
161 | def test(): |
---|
162 | SGData = G2spc.SpcGroup('p -3 m 1')[1] |
---|
163 | results = GetNonStdSubgroupsmag(SGData,('1/3','1/3','1/2')) |
---|
164 | if results: |
---|
165 | for spgp,bns,mv in results: |
---|
166 | print('Space group:',spgp, 'BNS:',bns) |
---|
167 | print('MV') |
---|
168 | print(mv) |
---|
169 | |
---|
170 | |
---|
171 | if __name__ == '__main__': |
---|
172 | # run self-tests |
---|
173 | selftestquiet = False |
---|
174 | test() |
---|
175 | print ("OK") |
---|