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
No related branches found
No related tags found
No related merge requests found
......@@ -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 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 Int = { '@type': 'int', T: number, valueKind: 'int' }
export type Float = { '@type': 'float', T: number, valueKind: 'float' }
......@@ -44,7 +42,7 @@ namespace Column {
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 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> {
......
......@@ -9,10 +9,6 @@ import * as Data from '../data-model'
import { EncodedColumn, decode } from '../../../common/binary-cif'
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 {
const mask = column.mask ? decode(column.mask) as number[] : void 0;
const data = decode(column.data);
......@@ -40,7 +36,7 @@ export default function Field(column: EncodedColumn): Data.Field {
const rowCount = data.length;
return wrap({
return {
'@array': data,
isDefined: true,
rowCount,
......@@ -56,5 +52,5 @@ export default function Field(column: EncodedColumn): Data.Field {
toFloatArray: isNumeric
? params => ColumnHelpers.typedArrayWindow(data, params)
: params => ColumnHelpers.createAndFillArray(rowCount, float, params)
});
};
}
\ No newline at end of file
......@@ -4,8 +4,9 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as Data from './data-model'
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 {
return createDatabase(schema, frame) as Frame;
......@@ -22,18 +23,13 @@ function getColumnCtor(t: Column.Schema): ColumnCtor {
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 'float': return (f, c, k) => createColumn(t, f, f.float, f.toFloatArray);
case 'tensor': return (f, c, k) => {
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));
}
case 'tensor': throw new Error(`Use createTensorColumn instead.`);
}
}
function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> {
return {
schema: schema,
schema,
'@array': field['@array'],
isDefined: field.isDefined,
rowCount: field.rowCount,
......@@ -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
_rowCount: number;
_columns: ReadonlyArray<string>;
......@@ -57,13 +71,17 @@ class CategoryTable implements Table<any> { // tslint:disable-line:class-name
this._schema = schema;
const cache = Object.create(null);
for (const k of fieldKeys) {
const cType = schema[k];
const ctor = getColumnCtor(cType);
Object.defineProperty(this, k, {
get: function() {
if (cache[k]) return cache[k];
const field = category.getField(k);
cache[k] = !!field ? ctor(field, category, k) : Column.Undefined(category.rowCount, cType);
const cType = schema[k];
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];
},
enumerable: true,
......
......@@ -75,6 +75,13 @@ export namespace Tensor {
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'] } {
const { dimensions, axisOrderFastToSlow: ao } = layout;
switch (dimensions.length) {
......
......@@ -243,8 +243,11 @@ export namespace PropertyAccess {
export async function run() {
//const { structures, models } = await readCIF('./examples/1cbs_full.bcif');
const { structures, models } = 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/3j3q_full.bcif');
//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');
......@@ -255,8 +258,6 @@ export namespace PropertyAccess {
// return;
console.log('parsed');
console.log(baseline(models[0]));
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)));
......
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