11
22import os , sys
3- import random
43
54import ujson as json
65
109from cif_utils import cif_to_ase , ase_to_eq_cif
1110from prediction import prop_models , get_prediction , get_aligned_descriptor , get_ordered_descriptor , get_legend , load_ml_models
1211from common import SERVE_UI , ML_MODELS , connect_database
13-
1412from knn_sample import knn_sample
15- from local_mpds import materialize , score
13+ from similar_els import materialize , score
14+ from prediction_ranges import TOL_QUALITY
1615
1716
1817app_labs = Blueprint ('app_labs' , __name__ )
@@ -45,22 +44,42 @@ def html_formula(string):
4544
4645if SERVE_UI :
4746 @app_labs .route ('/' , methods = ['GET' ])
47+ @app_labs .route ('/props.html' , methods = ['GET' ])
4848 def index ():
49- return send_from_directory (static_path , 'index.html' )
50- @app_labs .route ('/index.css' , methods = ['GET' ])
51- def style ():
52- return send_from_directory (static_path , 'index.css' )
49+ return send_from_directory (static_path , 'props.html' )
50+
51+ @app_labs .route ('/common.css' , methods = ['GET' ])
52+ def css ():
53+ return send_from_directory (static_path , 'common.css' )
54+
5355 @app_labs .route ('/player.html' , methods = ['GET' ])
5456 def player ():
5557 return send_from_directory (static_path , 'player.html' )
5658
59+ @app_labs .route ('/design.html' , methods = ['GET' ])
60+ def md ():
61+ return send_from_directory (static_path , 'design.html' )
62+
63+ @app_labs .route ('/jquery.min.js' , methods = ['GET' ])
64+ def jquery ():
65+ return send_from_directory (static_path , 'jquery.min.js' )
66+
67+ @app_labs .route ('/nouislider.min.js' , methods = ['GET' ])
68+ def nouislider ():
69+ return send_from_directory (static_path , 'nouislider.min.js' )
70+
5771@app_labs .after_request
5872def add_cors_header (response ):
5973 response .headers ['Access-Control-Allow-Origin' ] = '*'
6074 return response
6175
6276@app_labs .route ("/predict" , methods = ['POST' ])
6377def predict ():
78+ """
79+ A main endpoint for the properties
80+ prediction, based on the provided CIF
81+ or POSCAR
82+ """
6483 if 'structure' not in request .values :
6584 return fmt_msg ('Invalid request' )
6685
@@ -122,19 +141,30 @@ def predict():
122141
123142@app_labs .route ("/download_cif" , methods = ['POST' ])
124143def download_cif ():
125- if 'structure' not in request .values :
144+ """
145+ An utility endpoint to force
146+ a browser file (CIF) download
147+ """
148+ structure = request .values .get ('structure' )
149+ title = request .values .get ('title' )
150+
151+ if not structure or not title :
126152 return fmt_msg ('Invalid request' )
127153
128- structure = request .values .get ('structure' )
129- if not 0 < len (structure ) < 32768 :
154+ if not 0 < len (structure ) < 100000 :
130155 return fmt_msg ('Request size is invalid' )
131156
132157 return Response (structure , mimetype = "chemical/x-cif" , headers = {
133- "Content-Disposition" : "attachment;filename=%s.cif" % random . randint ( 10000 , 99999 )
158+ "Content-Disposition" : "attachment;filename=%s.cif" % title
134159 })
135160
136161@app_labs .route ("/design" , methods = ['POST' ])
137162def design ():
163+ """
164+ A main endpoint for generating
165+ the CIF structure based on
166+ the provided values of the properties
167+ """
138168 if 'numerics' not in request .values :
139169 return fmt_msg ('Invalid request' )
140170
@@ -144,31 +174,31 @@ def design():
144174 if type (numerics ) != dict :
145175 return fmt_msg ('Invalid request' )
146176
147- prop_ranges_dict = {}
177+ user_ranges_dict = {}
148178
149179 for prop_id in prop_models :
150180 if prop_id not in numerics or type (numerics [prop_id ]) != list or len (numerics [prop_id ]) != 2 :
151181 return fmt_msg ('Invalid request' )
152- try : prop_ranges_dict [prop_id + '_min' ], prop_ranges_dict [prop_id + '_max' ] = float (numerics [prop_id ][0 ]), float (numerics [prop_id ][1 ])
182+ try : user_ranges_dict [prop_id + '_min' ], user_ranges_dict [prop_id + '_max' ] = float (numerics [prop_id ][0 ]), float (numerics [prop_id ][1 ])
153183 except :
154184 return fmt_msg ('Invalid request' )
155185
156- if prop_ranges_dict ['w_min' ] == 0 and prop_ranges_dict ['w_max' ] == 0 :
157- prop_ranges_dict ['w_min' ], prop_ranges_dict ['w_max' ] = - 100 , 100 # NB. any band gap is allowed
186+ if user_ranges_dict ['w_min' ] == 0 and user_ranges_dict ['w_max' ] == 0 :
187+ user_ranges_dict ['w_min' ], user_ranges_dict ['w_max' ] = - 100 , 100 # NB. any band gap is allowed
158188
159189 cursor , connection = connect_database ()
160190
161191 result , error = None , "No results (outside of prediction capabilities)"
162192
163- els_samples = knn_sample (cursor , prop_ranges_dict )
193+ els_samples = knn_sample (cursor , user_ranges_dict )
164194 for els_sample in els_samples :
165195 #print "TRYING TO MATERIALIZE", ", ".join(els_sample)
166196
167- scoring , error = materialize (cursor , els_sample , active_ml_models )
197+ scoring , error = materialize (els_sample , active_ml_models )
168198 if error or not scoring :
169199 continue
170200
171- result = score (scoring , prop_ranges_dict )
201+ result = score (scoring , user_ranges_dict )
172202 break
173203
174204 connection .close ()
@@ -182,11 +212,31 @@ def design():
182212 if error : return fmt_msg (error )
183213 result ['structure' ].center (about = 0.0 )
184214
215+ formula = get_formula (result ['structure' ])
216+
217+ result_quality , aux_info = 0 , []
218+ for k , v in answer_props .items ():
219+ aux_info .append ([
220+ prop_models [k ]['name' ].replace (' ' , '_' ),
221+ sample [k + '_min' ],
222+ v ,
223+ sample [k + '_max' ],
224+ prop_models [k ]['units' ]
225+ ])
226+ tol = (sample [k + '_max' ] - sample [k + '_min' ]) * TOL_QUALITY
227+ if sample [k + '_min' ] - tol < v < sample [k + '_max' ] + tol :
228+ result_quality += 1
229+
185230 return Response (
186231 json .dumps ({
187- 'vis_cif' : ase_to_eq_cif (result ['structure' ], supply_sg = False ),
232+ 'vis_cif' : ase_to_eq_cif (
233+ result ['structure' ],
234+ supply_sg = False ,
235+ mpds_labs_loop = [result_quality ] + aux_info
236+ ),
188237 'props' : answer_props ,
189- 'formula' : html_formula (get_formula (result ['structure' ])),
238+ 'formula' : html_formula (formula ),
239+ 'title' : formula
190240 }, indent = 4 , escape_forward_slashes = False
191241 ),
192242 content_type = 'application/json'
0 commit comments