瀏覽代碼

ModelServer: support BinaryCIF "encoding providers" from source file

David Sehnal 6 年之前
父節點
當前提交
43a9d73930

+ 5 - 5
src/mol-io/common/binary-cif/array-encoder.ts

@@ -55,8 +55,8 @@ export namespace ArrayEncoder {
     }
 
     export function fromEncoding(encoding: Encoding[]) {
-        const e = by(getProvider(encoding[0]));
-        for (let i = 1; i < encoding.length; i++) e.and(getProvider(encoding[i]));
+        let e = by(getProvider(encoding[0]));
+        for (let i = 1; i < encoding.length; i++) e = e.and(getProvider(encoding[i]));
         return e;
     }
 
@@ -358,9 +358,9 @@ export namespace ArrayEncoding {
      * Packs Int32 array. The packing level is determined automatically to either 1-, 2-, or 4-byte words.
      */
     export function integerPacking(data: Int32Array): Result {
-        if (!(data instanceof Int32Array)) {
-            throw new Error('Integer packing can only be applied to Int32 data.');
-        }
+        // if (!(data instanceof Int32Array)) {
+        //     throw new Error('Integer packing can only be applied to Int32 data.');
+        // }
 
         const packing = determinePacking(data);
 

+ 6 - 2
src/mol-io/common/binary-cif/encoding.ts

@@ -84,12 +84,16 @@ export namespace Encoding {
         else if (data instanceof Uint32Array) srcType = Encoding.IntDataType.Uint32;
         else if (data instanceof Float32Array) srcType = Encoding.FloatDataType.Float32;
         else if (data instanceof Float64Array) srcType = Encoding.FloatDataType.Float64;
-        else throw new Error('Unsupported integer data type.');
+        else srcType = Encoding.IntDataType.Int32; // throw new Error('Unsupported integer data type.');
         return srcType;
     }
 
     export function isSignedIntegerDataType(data: TypedIntArray) {
-        return data instanceof Int8Array || data instanceof Int16Array || data instanceof Int32Array;
+        if (data instanceof Int8Array || data instanceof Int16Array || data instanceof Int32Array) return true;
+        for (let i = 0, _i = data.length; i < _i; i++) {
+            if (i < 0) return false;
+        }
+        return true;
     }
 
     // type[] -> Uint8[]

+ 6 - 3
src/mol-io/reader/cif/data-model.ts

@@ -114,17 +114,20 @@ export function getTensor(category: CifCategory, field: string, space: Tensor.Sp
 }
 
 export function getCifFieldType(field: CifField): Column.Schema.Int | Column.Schema.Float | Column.Schema.Str {
-    let floatCount = 0, hasString = false;
+    let floatCount = 0, hasString = false, undefinedCount = 0;
     for (let i = 0, _i = field.rowCount; i < _i; i++) {
         const k = field.valueKind(i);
-        if (k !== Column.ValueKind.Present) continue;
+        if (k !== Column.ValueKind.Present) {
+            undefinedCount++;
+            continue;
+        }
         const type = getNumberType(field.str(i));
         if (type === NumberType.Int) continue;
         else if (type === NumberType.Float) floatCount++;
         else { hasString = true; break; }
     }
 
-    if (hasString) return Column.Schema.str;
+    if (hasString || undefinedCount === field.rowCount) return Column.Schema.str;
     if (floatCount > 0) return Column.Schema.float;
     return Column.Schema.int;
 }

+ 2 - 1
src/servers/model/config.ts

@@ -57,7 +57,8 @@ const config = {
      */
     mapFile(source: string, id: string) {
         switch (source.toLowerCase()) {
-            case 'pdb': return `e:/test/quick/${id}_updated.cif`;
+            // case 'pdb': return `e:/test/quick/${id}_updated.cif`;
+            case 'pdb': return `e:/test/mol-star/model/out/${id}_updated.bcif`;
             default: return void 0;
         }
     }

+ 12 - 1
src/servers/model/server/query.ts

@@ -31,7 +31,6 @@ export async function resolveJob(job: Job): Promise<CifWriter.Encoder<any>> {
     const wrappedStructure = await getStructure(job);
 
     try {
-        const encoder = CifWriter.createEncoder({ binary: job.responseFormat.isBinary, encoderName: `ModelServer ${Version}` });
         perf.start('query');
         const structure = job.queryDefinition.structureTransform
             ? await job.queryDefinition.structureTransform(job.normalizedParams, wrappedStructure.structure)
@@ -40,6 +39,13 @@ export async function resolveJob(job: Job): Promise<CifWriter.Encoder<any>> {
         const result = await StructureSelection.unionStructure(StructureQuery.run(query, structure, Config.maxQueryTimeInMs));
         perf.end('query');
 
+        const encoder = CifWriter.createEncoder({
+            binary: job.responseFormat.isBinary,
+            encoderName: `ModelServer ${Version}`,
+            binaryEncodingPovider: getEncodingProvider(wrappedStructure),
+            binaryAutoClassifyEncoding: true
+        });
+
         ConsoleLogger.logId(job.id, 'Query', 'Query finished.');
 
         perf.start('encode');
@@ -68,6 +74,11 @@ export async function resolveJob(job: Job): Promise<CifWriter.Encoder<any>> {
     }
 }
 
+function getEncodingProvider(structure: StructureWrapper) {
+    if (!structure.isBinary) return void 0;
+    return CifWriter.createEncodingProviderFromCifFrame(structure.cifFrame);
+}
+
 function doError(job: Job, e: any) {
     const encoder = CifWriter.createEncoder({ binary: job.responseFormat.isBinary, encoderName: `ModelServer ${Version}` });
     encoder.writeCategory(_model_server_result, [job]);

+ 2 - 0
src/servers/model/server/structure-wrapper.ts

@@ -37,6 +37,7 @@ export interface StructureInfo {
 export interface StructureWrapper {
     info: StructureInfo,
 
+    isBinary: boolean,
     key: string,
     approximateSize: number,
     structure: Structure,
@@ -126,6 +127,7 @@ export async function readStructure(key: string, sourceId: string | '_local_', e
             sourceId,
             entryId
         },
+        isBinary: /\.bcif/.test(filename),
         key,
         approximateSize: typeof data === 'string' ? 2 * data.length : data.length,
         structure,

File diff suppressed because it is too large
+ 81 - 0
web/render-test/index.js


Some files were not shown because too many files changed in this diff