Skip to content
Snippets Groups Projects
Select Git revision
  • 6a35a3ece013be56660d73aba2b7be1ff1fa1254
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

webpack.config.js

Blame
  • structure-wrapper.ts 5.43 KiB
    /**
     * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    import { Structure, Model, Format } from 'mol-model/structure';
    import { PerformanceMonitor } from 'mol-util/performance-monitor';
    import { Cache } from './cache';
    import Config from '../config';
    import CIF, { CifFrame } from 'mol-io/reader/cif'
    import * as util from 'util'
    import * as fs from 'fs'
    import * as zlib from 'zlib'
    import { Job } from './jobs';
    import { ConsoleLogger } from 'mol-util/console-logger';
    import { ModelPropertiesProvider } from '../property-provider';
    
    require('util.promisify').shim();
    
    export enum StructureSourceType {
        File,
        Cache
    }
    
    export interface StructureInfo {
        sourceType: StructureSourceType;
        readTime: number;
        parseTime: number;
        createModelTime: number;
        attachPropsTime: number;
    
        sourceId: string,
        entryId: string
    }
    
    export interface StructureWrapper {
        info: StructureInfo,
        isBinary: boolean,
        key: string,
        approximateSize: number,
        models: ArrayLike<Model>,
        modelMap: Map<number, Model>,
        structureModelMap: Map<number, Structure>,
        propertyProvider: ModelPropertiesProvider | undefined,
        cifFrame: CifFrame
    }
    
    export async function createStructureWrapperFromJob(job: Job, propertyProvider: ModelPropertiesProvider | undefined, allowCache = true): Promise<StructureWrapper> {
        if (allowCache && Config.cacheParams.useCache) {
            const ret = StructureCache.get(job.key);
            if (ret) return ret;
        }
        const ret = await readStructureWrapper(job.key, job.sourceId, job.entryId, propertyProvider);
        if (allowCache && Config.cacheParams.useCache) {
            StructureCache.add(ret);
        }
        return ret;
    }
    
    export const StructureCache = new Cache<StructureWrapper>(s => s.key, s => s.approximateSize);
    const perf = new PerformanceMonitor();
    
    const readFileAsync = util.promisify(fs.readFile);
    const unzipAsync = util.promisify<zlib.InputType, Buffer>(zlib.unzip);
    
    async function readFile(filename: string) {
        const isGz = /\.gz$/i.test(filename);
        if (filename.match(/\.bcif/)) {
            let input = await readFileAsync(filename)
            if (isGz) input = await unzipAsync(input);
            const data = new Uint8Array(input.byteLength);
            for (let i = 0; i < input.byteLength; i++) data[i] = input[i];
            return data;
        } else {
            if (isGz) {
                const data = await unzipAsync(await readFileAsync(filename));
                return data.toString('utf8');
            }
            return readFileAsync(filename, 'utf8');
        }
    }
    
    async function parseCif(data: string|Uint8Array) {
        const comp = CIF.parse(data);
        const parsed = await comp.run();
        if (parsed.isError) throw parsed;
        return parsed.result;
    }
    
    export async function readStructureWrapper(key: string, sourceId: string | '_local_', entryId: string, propertyProvider: ModelPropertiesProvider | undefined) {
        const filename = sourceId === '_local_' ? entryId : Config.mapFile(sourceId, entryId);
        if (!filename) throw new Error(`Cound not map '${key}' to a valid filename.`);
        if (!fs.existsSync(filename)) throw new Error(`Could not find source file for '${key}'.`);
    
        perf.start('read');
        let data;
        try {
            data = await readFile(filename);
        } catch (e) {
            ConsoleLogger.error(key, '' + e);
            throw new Error(`Could not read the file for '${key}' from disk.`);
        }
    
        perf.end('read');
        perf.start('parse');
        const frame = (await parseCif(data)).blocks[0];
        perf.end('parse');
        perf.start('createModel');
        const models = await Model.create(Format.mmCIF(frame)).run();
        perf.end('createModel');
    
        const modelMap = new Map<number, Model>();
        for (const m of models) {
            modelMap.set(m.modelNum, m);
        }
    
        perf.start('attachProps');
        if (propertyProvider) {
            const modelProps = propertyProvider(models[0]);
            for (const p of modelProps) {
                await tryAttach(key, p);
            }
        }
        perf.end('attachProps');
    
        const ret: StructureWrapper = {
            info: {
                sourceType: StructureSourceType.File,
                readTime: perf.time('read'),
                parseTime: perf.time('parse'),
                createModelTime: perf.time('createModel'),
                attachPropsTime: 0, // perf.time('attachProps'),
                sourceId,
                entryId
            },
            isBinary: /\.bcif/.test(filename),
            key,
            approximateSize: typeof data === 'string' ? 2 * data.length : data.length,
            models,
            modelMap,
            structureModelMap: new Map(),
            cifFrame: frame,
            propertyProvider
        };
    
        return ret;
    }
    
    export async function resolveStructure(wrapper: StructureWrapper, modelNum?: number) {
        if (typeof modelNum === 'undefined') modelNum = wrapper.models[0].modelNum;
        if (wrapper.structureModelMap.has(modelNum)) return wrapper.structureModelMap.get(modelNum)!;
        if (!wrapper.modelMap.has(modelNum)) {
            return void 0;
        }
    
        const model = wrapper.modelMap.get(modelNum)!;
        const structure = Structure.ofModel(model);
        if (wrapper.propertyProvider) {
            const modelProps = wrapper.propertyProvider(model);
            for (const p of modelProps) {
                await tryAttach(wrapper.key, p);
            }
        }
        return structure;
    }
    
    async function tryAttach(key: string, promise: Promise<any>) {
        try {
            await promise;
        } catch (e) {
            ConsoleLogger.errorId(key, 'Custom prop:' + e);
        }
    }