Skip to content
Snippets Groups Projects
Select Git revision
  • 589fdcec031104fc4d1f73e1ab5dbd536434326a
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

api.ts

Blame
  • api.ts 6.29 KiB
    /**
     * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    import { Queries, Structure, StructureQuery, StructureSymmetry } from 'mol-model/structure';
    import { getAtomsTests } from '../query/atoms';
    
    export enum QueryParamType {
        JSON,
        String,
        Integer,
        Float
    }
    
    export interface QueryParamInfo {
        name: string,
        type: QueryParamType,
        description?: string,
        required?: boolean,
        defaultValue?: any,
        exampleValues?: any[],
        validation?: (v: any) => void
    }
    
    export interface QueryDefinition<Params = any> {
        name: string,
        niceName: string,
        exampleId: string, // default is 1cbs
        query: (params: any, structure: Structure) => StructureQuery,
        description: string,
        params: QueryParamInfo[],
        structureTransform?: (params: any, s: Structure) => Promise<Structure>,
        '@params': Params
    }
    
    export interface AtomSiteSchema {
        label_entity_id?: string,
    
        label_asym_id?: string,
        auth_asym_id?: string,
    
        label_comp_id?: string,
        auth_comp_id?: string,
        label_seq_id?: string,
        auth_seq_id?: string,
        pdbx_PDB_ins_code?: string,
    
        label_atom_id?: string,
        auth_atom_id?: string,
        type_symbol?: string
    }
    
    const AtomSiteTestParams: QueryParamInfo = {
        name: 'atom_site',
        type: QueryParamType.JSON,
        description: 'Object or array of objects describing atom properties. Names are same as in wwPDB mmCIF dictionary of the atom_site category.',
        exampleValues: [{ label_comp_id: 'ALA' }, { label_seq_id: 123, label_asym_id: 'A' }]
    };
    
    const RadiusParam: QueryParamInfo = {
        name: 'radius',
        type: QueryParamType.Float,
        defaultValue: 5,
        exampleValues: [5],
        description: 'Value in Angstroms.',
        validation(v: any) {
            if (v < 1 || v > 10) {
                throw `Invalid radius for residue interaction query (must be a value between 1 and 10).`;
            }
        }
    };
    
    function Q<Params = any>(definition: Partial<QueryDefinition<Params>>) {
        return definition;
    }
    
    const QueryMap = {
        'full': Q<{} | undefined>({ niceName: 'Full Structure', query: () => Queries.generators.all, description: 'The full structure.' }),
        'atoms': Q<{ atom_site: AtomSiteSchema }>({
            niceName: 'Atoms',
            description: 'Atoms satisfying the given criteria.',
            query: p => Queries.combinators.merge(getAtomsTests(p.atom_site).map(test => Queries.generators.atoms(test))),
            params: [ AtomSiteTestParams ]
        }),
        'symmetryMates': Q<{ radius: number }>({
            niceName: 'Symmetry Mates',
            description: 'Computes crystal symmetry mates within the specified radius.',
            query: () => Queries.generators.all,
            structureTransform(p, s) {
                return StructureSymmetry.builderSymmetryMates(s, p.radius).run();
            },
            params: [ RadiusParam ]
        }),
        'assembly': Q<{ name: string }>({
            niceName: 'Assembly',
            description: 'Computes structural assembly.',
            query: () => Queries.generators.all,
            structureTransform(p, s) {
                return StructureSymmetry.buildAssembly(s, '' + (p.name || '1')).run();
            },
            params: [{
                name: 'name',
                type: QueryParamType.String,
                defaultValue: '1',
                exampleValues: ['1'],
                description: 'Assembly name.'
            }]
        }),
        'residueInteraction': Q<{ atom_site: AtomSiteSchema, radius: number }>({
            niceName: 'Residue Interaction',
            description: 'Identifies all residues within the given radius from the source residue. Takes crystal symmetry into account.',
            query(p) {
                const tests = getAtomsTests(p.atom_site);
                const center = Queries.combinators.merge(tests.map(test => Queries.generators.atoms({
                    ...test,
                    entityTest: test.entityTest
                        ? ctx => test.entityTest!(ctx) && ctx.element.unit.conformation.operator.isIdentity
                        : ctx => ctx.element.unit.conformation.operator.isIdentity
                })));
                return Queries.modifiers.includeSurroundings(center, { radius: p.radius, wholeResidues: true });
            },
            structureTransform(p, s) {
                return StructureSymmetry.builderSymmetryMates(s, p.radius).run();
            },
            params: [ AtomSiteTestParams, RadiusParam ]
        }),
    };
    
    export type QueryName = keyof typeof QueryMap
    export type QueryParams<Q extends QueryName> = Partial<(typeof QueryMap)[Q]['@params']>
    
    export function getQueryByName(name: QueryName): QueryDefinition {
        return QueryMap[name] as QueryDefinition;
    }
    
    export const QueryList = (function () {
        const list: { name: string, definition: QueryDefinition }[] = [];
        for (const k of Object.keys(QueryMap)) list.push({ name: k, definition: <QueryDefinition>QueryMap[k as QueryName] });
        list.sort(function (a, b) { return a.name < b.name ? -1 : a.name > b.name ? 1 : 0 });
        return list;
    })();
    
    // normalize the queries
    (function () {
        for (let q of QueryList) {
            const m = q.definition;
            m.name = q.name;
            m.params = m.params || [];
        }
    })();
    
    // function _normalizeQueryParams(params: { [p: string]: string }, paramList: QueryParamInfo[]): { [p: string]: string | number | boolean } {
    //     const ret: any = {};
    //     for (const p of paramList) {
    //         const key = p.name;
    //         const value = params[key];
    //         if (typeof value === 'undefined' || (typeof value !== 'undefined' && value !== null && value['length'] === 0)) {
    //             if (p.required) {
    //                 throw `The parameter '${key}' is required.`;
    //             }
    //             if (typeof p.defaultValue !== 'undefined') ret[key] = p.defaultValue;
    //         } else {
    //             switch (p.type) {
    //                 case QueryParamType.JSON: ret[key] = JSON.parse(value); break;
    //                 case QueryParamType.String: ret[key] = value; break;
    //                 case QueryParamType.Integer: ret[key] = parseInt(value); break;
    //                 case QueryParamType.Float: ret[key] = parseFloat(value); break;
    //             }
    
    //             if (p.validation) p.validation(ret[key]);
    //         }
    //     }
    
    //     return ret;
    // }
    
    export function normalizeQueryParams(query: QueryDefinition, params: any) {
        return params;
        //return _normalizeQueryParams(params, query.params);
    }