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

CIF tensor fields should now be working

parent ba4f08ae
Branches
Tags
No related merge requests found
...@@ -25,8 +25,6 @@ namespace Column { ...@@ -25,8 +25,6 @@ namespace Column {
export type Schema<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> | Schema.Tensor export type Schema<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> | Schema.Tensor
export namespace Schema { export namespace Schema {
export type Scalar<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T>
export type Str = { '@type': 'str', T: string, valueKind: 'str' } export type Str = { '@type': 'str', T: string, valueKind: 'str' }
export type Int = { '@type': 'int', T: number, valueKind: 'int' } export type Int = { '@type': 'int', T: number, valueKind: 'int' }
export type Float = { '@type': 'float', T: number, valueKind: 'float' } export type Float = { '@type': 'float', T: number, valueKind: 'float' }
...@@ -44,7 +42,7 @@ namespace Column { ...@@ -44,7 +42,7 @@ namespace Column {
export function vector(dim: number): Tensor { return tensor(Tensors.Vector(dim)); } export function vector(dim: number): Tensor { return tensor(Tensors.Vector(dim)); }
export function matrix(rows: number, cols: number): Tensor { return tensor(Tensors.ColumnMajorMatrix(rows, cols)); } export function matrix(rows: number, cols: number): Tensor { return tensor(Tensors.ColumnMajorMatrix(rows, cols)); }
export function aliased<T>(t: Schema): Aliased<T> { return t as any as Aliased<T>; } export function aliased<T>(t: Str | Int): Aliased<T> { return t as any as Aliased<T>; }
} }
export interface ToArrayParams<T> { export interface ToArrayParams<T> {
......
...@@ -9,10 +9,6 @@ import * as Data from '../data-model' ...@@ -9,10 +9,6 @@ import * as Data from '../data-model'
import { EncodedColumn, decode } from '../../../common/binary-cif' import { EncodedColumn, decode } from '../../../common/binary-cif'
import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../../common/text/number-parser' import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../../common/text/number-parser'
function wrap(o: Data.Field) {
return { ...o };
}
export default function Field(column: EncodedColumn): Data.Field { export default function Field(column: EncodedColumn): Data.Field {
const mask = column.mask ? decode(column.mask) as number[] : void 0; const mask = column.mask ? decode(column.mask) as number[] : void 0;
const data = decode(column.data); const data = decode(column.data);
...@@ -40,7 +36,7 @@ export default function Field(column: EncodedColumn): Data.Field { ...@@ -40,7 +36,7 @@ export default function Field(column: EncodedColumn): Data.Field {
const rowCount = data.length; const rowCount = data.length;
return wrap({ return {
'@array': data, '@array': data,
isDefined: true, isDefined: true,
rowCount, rowCount,
...@@ -56,5 +52,5 @@ export default function Field(column: EncodedColumn): Data.Field { ...@@ -56,5 +52,5 @@ export default function Field(column: EncodedColumn): Data.Field {
toFloatArray: isNumeric toFloatArray: isNumeric
? params => ColumnHelpers.typedArrayWindow(data, params) ? params => ColumnHelpers.typedArrayWindow(data, params)
: params => ColumnHelpers.createAndFillArray(rowCount, float, params) : params => ColumnHelpers.createAndFillArray(rowCount, float, params)
}); };
} }
\ No newline at end of file
...@@ -4,8 +4,9 @@ ...@@ -4,8 +4,9 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import * as Data from './data-model'
import { Database, Table, Column, ColumnHelpers } from 'mol-data/db' import { Database, Table, Column, ColumnHelpers } from 'mol-data/db'
import { Tensor } from 'mol-math/linear-algebra'
import * as Data from './data-model'
export function toDatabase<Schema extends Database.Schema, Frame extends Database<Schema> = Database<Schema>>(schema: Schema, frame: Data.Frame): Frame { export function toDatabase<Schema extends Database.Schema, Frame extends Database<Schema> = Database<Schema>>(schema: Schema, frame: Data.Frame): Frame {
return createDatabase(schema, frame) as Frame; return createDatabase(schema, frame) as Frame;
...@@ -22,18 +23,13 @@ function getColumnCtor(t: Column.Schema): ColumnCtor { ...@@ -22,18 +23,13 @@ function getColumnCtor(t: Column.Schema): ColumnCtor {
case 'str': return (f, c, k) => createColumn(t, f, f.str, f.toStringArray); case 'str': return (f, c, k) => createColumn(t, f, f.str, f.toStringArray);
case 'int': return (f, c, k) => createColumn(t, f, f.int, f.toIntArray); case 'int': return (f, c, k) => createColumn(t, f, f.int, f.toIntArray);
case 'float': return (f, c, k) => createColumn(t, f, f.float, f.toFloatArray); case 'float': return (f, c, k) => createColumn(t, f, f.float, f.toFloatArray);
case 'tensor': return (f, c, k) => { case 'tensor': throw new Error(`Use createTensorColumn instead.`);
const space = t.space;
const value = (row: number) => Data.getTensor(c, k, space, row);
return createColumn(t, f, value, params => ColumnHelpers.createAndFillArray(f.rowCount, value, params));
}
} }
} }
function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> { function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
return { return {
schema: schema, schema,
'@array': field['@array'], '@array': field['@array'],
isDefined: field.isDefined, isDefined: field.isDefined,
rowCount: field.rowCount, rowCount: field.rowCount,
...@@ -44,6 +40,24 @@ function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row: ...@@ -44,6 +40,24 @@ function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row:
}; };
} }
function createTensorColumn(schema: Column.Schema.Tensor, category: Data.Category, key: string): Column<Tensor> {
const space = schema.space;
const first = category.getField(`${key}[1]`) || Column.Undefined(category.rowCount, schema);
const value = (row: number) => Data.getTensor(category, key, space, row);
const toArray: Column<Tensor>['toArray'] = params => ColumnHelpers.createAndFillArray(category.rowCount, value, params)
return {
schema,
'@array': void 0,
isDefined: first.isDefined,
rowCount: category.rowCount,
value,
valueKind: first.valueKind,
areValuesEqual: (rowA, rowB) => Tensor.areEqualExact(value(rowA), value(rowB)),
toArray
};
}
class CategoryTable implements Table<any> { // tslint:disable-line:class-name class CategoryTable implements Table<any> { // tslint:disable-line:class-name
_rowCount: number; _rowCount: number;
_columns: ReadonlyArray<string>; _columns: ReadonlyArray<string>;
...@@ -57,13 +71,17 @@ class CategoryTable implements Table<any> { // tslint:disable-line:class-name ...@@ -57,13 +71,17 @@ class CategoryTable implements Table<any> { // tslint:disable-line:class-name
this._schema = schema; this._schema = schema;
const cache = Object.create(null); const cache = Object.create(null);
for (const k of fieldKeys) { for (const k of fieldKeys) {
const cType = schema[k];
const ctor = getColumnCtor(cType);
Object.defineProperty(this, k, { Object.defineProperty(this, k, {
get: function() { get: function() {
if (cache[k]) return cache[k]; if (cache[k]) return cache[k];
const field = category.getField(k); const cType = schema[k];
cache[k] = !!field ? ctor(field, category, k) : Column.Undefined(category.rowCount, cType); if (cType.valueKind === 'tensor') {
cache[k] = createTensorColumn(cType, category, k);
} else {
const ctor = getColumnCtor(cType);
const field = category.getField(k);
cache[k] = !!field ? ctor(field, category, k) : Column.Undefined(category.rowCount, cType);
}
return cache[k]; return cache[k];
}, },
enumerable: true, enumerable: true,
......
...@@ -75,6 +75,13 @@ export namespace Tensor { ...@@ -75,6 +75,13 @@ export namespace Tensor {
return vec; return vec;
} }
export function areEqualExact(a: Tensor, b: Tensor) {
const len = a.length;
if (len !== b.length) return false;
for (let i = 0; i < len; i++) if (a[i] !== b[i]) return false;
return true;
}
function accessors(layout: Layout): { get: Space['get'], set: Space['set'] } { function accessors(layout: Layout): { get: Space['get'], set: Space['set'] } {
const { dimensions, axisOrderFastToSlow: ao } = layout; const { dimensions, axisOrderFastToSlow: ao } = layout;
switch (dimensions.length) { switch (dimensions.length) {
......
...@@ -243,8 +243,11 @@ export namespace PropertyAccess { ...@@ -243,8 +243,11 @@ export namespace PropertyAccess {
export async function run() { export async function run() {
//const { structures, models } = await readCIF('./examples/1cbs_full.bcif'); //const { structures, models } = await readCIF('./examples/1cbs_full.bcif');
const { structures, models } = await readCIF('e:/test/quick/3j3q_full.bcif'); const { structures, models, mmcif } = await readCIF('e:/test/quick/3j3q_full.bcif');
//const { structures, models } = await readCIF('e:/test/quick/1cbs_updated.cif'); //const { structures, models, mmcif } = await readCIF('e:/test/quick/1cbs_updated.cif');
console.log(mmcif.pdbx_struct_oper_list.matrix.toArray());
console.log(mmcif.pdbx_struct_oper_list.vector.toArray());
//const { structures, models } = await readCIF('e:/test/molstar/3j3q.bcif'); //const { structures, models } = await readCIF('e:/test/molstar/3j3q.bcif');
...@@ -255,8 +258,6 @@ export namespace PropertyAccess { ...@@ -255,8 +258,6 @@ export namespace PropertyAccess {
// return; // return;
console.log('parsed');
console.log(baseline(models[0])); console.log(baseline(models[0]));
console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom))); console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atom))); console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment