def test_get_reps(self): """ Testing the get view/reps """ transpiler = PyMolTranspiler().transpile(file='test/1ubq.pse') v = transpiler.get_view() r = transpiler.get_reps() #print(v) self.assertTrue(len(v) > 0) #print(r) self.assertTrue(len(r) > 0)
def get_offset_coordinates(self, sequence: Optional[str] = None): """ Gets the coordinates and offsets them. :return: """ if not self.chain_definitions: self.lookup_sifts() self.coordinates = PyMolTranspiler().renumber( self.get_coordinates(), self.chain_definitions, sequence=sequence, make_A=self.chain, remove_solvent=True).raw_pdb if self.chain != 'A': ## fix this horror. for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == 'A': self.chain_definitions[i]['chain'] = 'XXX' break for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == self.chain: self.chain_definitions[i]['chain'] = 'A' break for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == 'XXX': self.chain_definitions[i]['chain'] = self.chain break # just om case there is a double trip! (Non server usage) self.chain = 'A' self.offset = 0 for i, c in enumerate(self.chain_definitions): if c['chain'] == 'A': self.chain_definitions[i]['offset'] = 0 return self.coordinates
def convert_mesh(request): log.info(f'Mesh conversion requested by {User.get_username(request)}') if 'demo_filename' in request.params: filename = demo_file(request) # prevention against attacks fh = open(filename) else: request.params['file'].file.seek(0) fh = io.StringIO(request.params['file'].file.read().decode("utf8"), newline=None) if 'scale' in request.params: scale = float(request.params['scale']) else: scale = 0 if 'centroid' in request.params and request.params['centroid'] in ( 'unaltered', 'origin', 'center'): centroid_mode = request.params['centroid'] else: centroid_mode = 'unaltered' if 'origin' in request.params and request.params['centroid'] == 'origin': origin = request.params['origin'].split(',') else: origin = None try: mesh = PyMolTranspiler.convert_mesh(fh, scale, centroid_mode, origin) return {'mesh': mesh} except Exception as error: return { 'status': 'error', 'msg': f'{error.__class__.__name__}: {error}. (Most errors are because the mesh is not triangulated: hover over file input for more).' }
def test_transpile2(self): """ Tests the pse transpiler """ settings = {'viewport': 'viewport', 'image': None, 'uniform_non_carbon': True, 'verbose': False, 'validation': True, 'stick_format': 'sym_licorice', 'save': True, 'backgroundcolor': 'white', 'location_viewport': 'left', 'columns_viewport': 9, 'columns_text': 3} PyMolTranspiler().transpile(file='../app/michelanglo_app/demo/F.pse', **settings)
def test_new_template(): #transpiler = PyMolTranspiler(file='git_docs/images/1ubq.pse') transpiler = PyMolTranspiler().transpile(file='test/1ubq.pse') transpiler.pdb = '1UBQ' transpiler.m4_alt = None code=transpiler.get_js(toggle_fx=True, viewport='viewport', variants=[], save_button='save_button', backgroundColor='white',tag_wrapped=True) transpiler.write_hmtl(template_file='test2.mako', output_file='example.html', code=code)
def save_coordinates(request, mod_fx=None): """ Saves the request['pdb'] file. Does not accept str. """ extension = request.params['pdb'].filename.split('.')[-1] if extension not in valid_extensions: log.warning( f'Odd format in pdb upload: {extension} {valid_extensions}') extension = 'pdb' filename = save_file(request, extension, field='pdb') trans = PyMolTranspiler().load_pdb(file=filename, mod_fx=mod_fx) os.remove(filename) if extension != 'pdb': os.remove(filename.replace(extension, 'pdb')) return trans
def test_pymol_output(): raise DeprecationWarning transpiler = PyMolTranspiler(verbose=True, validation=False) transpiler.pdb = '1UBQ' view = '' reps = '' data = open(os.path.join('michelanglo_app','static','pymol_demo.txt')).read().split('PyMOL>') for block in data: if 'get_view' in block: view = block elif 'iterate' in block: # strickly lowercase as it ends in *I*terate reps = block elif not block: pass #empty line. else: warn('Unknown block: '+block) transpiler.convert_view(view) transpiler.convert_representation(reps) code = transpiler.get_html(tabbed=0) # ngl='ngl.js' return transpiler
def removal(request): malformed = is_malformed(request, 'pdb', 'chains') if malformed: return {'status': malformed} ## variant of mutate... pdb = get_pdb_block(request) definitions = get_chain_definitions(request) history = get_history(request) history['changes'] += f'Chains removed. ' chains = request.params['chains'].split() trans = PyMolTranspiler().chain_removal_block(block=pdb, chains=chains) for i in reversed(range(len(definitions))): if definitions[i]['chain'] in chains: definitions.pop(i) return { 'pdb': trans.pdb_block, 'definitions': definitions, 'history': history }
def renumber(request): malformed = is_malformed(request, 'pdb') if malformed: return {'status': malformed} pdb = get_pdb_block(request) definitions = get_chain_definitions(request) history = get_history(request) trans = PyMolTranspiler().renumber(pdb, definitions) for current_chain_def in definitions: current_chain_def['applied_offset'] = current_chain_def['offset'] #current_chain_def['x'] += current_chain_def['offset'] #current_chain_def['y'] += current_chain_def['offset'] #current_chain_def['range'] = f"{current_chain_def['x']}-{current_chain_def['y']}" current_chain_def['offset'] = 0 history['changes'] += 'Renamed. ' return { 'pdb': trans.pdb_block, 'definitions': definitions, 'history': history }
def get_offset_coordinates(self): """ Gets the coordinates and offsets them. :return: """ if not self.chain_definitions: self.lookup_sifts() self.coordinates = PyMolTranspiler().renumber(self.get_coordinates(), self.chain_definitions, make_A=self.chain).raw_pdb if self.chain != 'A': ### fix this horror. for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == 'A': self.chain_definitions[i]['chain'] = 'XXX' break for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == self.chain: self.chain_definitions[i]['chain'] = 'A' break for i, c in enumerate(self.chain_definitions): if self.chain_definitions[i]['chain'] == 'XXX': self.chain_definitions[i]['chain'] = self.chain break return self.coordinates
def premutate(request): malformed = is_malformed(request, 'pdb', 'mutations', 'chain', 'format') if malformed: return {'status': malformed} ## variant of mutate... pdb = get_pdb_block(request) definitions = get_chain_definitions(request) history = get_history(request) history['changes'] += f'Mutated. ' if 'chain' in request.params: chain = request.params['chain'] chains = None elif 'chain[]' in request.params: chain = None chains = request.params.getall('chain[]') else: raise ValueError if 'mutations' in request.params: mutations = request.params['mutations'].split() elif 'mutations[]' in request.params: mutations = request.params.getall('mutations[]') else: raise ValueError try: trans = PyMolTranspiler().mutate_block(block=pdb, mutations=mutations, chain=chain, chains=chains) return { 'pdb': trans.pdb_block, 'definitions': definitions, 'history': history } except ValueError: request.response.status = 422 return {'status': f'Invalid mutations'}
def convert_mesh(request): log.info(f'Mesh conversion requested by {User.get_username(request)}') if 'demo_file' in request.params: filename = demo_file(request) # prevention against attacks fh = open(filename) else: request.params['file'].file.seek(0) fh = io.StringIO(request.params['file'].file.read().decode("utf8"), newline=None) if 'scale' in request.params: scale = float(request.params['scale']) else: scale = 0 if 'centroid' in request.params and request.params['centroid'] in ( 'unaltered', 'origin', 'center'): centroid_mode = request.params['centroid'] else: centroid_mode = 'unaltered' if 'origin' in request.params and request.params['centroid'] == 'origin': origin = request.params['origin'].split(',') else: origin = None mesh = PyMolTranspiler.convert_mesh(fh, scale, centroid_mode, origin) return {'mesh': mesh}
def get_pdb_block_from_request(request): if isinstance(request.params['pdb'], str): # string text = request.params['pdb'] ## see if it's mmCIF if 'format' in request.params: if request.params['format'].lower() == 'pdb': return get_pdb_block_from_str(text) elif request.params['format'].lower() not in valid_extensions: log.warning( f'Odd format in pdb upload: {request.params["format"]} {valid_extensions}' ) return get_pdb_block_from_str(text) else: ## mmCIF save_file is abivalent to file or str filename = save_file(request, request.params['format'].lower(), field='pdb') return PyMolTranspiler().load_pdb(file=filename).pdb_block else: return get_pdb_block_from_str(text) elif hasattr(request.params['pdb'], "filename"): # file return save_coordinates( request).pdb_block # has its own check to deal with mmCIF. else: raise TypeError
def test_transpile(self): """ Tests the pse transpiler """ transpiler = PyMolTranspiler().transpile(file='test/1ubq.pse') transpiler.raw_pdb
def mutate(request): #''page', 'key'?, 'chain', 'mutations' # inplace is a value that does not appear on the site. It is an API only route. # inplace actually fails if the structure is a PDB code. malformed = is_malformed(request, 'page', 'model', 'chain', 'mutations', 'name') if malformed: return {'status': malformed} page = Page.select(request, request.params['page']) log.info(f'{User.get_username(request)} is making mutants page {page}') user = request.user verdict = permission(request, page, 'del', key_label='encryption_key') if verdict['status'] != 'OK': return verdict else: try: settings = page.settings model = int(request.params['model']) chain = request.params['chain'] mutations = request.params['mutations'].split() all_protein_data = json.loads(settings['proteinJSON']) protein_data = all_protein_data[model] filename = os.path.join('michelanglo_app', 'temp', f'{page.identifier}.mut.pdb') if protein_data['type'] == 'data': if protein_data['isVariable'] is True or protein_data[ 'isVariable'] == 'true': # if is variable is true the pdb block is in settings pdb. # Legacy pages have been update, so there are no settings['pdb']:str name = protein_data['value'] pdb_block = dict(settings['pdb'])[name] else: pdb_block = protein_data['value'] else: pdb_block = get_pdb_block(protein_data['value']) ## covert trans = PyMolTranspiler().mutate_block(block=pdb_block, chain=chain, mutations=mutations) new_block = trans.pdb_block #return {'status': 'Cannot create mutations from URL for security reasons. Please download the PDB file and upload it or ask the site admin to whitelist the URL.'} new_variable = sanitise_name(request.params['name'], f"mutant_{len(all_protein_data)}", all_protein_data) if 'inplace' in request.params and is_js_true( request.params['inplace']): all_protein_data[model] = { **all_protein_data[model], "type": "data", "value": new_variable, "isVariable": "true" } settings['proteinJSON'] = json.dumps(all_protein_data) settings['pdb'][model] = (new_variable, new_block) else: all_protein_data.append({ "type": "data", "value": new_variable, "history": "mutagenesis", "isVariable": "true" }) if 'chain_definitions' in all_protein_data[model]: all_protein_data[-1][ 'chain_definitions'] = all_protein_data[model][ 'chain_definitions'] settings['proteinJSON'] = json.dumps(all_protein_data) settings['pdb'].append((new_variable, new_block)) new_model = len(all_protein_data) - 1 settings[ 'description'] += f'\n\nProtein variants generated for model #{model} ({all_protein_data[model]["value"] if "value" in all_protein_data[model] else "no name given"}) as model #{new_model} ({new_variable}).\n\n' common = '<span class="prolink" data-toggle="protein" data-hetero="true"' for mutant in mutations: n = re.search("(\d+)", mutant).group(1) settings['description'] += f'* __{mutant}__ '+\ f'({common} data-focus="residue" data-title="{mutant} wild type" data-load="{model} " data-selection="{n}:{chain}">wild type</span>'+\ f'/{common} data-focus="clash" data-title="{mutant} mutant" data-load="{new_model} " data-selection="{n}:{chain}">mutant</span>)\n' settings['descr_mdowned'] = markdown.markdown( settings['description']) page.save(settings) return {'status': 'success'} except ValueError: request.response.status = 422 return {'status': 'Invalid mutation!'}
def __init__(self, structure: Structure, mutation: Mutation, sequence: Optional[str] = None): """ :param structure: a instance of Structure, a former namedtuple and is in core.py :param mutation: a instance of mutation. """ self.mutation = mutation self.position = mutation.residue_index self.structure = structure self.model = None self.chain = 'A' #structure.chain get offset will change the chain to A. self.code = structure.code if self.structure.coordinates: self.coordinates = self.structure.coordinates elif len(self.code) == 4: self.coordinates = structure.get_offset_coordinates() else: self.structure.type = 'swissmodel' if self.structure.chain: chain = self.structure.chain else: # retrieve from Swissmodel does not have template in description # (see Structure.from_swissmodel_query) # but the old pregen stuff did! chain = re.match('\w{4}\.\w+\.(\w)', structure.description).group(1) pdbblock = structure.get_coordinates() self.coordinates = PyMolTranspiler().renumber(pdb=pdbblock, definitions=structure.chain_definitions, make_A=chain, sequence=sequence ).raw_pdb assert self.coordinates, 'There are no coordinates!!' # these two are very much for the ajax. self.chain_definitions = structure.chain_definitions # seems redundant but str(structure) does not give these. self.history = {'code': self.code, 'changes': 'offset and made chain A'}, # do operations on structure self.target_selection = f'(resi {self.position} and chain {self.chain})' self.pymol = None self._obj_name = 'myprotein' with pymol2.PyMOL() as self.pymol: self.pymol.cmd.read_pdbstr(self.coordinates, self._obj_name) self.N_atoms = self.pymol.cmd.select(self.target_selection) # --- verify okay if self.N_atoms == 0: raise ValueError('Residue is in missing density') elif self.N_atoms == 1: raise ValueError('Structure is likely an Calpha trace') # --- analyses self.has_all_heavy_atoms = self.N_atoms >= self.normal_HA[self.mutation.from_residue] self.pymol.cmd.h_add() self.neighbours = self.get_neighbours() self.SASA = self.get_SASA() if self.mutation.from_residue != 'G': self.SASA_sidechain = self.get_SASA(f'{self.target_selection} and not name N+H+C+CA+HA+O+OXT') else: self.SASA_sidechain = self.get_SASA(f'{self.target_selection} and name CA') self.RSA = self.SASA / self.maxASA[self.mutation.from_residue] self.SS = self.get_SS() self.buried = self.RSA <= 0.2 self.ligand_list = self.get_ligand_list() t = self.get_distance_to_closest_ligand() self.closest_ligand = t['closest'] self.distance_to_closest_ligand = t['distance'] self.pymol = None
def with_sdf(request): malformed = is_malformed(request, 'apo') if malformed: return {'status': malformed} pagename = get_uuid(request) pdbfile = save_file(request, 'pdb', field='apo') ### deal with sdf sdfdex = [] for k in request.params.keys(): if k in ('apo', 'viewcode'): continue else: print('debug', k) sdffile = save_file(request, 'sdf', k) sdfdex.append({ 'name': re.sub('[^\w_]', '', k.replace(' ', '_')), 'block': PyMolTranspiler().sdf_to_pdb(sdffile, pdbfile) }) if sdfdex == []: return {'status': 'No SDF files'} loadfun = 'const ligands = ' + json.dumps(sdfdex) + ';' loadfun += ''' window.generate_ligands = () => { if (window.myData === undefined) {setTimeout(window.generate_ligands, 100); console.log('wait');} else { ligands.forEach((v,i) => { window[v.name] = apo.replace(/END\\n?/,'TER\\n') + v.block; }); } } window.generate_ligands(); ''' ligand_defs = ','.join([ f'{{"type": "data", "value": "{e["name"]}", "isVariable": true}}' for e in sdfdex ]) prolink = '* <span class="prolink" data-toggle="protein" data-load="{i}" data-selection="UNK" data-focus="residue">Ligand: {i}</span>\n' descr = 'These are the models in this page. To make your own prolinks, do note that the ligand is called "UNK" for selection purposes.\n\n.'+\ '* <span class="prolink" data-toggle="protein" data-load="apo" data-view="auto">Apo structure</span>\n'+\ ''.join([prolink.format(i=e['name']) for e in sdfdex]) ### viewcode! if 'viewcode' in request.params: viewcode = request.params['viewcode'] data_other = re.sub(r'<\w+ (.*?)>.*', r'\1', viewcode).replace('data-toggle="protein"', '')\ .replace('data-toggle=\'protein\'', '')\ .replace('data-toggle=protein', '') if not request.user or request.user.role not in ('admin', 'friend'): data_other = clean_data_other(data_other) else: data_other = '' ### settings settings = { 'data_other': data_other, 'page': pagename, 'editable': True, 'backgroundcolor': 'white', 'validation': None, 'js': None, 'pdb': [], 'loadfun': loadfun, 'proteinJSON': '[{"type": "data", "value": "apo", "isVariable": true}, ' + ligand_defs + ']', 'descriptors': { 'text': descr } } trans = PyMolTranspiler().load_pdb(file=pdbfile) os.remove(pdbfile) settings['pdb'] = [('apo', trans.pdb_block)] settings['title'] = 'User submitted structure (from uploaded PDB+SDF)' commit_submission(request, settings, pagename) return {'page': pagename}
def convert_pse(request): user = request.user log.info('Conversion of PyMol requested.') request.session['status'] = make_msg( 'Checking data', 'The data has been received and is being checked') try: malformed = is_malformed(request, 'uniform_non_carbon', 'stick_format', 'combine_objects') if malformed: return {'status': malformed} if 'demo_filename' not in request.params and 'file' not in request.params: request.response.status = 422 log.warning( f'{User.get_username(request)} malformed request due to missing demo_filename or file' ) return f'Missing field (either demo_filename or file are compulsory)' ## set settings settings = { 'viewport': 'viewport', # 'tabbed': int(request.params['indent']), 'image': None, 'uniform_non_carbon': is_js_true(request.params['uniform_non_carbon']), 'verbose': False, 'validation': True, 'stick_format': request.params['stick_format'], 'combine_objects': is_js_true(request.params['combine_objects']), 'save': True, 'async_pdb': is_js_true(request.params['combine_objects'] ), # async pdb will mess up overlays! 'backgroundcolor': 'white', 'location_viewport': 'left', 'columns_viewport': 9, 'columns_text': 3 } # parse data dependding on mode. request.session['status'] = make_msg('Conversion', 'Conversion in progress') ## case 1: user submitted output ##### mode no longer supported ## case 2: user uses pse ## case 2b: DEMO mode. if 'demo_filename' in request.params: mode = 'demo' filename = demo_file(request) # prevention against attacks ## case 2a: file mode. else: mode = 'file' malformed = is_malformed(request, 'file', 'pdb') if malformed: return {'status': malformed} filename = save_file(request, 'pse') ### GO! log.debug('About to call the transpiler!') log.debug(filename) trans = PyMolTranspiler(job=User.get_username(request)).transpile( file=filename, **settings) ### save the PDB data? if mode == 'demo' or not is_js_true(request.params['pdb']): trans.pdb = None # yes save it. else: trans.pdb = request.params['pdb'] # PDB code to use request.session['file'] = filename # deal with user permissions. code = 1 request.session['status'] = make_msg('Permissions', 'Finalising user permissions') pagename = get_uuid(request) # create output settings['title'] = 'User submitted structure (from PyMOL file)' settings['descriptors'] = trans.description # save proteinJSON protein_info = [] settings['pdb'] = [] if not trans.pdb: # PDB not provided. for name in trans.pdbblocks: settings['pdb'].append((name, trans.pdbblocks[name])) protein_info.append({ "type": "data", "value": name, "isVariable": True, "loadFx": f"load{name}" }) elif len(trans.pdb) == 4: settings['descriptors']['ref'] = get_references(trans.pdb) for name in trans.pdbblocks: protein_info.append({ "type": "rcsb", "value": trans.pdb, "loadFx": f"load{name}", 'history': 'from PyMOL', "chain_definitions": get_chain_definitions(request) }) # there should be only one! else: protein_info = [{ "type": "url", "value": trans.pdb, "loadFx": "loadfun" }] ## load fun request.session['status'] = make_msg('Load function', 'Making load function') # load fun should not be a string.... settings['loadfun'] = '\n\n' + '\n\n'.join( trans.loadfuns.values()) + '\n\n' if len(trans.pdbblocks ) == 1: # settings['combine_objects'] == True is a single model pass else: first = list(trans.pdbblocks.keys())[0] middle = '' for name in trans.loadfuns: if name == first: continue middle += f''' protein.stage.loadFile(new Blob([window['{name}'], {{type: 'text/plain'}}]), {{ext: 'pdb', firstModelOnly: true}}) .then(window['load{name}']); ''' settings[ 'loadfun'] += 'function loadfun (protein) { window["load' + first + '"](protein);' + middle + '}' protein_info[0]['loadFx'] = 'loadfun' settings['proteinJSON'] = json.dumps(protein_info) commit_submission(request, settings, pagename) # save sharable page data request.session['status'] = make_msg('Saving', 'Storing data for retrieval.') request.session['status'] = make_msg('Loading results', 'Conversion is being loaded', condition='complete', color='bg-info') return {'page': pagename} except Exception as err: log.exception(f'serious error in page creation from PyMol: {err}') request.response.status = 500 request.session['status'] = make_msg( 'A server-side error arose', 'The code failed to run serverside.', 'error', 'bg-danger') return {'status': 'error'}
def convert_pse(request): user = request.user log.info('Conversion of PyMol requested.') request.session['status'] = make_msg( 'Checking data', 'The data has been received and is being checked') try: malformed = is_malformed(request, 'uniform_non_carbon', 'stick_format') if malformed: return {'status': malformed} if 'demo_filename' not in request.params and 'file' not in request.params: request.response.status = 422 log.warning( f'{User.get_username(request)} malformed request due to missing demo_filename or file' ) return f'Missing field (either demo_filename or file are compulsory)' ## set settings settings = { 'viewport': 'viewport', # 'tabbed': int(request.params['indent']), 'image': None, 'uniform_non_carbon': is_js_true(request.params['uniform_non_carbon']), 'verbose': False, 'validation': True, 'stick_format': request.params['stick_format'], 'save': True, 'backgroundcolor': 'white', 'location_viewport': 'left', 'columns_viewport': 9, 'columns_text': 3 } # parse data dependding on mode. request.session['status'] = make_msg('Conversion', 'Conversion in progress') ## case 1: user submitted output ##### mode no longer supported ## case 2: user uses pse ## case 2b: DEMO mode. if 'demo_filename' in request.params: mode = 'demo' filename = demo_file(request) # prevention against attacks ## case 2a: file mode. else: mode = 'file' malformed = is_malformed(request, 'file', 'pdb') if malformed: return {'status': malformed} filename = save_file(request, 'pse') ### GO! log.debug('About to call the transpiler!') log.debug(filename) trans = PyMolTranspiler(job=User.get_username(request)).transpile( file=filename, **settings) ### finish up if mode == 'demo' or not is_js_true(request.params['pdb']): ## pdb_string checkbox is true means that it adds the coordinates in the JS and not pdb code is given with open( os.path.join( trans.tmp, os.path.split(filename)[1].replace('.pse', '.pdb'))) as fh: trans.raw_pdb = fh.read() else: trans.pdb = request.params['pdb'] request.session['file'] = filename # deal with user permissions. code = 1 request.session['status'] = make_msg('Permissions', 'Finalising user permissions') pagename = get_uuid(request) # create output settings['pdb'] = [] request.session['status'] = make_msg('Load function', 'Making load function') settings['loadfun'] = trans.get_loadfun_js(tag_wrapped=True, **settings) settings['descriptors'] = trans.description if trans.raw_pdb: settings[ 'proteinJSON'] = '[{"type": "data", "value": "pdb", "isVariable": true, "loadFx": "loadfun"}]' settings['pdb'] = [ ('pdb', '\n'.join(trans.ss) + '\n' + trans.raw_pdb) ] # note that this used to be a string, elif len(trans.pdb) == 4: settings['descriptors']['ref'] = get_references(trans.pdb) settings['proteinJSON'] = json.dumps([{ "type": "rcsb", "value": trans.pdb, "loadFx": "loadfun", 'history': 'from PyMOL', "chain_definitions": get_chain_definitions(request) }]) else: settings[ 'proteinJSON'] = '[{{"type": "file", "value": "{0}", "loadFx": "loadfun"}}]'.format( trans.pdb) settings['title'] = 'User submitted structure (from PyMOL file)' commit_submission(request, settings, pagename) # save sharable page data request.session['status'] = make_msg('Saving', 'Storing data for retrieval.') request.session['status'] = make_msg('Loading results', 'Conversion is being loaded', condition='complete', color='bg-info') return {'page': pagename} except Exception as err: log.exception(f'serious error in page creation from PyMol: {err}') request.response.status = 500 request.session['status'] = make_msg( 'A server-side error arose', 'The code failed to run serverside.', 'error', 'bg-danger') return {'status': 'error'}
def dehydrate(request): malformed = is_malformed(request, 'pdb', 'water', 'ligand', 'format') if malformed: return {'status': malformed} pdb = get_pdb_block(request) definitions = get_chain_definitions(request) history = get_history(request) history['changes'] += f'Dehydrated. ' try: water = is_js_true(request.params['water']) ligand = is_js_true(request.params['ligand']) if not (water or ligand): raise ValueError trans = PyMolTranspiler().dehydrate_block(block=pdb, water=water, ligand=ligand) return { 'pdb': trans.pdb_block, 'definitions': definitions, 'history': history } except ValueError: request.response.status = 422 return {'status': f'Nothing to delete'} # # # # def operation(request, pdb, fun_code, fun_file, **kargs): # """ # This method is called by premutate and removal, neither changes anything serverside. # """ # # get_uuid is not really needed as it does not go to DB. # filename = os.path.join('michelanglo_app', 'temp', f'{uuid.uuid4()}.pdb') # ## type is determined # pdb = get_pdb_block(request) # if hasattr(pdb, 'filename'): # #this is a special case wherein the uses has sent a file upload. # #for now it is simply saved and annotated and reopened. # #totally wasteful but for now none of the methods upload a file. # trans = save_coordinates(request, mod_fx=None) # block = trans.raw_pdb() ### xxxxxxxx # print(block) # raise NotImplementedError # else: # # if len(pdb) == 4: ##PDB code. # code = pdb # fun_code(pdb, filename, **kargs) # elif len(pdb.strip()) == 0: # request.response.status = 422 # return {'status': f'Empty PDB string?!'} # else: #string # if re.match('https://swissmodel.expasy.org', pdb): ## swissmodel # pdb = requests.get(pdb).text # with open(filename, 'w') as fh: # fh.write(pdb) # fun_file(filename, filename, **kargs) # with open(filename, 'r') as fh: # block = fh.read() # os.remove(filename) # if len(pdb) == 4: # return {'pdb': f'REMARK 100 THIS ENTRY IS ALTERED FROM {pdb}.\n' +block} # elif 'REMARK 100 THIS ENTRY' in block: # code = re.match('REMARK 100 THIS ENTRY IS \w+ FROM (\w+).', pdb).group(1) # return {'pdb': f'REMARK 100 THIS ENTRY IS ALTERED FROM {code}.\n' + block} # else: # return {'pdb': block}