Skip to content
Snippets Groups Projects
Commit 8d9604ed authored by David Sehnal's avatar David Sehnal
Browse files

domain annotation server (prototype)

parent 4f70aa55
No related branches found
No related tags found
No related merge requests found
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -24,15 +24,20 @@
"transform": {
"\\.ts$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"moduleDirectories": ["node_modules", "build/node_modules"],
"moduleDirectories": [
"node_modules",
"build/node_modules"
],
"testRegex": "\\.spec\\.ts$"
},
"author": "",
"license": "MIT",
"devDependencies": {
"@types/benchmark": "^1.0.30",
"@types/express": "^4.0.39",
"@types/jest": "^21.1.5",
"@types/node": "^8.0.47",
"@types/node-fetch": "^1.6.7",
"benchmark": "^2.1.4",
"download-cli": "^1.0.5",
"jest": "^21.2.1",
......@@ -45,8 +50,11 @@
"ts-jest": "^21.1.4",
"tslint": "^5.8.0",
"typescript": "^2.6.1",
"uglify-js": "^3.1.6",
"uglify-js": "^3.1.7",
"util.promisify": "^1.0.0"
},
"dependencies": {}
"dependencies": {
"express": "^4.16.2",
"node-fetch": "^1.7.3"
}
}
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Table } from 'mol-base/collections/database'
import { CIFEncoder, create as createEncoder } from 'mol-io/writer/cif'
import * as S from './schemas'
import { getCategoryInstanceProvider } from './utils'
export default function create(allData: any) {
const mols = Object.keys(allData);
if (!mols.length) return '#';
const data = allData[mols[0]];
const enc = createEncoder();
enc.startDataBlock(mols[0]);
for (const cat of Object.keys(S.categories)) {
writeDomain(enc, getDomain(cat, (S.categories as any)[cat], data));
}
return enc.getData();
}
interface DomainAnnotation {
name: string,
domains: Table<any>,
mappings: Table<S.mapping>
}
type MappingRow = Table.Row<S.mapping>;
function writeDomain(enc: CIFEncoder<any>, domain: DomainAnnotation | undefined) {
if (!domain) return;
enc.writeCategory(getCategoryInstanceProvider(`pdbx_${domain.name}_domain_annotation`, domain.domains));
enc.writeCategory(getCategoryInstanceProvider(`pdbx_${domain.name}_domain_mapping`, domain.mappings));
}
function getMappings(startId: number, group_id: number, mappings: any): MappingRow[] {
const rows: MappingRow[] = [];
const n = (v: any) => v === null ? void 0 : v;
for (const entry of mappings) {
if (entry.start && entry.end) {
rows.push({
id: startId++,
group_id,
label_entity_id: '' + entry.entity_id,
label_asym_id: entry.struct_asym_id,
auth_asym_id: entry.chain_id,
beg_label_seq_id: n(entry.start.residue_number),
beg_auth_seq_id: n(entry.start.author_residue_number),
pdbx_beg_PDB_ins_code: entry.start.author_insertion_code,
end_label_seq_id: n(entry.end.residue_number),
end_auth_seq_id: n(entry.end.author_residue_number),
pdbx_end_PDB_ins_code: entry.end.author_insertion_code
});
} else {
rows.push({
id: startId++,
group_id,
label_entity_id: '' + entry.entity_id,
label_asym_id: entry.struct_asym_id,
auth_asym_id: entry.chain_id
} as any);
}
}
return rows;
}
function getDomainInfo(id: string, mapping_group_id: number, data: any, schema: any) {
const props = Object.create(null);
for (const k of Object.keys(schema)) props[k] = data[k];
return { id, mapping_group_id, identifier: data.identifier, ...props };
}
function getDomain(name: string, schema: any, allData: any) {
if (!allData[name]) return void 0;
const data = allData[name];
const domains: any[] = [];
const mappings: MappingRow[] = [];
let mappingSerialId = 1, mapping_group_id = 1;
for (const id of Object.keys(data)) {
const domain = data[id];
domains.push(getDomainInfo(id, mapping_group_id, domain, schema));
mappings.push(...getMappings(mappingSerialId, mapping_group_id, domain.mappings));
mappingSerialId = mappings.length + 1;
mapping_group_id++;
}
return domains.length > 0 ? {
name,
domains: Table.ofRows({ ...S.Base, ...schema }, domains),
mappings: Table.ofRows(S.mapping, mappings)
} : void 0;
}
\ No newline at end of file
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Column } from 'mol-base/collections/database'
import Type = Column.Type
export const Base = {
id: Type.str,
identifier: Type.str,
mapping_group_id: Type.int
}
export type Base = typeof Base
export const mapping = {
id: Type.int,
group_id: Type.int,
label_entity_id: Type.str,
label_asym_id: Type.str,
auth_asym_id: Type.str,
beg_label_seq_id: Type.int,
beg_auth_seq_id: Type.int,
pdbx_beg_PDB_ins_code: Type.str,
end_label_seq_id: Type.int,
end_auth_seq_id: Type.int,
pdbx_end_PDB_ins_code: Type.str
}
export type mapping = typeof mapping
export const Pfam = {
description: Type.str
}
export type Pfam = typeof Pfam
export const InterPro = {
name: Type.str
}
export type InterPro = typeof InterPro
export const CATH = {
name: Type.str,
homology: Type.str,
architecture: Type.str,
identifier: Type.str,
class: Type.str,
topology: Type.str,
}
export type CATH = typeof CATH
export const EC = {
accepted_name: Type.str,
reaction: Type.str,
systematic_name: Type.str
}
export type EC = typeof EC
export const UniProt = {
name: Type.str
}
export type UniProt = typeof UniProt
export const SCOP = {
sccs: Type.str,
description: Type.str
}
export type SCOP = typeof SCOP
export const GO = {
category: Type.str,
definition: Type.str,
name: Type.str
}
export type GO = typeof GO
export const categories = {
Pfam,
InterPro,
CATH,
EC,
UniProt,
SCOP,
GO
}
\ No newline at end of file
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as express from 'express'
import fetch from 'node-fetch'
import createMapping from './mapping'
async function getMappings(id: string) {
const data = await fetch(`https://www.ebi.ac.uk/pdbe/api/mappings/${id}`);
const json = await data.json();
return createMapping(json);
};
let PORT = process.env.port || 1338;
const app = express();
const PREFIX = '/'
app.get(`${PREFIX}/:id`, async (req, res) => {
try {
console.log('Requesting ' + req.params.id);
const mapping = await getMappings(req.params.id);
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf-8',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'X-Requested-With'
});
res.end(mapping);
} catch {
console.log('Failed ' + req.params.id);
res.writeHead(404, { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'X-Requested-With' });
res.end();
}
});
app.get(`${PREFIX}`, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Usage: /pdb_id, e.g. /1tqn');
})
app.listen(PORT);
console.log('Running on port ' + PORT);
\ No newline at end of file
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import fetch from 'node-fetch'
import createMapping from './mapping'
(async function () {
const data = await fetch('https://www.ebi.ac.uk/pdbe/api/mappings/1tqn?pretty=true');
const json = await data.json();
console.log(createMapping(json));
}());
\ No newline at end of file
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Table } from 'mol-base/collections/database'
import Iterator from 'mol-base/collections/iterator'
import * as Encoder from 'mol-io/writer/cif'
function columnValue(k: string) {
return (i: number, d: any) => d[k].value(i);
}
function columnValueKind(k: string) {
return (i: number, d: any) => d[k].valueKind(i);
}
function ofSchema(schema: Table.Schema) {
const fields: Encoder.FieldDefinition[] = [];
for (const k of Object.keys(schema)) {
const t = schema[k];
// TODO: matrix/vector/support
const type = t.kind === 'str' ? Encoder.FieldType.Str : t.kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float;
fields.push({ name: k, type, value: columnValue(k), valueKind: columnValueKind(k) })
}
return fields;
}
function ofTable<S extends Table.Schema>(name: string, table: Table<S>): Encoder.CategoryDefinition<number> {
return { name, fields: ofSchema(table._schema) }
}
export function getCategoryInstanceProvider(name: string, table: Table<any>): Encoder.CategoryProvider {
return () => {
return {
data: table,
definition: ofTable(name, table),
keys: () => Iterator.Range(0, table._rowCount - 1),
rowCount: table._rowCount
};
}
}
......@@ -57,7 +57,7 @@ export interface CategoryProvider {
(ctx: any): CategoryInstance
}
export interface CIFEncoder<T, Context> extends Encoder<T> {
export interface CIFEncoder<T = string | Uint8Array, Context = any> extends Encoder<T> {
startDataBlock(header: string): void,
writeCategory(category: CategoryProvider, contexts?: Context[]): void,
getData(): T
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment