Browse Source

explicit pdbqt provider

- instead of trying to deduce it during parsing
Alexander Rose 4 years ago
parent
commit
1b67bc41f5

+ 8 - 3
src/mol-io/reader/pdb/parser.ts

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { PdbFile } from './schema';
@@ -9,6 +10,10 @@ import { Task } from '../../../mol-task';
 import { ReaderResult } from '../result';
 import { Tokenizer } from '../common/text/tokenizer';
 
-export function parsePDB(data: string, id?: string): Task<ReaderResult<PdbFile>> {
-    return Task.create('Parse PDB', async ctx => ReaderResult.success({ id, lines: await Tokenizer.readAllLinesAsync(data, ctx) }));
+export function parsePDB(data: string, id?: string, isPdbqt = false): Task<ReaderResult<PdbFile>> {
+    return Task.create('Parse PDB', async ctx => ReaderResult.success({
+        lines: await Tokenizer.readAllLinesAsync(data, ctx),
+        id,
+        isPdbqt
+    }));
 }

+ 4 - 2
src/mol-io/reader/pdb/schema.ts

@@ -1,12 +1,14 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { Tokens } from '../common/text/tokenizer';
 
 export interface PdbFile {
-    id?: string,
     lines: Tokens
+    id?: string,
+    isPdbqt?: boolean,
 }

+ 1 - 9
src/mol-model-formats/structure/pdb/to-cif.ts

@@ -23,6 +23,7 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
     const { lines } = pdb;
     const { data, indices } = lines;
     const tokenizer = Tokenizer(data);
+    const isPdbqt = !!pdb.isPdbqt;
 
     // Count the atoms
     let atomCount = 0;
@@ -47,7 +48,6 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
     const heteroNames: [string, string][] = [];
 
     let modelNum = 0, modelStr = '';
-    let isPdbqt = false;
 
     for (let i = 0, _i = lines.count; i < _i; i++) {
         let s = indices[2 * i], e = indices[2 * i + 1];
@@ -60,8 +60,6 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
                     addAnisotropic(anisotropic, modelStr, tokenizer, s, e);
                 }
                 break;
-            case 'B':
-                if (substringStartsWith(data, s, e, 'BRANCH')) isPdbqt = true;
             case 'C':
                 if (substringStartsWith(data, s, e, 'CRYST1')) {
                     helperCategories.push(...parseCryst1(pdb.id || '?', data.substring(s, e)));
@@ -78,8 +76,6 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
                     i = j - 1;
                 }
                 break;
-            case 'E':
-                if (substringStartsWith(data, s, e, 'ENDROOT')) isPdbqt = true;
             case 'H':
                 if (substringStartsWith(data, s, e, 'HETATM')) {
                     if (!modelNum) { modelNum++; modelStr = '' + modelNum; }
@@ -134,8 +130,6 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
                     }
                     helperCategories.push(...parseRemark350(lines, i, j));
                     i = j - 1;
-                } else if (substringStartsWith(data, s, e, 'ROOT')) {
-                    isPdbqt = true;
                 }
                 break;
             case 'S':
@@ -151,8 +145,6 @@ export async function pdbToMmCif(pdb: PdbFile): Promise<CifFrame> {
                 }
                 // TODO: SCALE record => cif.atom_sites.fract_transf_matrix, cif.atom_sites.fract_transf_vector
                 break;
-            case 'T':
-                if (substringStartsWith(data, s, e, 'TORSDOF')) isPdbqt = true;
         }
     }
 

+ 13 - 3
src/mol-plugin-state/formats/trajectory.ts

@@ -75,11 +75,11 @@ export const CifCoreProvider: TrajectoryFormatProvider = {
     visuals: defaultVisuals
 };
 
-function directTrajectory(transformer: StateTransformer<PluginStateObject.Data.String | PluginStateObject.Data.Binary, PluginStateObject.Molecule.Trajectory>): TrajectoryFormatProvider['parse'] {
+function directTrajectory<P>(transformer: StateTransformer<PluginStateObject.Data.String | PluginStateObject.Data.Binary, PluginStateObject.Molecule.Trajectory, P>, transformerParams?: P): TrajectoryFormatProvider['parse'] {
     return async (plugin, data, params) => {
         const state = plugin.state.data;
         const trajectory = await state.build().to(data)
-            .apply(transformer, void 0, { tags: params?.trajectoryTags })
+            .apply(transformer, transformerParams, { tags: params?.trajectoryTags })
             .commit({ revertOnError: true });
         return { trajectory };
     };
@@ -89,11 +89,20 @@ export const PdbProvider: TrajectoryFormatProvider = {
     label: 'PDB',
     description: 'PDB',
     category: Category,
-    stringExtensions: ['pdb', 'ent', 'pdbqt'],
+    stringExtensions: ['pdb', 'ent'],
     parse: directTrajectory(StateTransforms.Model.TrajectoryFromPDB),
     visuals: defaultVisuals
 };
 
+export const PdbqtProvider: TrajectoryFormatProvider = {
+    label: 'PDBQT',
+    description: 'PDBQT',
+    category: Category,
+    stringExtensions: ['pdbqt'],
+    parse: directTrajectory(StateTransforms.Model.TrajectoryFromPDB, { isPdbqt: true }),
+    visuals: defaultVisuals
+};
+
 export const GroProvider: TrajectoryFormatProvider = {
     label: 'GRO',
     description: 'GRO',
@@ -135,6 +144,7 @@ export const BuiltInTrajectoryFormats = [
     ['mmcif', MmcifProvider] as const,
     ['cifCore', CifCoreProvider] as const,
     ['pdb', PdbProvider] as const,
+    ['pdbqt', PdbqtProvider] as const,
     ['gro', GroProvider] as const,
     ['3dg', Provider3dg] as const,
     ['mol', MolProvider] as const,

+ 6 - 3
src/mol-plugin-state/transforms/model.ts

@@ -209,11 +209,14 @@ const TrajectoryFromPDB = PluginStateTransform.BuiltIn({
     name: 'trajectory-from-pdb',
     display: { name: 'Parse PDB', description: 'Parse PDB string and create trajectory.' },
     from: [SO.Data.String],
-    to: SO.Molecule.Trajectory
+    to: SO.Molecule.Trajectory,
+    params: {
+        isPdbqt: PD.Boolean(false)
+    }
 })({
-    apply({ a }) {
+    apply({ a, params }) {
         return Task.create('Parse PDB', async ctx => {
-            const parsed = await parsePDB(a.data, a.label).runInContext(ctx);
+            const parsed = await parsePDB(a.data, a.label, params.isPdbqt).runInContext(ctx);
             if (parsed.isError) throw new Error(parsed.message);
             const models = await trajectoryFromPDB(parsed.result).runInContext(ctx);
             const props = { label: `${models[0].entry}`, description: `${models.length} model${models.length === 1 ? '' : 's'}` };