예제 #1
0
 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)
예제 #2
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
예제 #3
0
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).'
        }
예제 #4
0
 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)
예제 #5
0
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)
예제 #6
0
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
예제 #7
0
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'}
예제 #12
0
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}
예제 #13
0
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
예제 #14
0
 def test_transpile(self):
     """
     Tests the pse transpiler
     """
     transpiler = PyMolTranspiler().transpile(file='test/1ubq.pse')
     transpiler.raw_pdb
예제 #15
0
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!'}
예제 #16
0
    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
예제 #17
0
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}
예제 #18
0
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'}
예제 #19
0
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}