Skip to content
Snippets Groups Projects
Commit 37a0b07d authored by Sebastian Bittrich's avatar Sebastian Bittrich
Browse files

stub for encoding config

parent 9dd3a466
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.
...@@ -53,5 +53,58 @@ export namespace CifWriter { ...@@ -53,5 +53,58 @@ export namespace CifWriter {
return ff && ff.binaryEncoding ? ArrayEncoder.fromEncoding(ff.binaryEncoding) : void 0; return ff && ff.binaryEncoding ? ArrayEncoder.fromEncoding(ff.binaryEncoding) : void 0;
} }
} }
};
export function createEncodingProviderFromJsonConfig(hints: EncodingStrategyHint[]): EncodingProvider {
return {
get(c, f) {
for (let i = 0; i < hints.length; i++) {
const hint = hints[i];
if (hint.categoryName === c && hint.columnName === f) {
return resolveEncoding(hint);
}
}
}
}
} }
function resolveEncoding(hint: EncodingStrategyHint): ArrayEncoder | undefined {
const precision: number | undefined = hint.precision;
if (precision !== void 0) {
const multiplier = Math.pow(10, precision);
const fixedPoint = E.by(E.fixedPoint(multiplier));
switch (hint.encoding) {
case 'pack':
return fixedPoint.and(E.integerPacking);
case 'rle':
return fixedPoint.and(E.runLength).and(E.integerPacking);
case 'delta':
return fixedPoint.and(E.delta).and(E.integerPacking);
case 'delta-rle':
return fixedPoint.and(E.delta).and(E.runLength).and(E.integerPacking);
};
} else {
switch (hint.encoding) {
case 'pack':
return E.by(E.integerPacking);
case 'rle':
return E.by(E.runLength).and(E.integerPacking);
case 'delta':
return E.by(E.delta).and(E.integerPacking);
case 'delta-rle':
return E.by(E.delta).and(E.runLength).and(E.integerPacking);
}
}
}
}
// defines the information needed to encode certain fields: category and column name as well as encoding tag, precision is optional and identifies float columns
// TODO would be nice to infer strategy and precision if needed
export interface EncodingStrategyHint {
categoryName: string,
columnName: string,
// 'pack', 'rle', 'delta', or 'delta-rle'
encoding: string,
// number of decimal places to keep - must be specified to float columns
precision?: number
} }
\ No newline at end of file
...@@ -111,12 +111,13 @@ function getDefaultEncoder(type: Field.Type): ArrayEncoder { ...@@ -111,12 +111,13 @@ function getDefaultEncoder(type: Field.Type): ArrayEncoder {
} }
function tryGetEncoder(categoryName: string, field: Field, format: Field.Format | undefined, provider: EncodingProvider | undefined) { function tryGetEncoder(categoryName: string, field: Field, format: Field.Format | undefined, provider: EncodingProvider | undefined) {
if (format && format.encoder) { // TODO made provider the first check - might break servers/model/query
if (provider && provider.get(categoryName, field.name)) {
return provider.get(categoryName, field.name);
} else if (format && format.encoder) {
return format.encoder; return format.encoder;
} else if (field.defaultFormat && field.defaultFormat.encoder) { } else if (field.defaultFormat && field.defaultFormat.encoder) {
return field.defaultFormat.encoder; return field.defaultFormat.encoder;
} else if (provider) {
return provider.get(categoryName, field.name);
} else { } else {
return void 0; return void 0;
} }
......
import './index.html'
import { CIF, CifCategory, CifField, getCifFieldType } from '../../mol-io/reader/cif';
import { CifWriter } from '../../mol-io/writer/cif';
import { classifyFloatArray, classifyIntArray } from '../../mol-io/common/binary-cif';
async function parseCif(data: string|Uint8Array) {
const comp = CIF.parse(data);
const parsed = await comp.run();
if (parsed.isError) throw parsed;
return parsed.result;
}
async function downloadCif(url: string, isBinary: boolean) {
const data = await fetch(url);
return parseCif(isBinary ? new Uint8Array(await data.arrayBuffer()) : await data.text());
}
async function downloadFromPdb(pdb: string) {
const parsed = await downloadCif(`https://webchem.ncbr.muni.cz/ModelServer/static/bcif/${pdb}`, true);
return parsed.blocks[0];
}
async function init(props = {}) {
const cif = await downloadFromPdb('1brr')
const encoder = CifWriter.createEncoder({
binary: true,
encoderName: 'mol*',
binaryEncodingPovider: CifWriter.createEncodingProviderFromJsonConfig([
{
'categoryName': 'atom_site',
'columnName': 'Cartn_y',
'encoding': 'rle',
'precision': 0
},
{
'categoryName': 'atom_site',
'columnName': 'Cartn_z',
'encoding': 'delta',
'precision': 1
},
{
'categoryName': 'atom_site',
'columnName': 'label_seq_id',
'encoding': 'delta-rle'
}
])
});
encoder.startDataBlock(cif.header);
for (const c of cif.categoryNames) {
const cat = cif.categories[c];
const fields: CifWriter.Field[] = [];
for (const f of cat.fieldNames) {
fields.push(classify(f, cat.getField(f)!))
}
encoder.writeCategory(getCategoryInstanceProvider(cif.categories[c], fields));
}
const ret = encoder.getData() as Uint8Array;
const cif2 = (await parseCif(ret)).blocks[0];
// should be untouched
console.log(cif2.categories['atom_site'].getField('Cartn_x'));
// should have integer precision
console.log(cif2.categories['atom_site'].getField('Cartn_y'));
// should have 1 decimal place
console.log(cif2.categories['atom_site'].getField('Cartn_z'));
console.log(cif2.categories['atom_site'].getField('label_seq_id'));
}
init()
function getCategoryInstanceProvider(cat: CifCategory, fields: CifWriter.Field[]): CifWriter.Category {
return {
name: cat.name,
instance: () => CifWriter.categoryInstance(fields, { data: cat, rowCount: cat.rowCount })
};
}
function classify(name: string, field: CifField): CifWriter.Field {
const type = getCifFieldType(field);
if (type['@type'] === 'str') {
return { name, type: CifWriter.Field.Type.Str, value: field.str, valueKind: field.valueKind };
} else if (type['@type'] === 'float') {
const encoder = classifyFloatArray(field.toFloatArray({ array: Float64Array }));
return CifWriter.Field.float(name, field.float, { valueKind: field.valueKind, encoder, typedArray: Float64Array });
} else {
const encoder = classifyIntArray(field.toIntArray({ array: Int32Array }));
return CifWriter.Field.int(name, field.int, { valueKind: field.valueKind, encoder, typedArray: Int32Array });
}
}
\ No newline at end of file
...@@ -98,4 +98,5 @@ module.exports = [ ...@@ -98,4 +98,5 @@ module.exports = [
createBrowserTest('render-spheres'), createBrowserTest('render-spheres'),
createBrowserTest('render-structure'), createBrowserTest('render-structure'),
createBrowserTest('render-text'), createBrowserTest('render-text'),
createBrowserTest('encoding-config')
] ]
\ No newline at end of file
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