From 17f534186da1b2c8b13ef9d9c272aa6f99fe5d7b Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sun, 24 Feb 2019 15:31:49 +0100 Subject: [PATCH] build mol-server/preprocess as a separate app (damn shaders: need to fix), use Buffer.from/alloc instead of new Buffer --- src/perf-tests/cif-encoder.ts | 2 +- src/servers/model/preprocess/preprocess.ts | 39 ++++++++++++++++++- src/servers/model/property-provider.ts | 6 +-- src/servers/model/server/api-local.ts | 2 +- src/servers/model/server/api-web.ts | 2 +- src/servers/model/server/structure-wrapper.ts | 20 ++++++---- src/servers/model/test.ts | 2 +- src/servers/volume/common/binary-schema.ts | 2 +- src/servers/volume/common/file.ts | 2 +- src/servers/volume/pack/main.ts | 2 +- src/servers/volume/pack/sampling.ts | 6 +-- src/servers/volume/server/local-api.ts | 2 +- src/servers/volume/server/web-api.ts | 2 +- webpack.config.js | 1 + 14 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/perf-tests/cif-encoder.ts b/src/perf-tests/cif-encoder.ts index 59f0eb3f6..5749ba5a4 100644 --- a/src/perf-tests/cif-encoder.ts +++ b/src/perf-tests/cif-encoder.ts @@ -60,7 +60,7 @@ function testBinary() { enc.writeCategory(getCat('cat2'), [{ rowCount: 1, fields: category2fields }]); enc.encode(); const data = enc.getData() as Uint8Array; - fs.writeFileSync('e:/test/mol-star/test.bcif', new Buffer(data)); + fs.writeFileSync('e:/test/mol-star/test.bcif', Buffer.from(data)); console.log('written binary'); } diff --git a/src/servers/model/preprocess/preprocess.ts b/src/servers/model/preprocess/preprocess.ts index 187a017b7..f36ee59ee 100644 --- a/src/servers/model/preprocess/preprocess.ts +++ b/src/servers/model/preprocess/preprocess.ts @@ -4,7 +4,7 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { readStructureWrapper, resolveStructures } from '../server/structure-wrapper'; +import { readStructureWrapper, resolveStructures, readDataAndFrame } from '../server/structure-wrapper'; import { classifyCif } from './converter'; import { Structure } from 'mol-model/structure'; import { CifWriter } from 'mol-io/writer/cif'; @@ -15,7 +15,14 @@ import { ModelPropertiesProvider } from '../property-provider'; // TODO: error handling -export async function preprocessFile(filename: string, propertyProvider?: ModelPropertiesProvider, outputCif?: string, outputBcif?: string) { +export function preprocessFile(filename: string, propertyProvider?: ModelPropertiesProvider, outputCif?: string, outputBcif?: string) { + return propertyProvider + ? preprocess(filename, propertyProvider, outputCif, outputBcif) + : convert(filename, outputCif, outputBcif); +} + + +async function preprocess(filename: string, propertyProvider?: ModelPropertiesProvider, outputCif?: string, outputBcif?: string) { const input = await readStructureWrapper('entry', '_local_', filename, propertyProvider); const categories = await classifyCif(input.cifFrame); const inputStructures = (await resolveStructures(input))!; @@ -36,6 +43,34 @@ export async function preprocessFile(filename: string, propertyProvider?: ModelP } } +async function convert(filename: string, outputCif?: string, outputBcif?: string) { + const { frame } = await readDataAndFrame(filename); + const categories = await classifyCif(frame); + + if (outputCif) { + const writer = wrapFileToWriter(outputCif); + const encoder = CifWriter.createEncoder({ binary: false }); + encodeConvert(frame.header, categories, encoder, writer); + writer.end(); + } + + if (outputBcif) { + const writer = wrapFileToWriter(outputBcif); + const encoder = CifWriter.createEncoder({ binary: true, binaryAutoClassifyEncoding: true }); + encodeConvert(frame.header, categories, encoder, writer); + writer.end(); + } +} + +function encodeConvert(header: string, categories: CifWriter.Category[], encoder: CifWriter.Encoder, writer: Writer) { + encoder.startDataBlock(header); + for (const cat of categories) { + encoder.writeCategory(cat); + } + encoder.encode(); + encoder.writeTo(writer); +} + function encode(structure: Structure, header: string, categories: CifWriter.Category[], encoder: CifWriter.Encoder, exportCtx: CifExportContext, writer: Writer) { const skipCategoryNames = new Set<string>(categories.map(c => c.name)); encoder.startDataBlock(header); diff --git a/src/servers/model/property-provider.ts b/src/servers/model/property-provider.ts index d64e5b4cf..77ab34c50 100644 --- a/src/servers/model/property-provider.ts +++ b/src/servers/model/property-provider.ts @@ -18,11 +18,11 @@ export type AttachModelProperty = (args: { model: Model, params: any, cache: any export type AttachModelProperties = (args: { model: Model, params: any, cache: any }) => Promise<any>[] export type ModelPropertiesProvider = (model: Model, cache: any) => Promise<any>[] -export function createModelPropertiesProviderFromConfig(): ModelPropertiesProvider { +export function createModelPropertiesProviderFromConfig() { return createModelPropertiesProvider(Config.customProperties); } -export function createModelPropertiesProvider(configOrPath: ModelPropertyProviderConfig | string | undefined): ModelPropertiesProvider { +export function createModelPropertiesProvider(configOrPath: ModelPropertyProviderConfig | string | undefined): ModelPropertiesProvider | undefined { let config: ModelPropertyProviderConfig; if (typeof configOrPath === 'string') { try { @@ -35,7 +35,7 @@ export function createModelPropertiesProvider(configOrPath: ModelPropertyProvide config = configOrPath!; } - if (!config || !config.sources || config.sources.length === 0) return () => []; + if (!config || !config.sources || config.sources.length === 0) return void 0; const ps: AttachModelProperties[] = []; for (const p of config.sources) { diff --git a/src/servers/model/server/api-local.ts b/src/servers/model/server/api-local.ts index 83fe022eb..74178f2c8 100644 --- a/src/servers/model/server/api-local.ts +++ b/src/servers/model/server/api-local.ts @@ -84,7 +84,7 @@ export function wrapFileToWriter(fn: string) { }, writeBinary(this: any, data: Uint8Array) { this.open(); - fs.writeSync(this.file, new Buffer(data.buffer)); + fs.writeSync(this.file, Buffer.from(data.buffer)); return true; }, writeString(this: any, data: string) { diff --git a/src/servers/model/server/api-web.ts b/src/servers/model/server/api-web.ts index a141dbfef..a472a9f3d 100644 --- a/src/servers/model/server/api-web.ts +++ b/src/servers/model/server/api-web.ts @@ -39,7 +39,7 @@ function wrapResponse(fn: string, res: express.Response) { }, writeBinary(this: any, data: Uint8Array) { if (!this.headerWritten) this.writeHeader(true); - return res.write(new Buffer(data.buffer)); + return res.write(Buffer.from(data.buffer)); }, writeString(this: any, data: string) { if (!this.headerWritten) this.writeHeader(false); diff --git a/src/servers/model/server/structure-wrapper.ts b/src/servers/model/server/structure-wrapper.ts index 615e57e75..6eef79c02 100644 --- a/src/servers/model/server/structure-wrapper.ts +++ b/src/servers/model/server/structure-wrapper.ts @@ -90,24 +90,30 @@ async function parseCif(data: string|Uint8Array) { 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}'.`); - +export async function readDataAndFrame(filename: string, key?: string) { 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.`); + ConsoleLogger.error(key || filename, '' + e); + throw new Error(`Could not read the file for '${key || filename}' from disk.`); } perf.end('read'); perf.start('parse'); const frame = (await parseCif(data)).blocks[0]; perf.end('parse'); + + return { data, frame }; +} + +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}'.`); + + const { data, frame } = await readDataAndFrame(filename, key); perf.start('createModel'); const models = await trajectoryFromMmCIF(frame).run(); perf.end('createModel'); diff --git a/src/servers/model/test.ts b/src/servers/model/test.ts index 8d7f85b1e..b250de2ef 100644 --- a/src/servers/model/test.ts +++ b/src/servers/model/test.ts @@ -13,7 +13,7 @@ function wrapFile(fn: string) { }, writeBinary(this: any, data: Uint8Array) { this.open(); - fs.writeSync(this.file, new Buffer(data)); + fs.writeSync(this.file, Buffer.from(data)); return true; }, writeString(this: any, data: string) { diff --git a/src/servers/volume/common/binary-schema.ts b/src/servers/volume/common/binary-schema.ts index 3bd0b10cc..cdc72fb51 100644 --- a/src/servers/volume/common/binary-schema.ts +++ b/src/servers/volume/common/binary-schema.ts @@ -97,7 +97,7 @@ function writeElement(e: Element, buffer: Buffer, src: any, offset: number) { function write(element: Element, src: any) { const size = byteCount(element, src); - const buffer = new Buffer(size); + const buffer = Buffer.alloc(size); writeElement(element, buffer, src, 0); return buffer; } diff --git a/src/servers/volume/common/file.ts b/src/servers/volume/common/file.ts index c01670aa1..f641faf7e 100644 --- a/src/servers/volume/common/file.ts +++ b/src/servers/volume/common/file.ts @@ -57,7 +57,7 @@ export function createFile(filename: string) { }); } -const smallBuffer = SimpleBuffer.fromBuffer(new Buffer(8)); +const smallBuffer = SimpleBuffer.fromBuffer(Buffer.alloc(8)); export async function writeInt(file: FileHandle, value: number, position: number) { smallBuffer.writeInt32LE(value, 0); await file.writeBuffer(position, smallBuffer, 4); diff --git a/src/servers/volume/pack/main.ts b/src/servers/volume/pack/main.ts index a43bddae2..270682fbe 100644 --- a/src/servers/volume/pack/main.ts +++ b/src/servers/volume/pack/main.ts @@ -40,7 +40,7 @@ function updateAllocationProgress(progress: Data.Progress, progressDone: number) */ async function allocateFile(ctx: Data.Context) { const { totalByteSize, file } = ctx; - const buffer = new Buffer(Math.min(totalByteSize, 8 * 1024 * 1024)); + const buffer = Buffer.alloc(Math.min(totalByteSize, 8 * 1024 * 1024)); const progress: Data.Progress = { current: 0, max: Math.ceil(totalByteSize / buffer.byteLength) }; let written = 0; while (written < totalByteSize) { diff --git a/src/servers/volume/pack/sampling.ts b/src/servers/volume/pack/sampling.ts index 97d77961d..299c1fb8c 100644 --- a/src/servers/volume/pack/sampling.ts +++ b/src/servers/volume/pack/sampling.ts @@ -20,11 +20,11 @@ export async function createContext(filename: string, channels: Format.Context[] const { extent, valueType, grid, origin } = channels[0].data.header; const samplingCounts = getSamplingCounts(extent, blockSize); - const cubeBuffer = new Buffer(new ArrayBuffer(channels.length * blockSize * blockSize * blockSize * getElementByteSize(valueType))); + const cubeBuffer = Buffer.from(new ArrayBuffer(channels.length * blockSize * blockSize * blockSize * getElementByteSize(valueType))); const litteEndianCubeBuffer = SimpleBuffer.IsNativeEndianLittle ? cubeBuffer - : new Buffer(new ArrayBuffer(channels.length * blockSize * blockSize * blockSize * getElementByteSize(valueType))); + : Buffer.from(new ArrayBuffer(channels.length * blockSize * blockSize * blockSize * getElementByteSize(valueType))); // The data can be periodic iff the extent is the same as the grid and origin is 0. if (grid.some((v, i) => v !== extent[i]) || origin.some(v => v !== 0)) { @@ -100,7 +100,7 @@ function createBlockBuffer(sampleCount: number[], blockSize: number, valueType: for (let i = 0; i < numChannels; i++) values[i] = createTypedArray(valueType, sampleCount[0] * sampleCount[1] * blockSize); return { values, - buffers: values.map(xs => new Buffer(xs.buffer)), + buffers: values.map(xs => Buffer.from(xs.buffer)), slicesWritten: 0 }; } diff --git a/src/servers/volume/server/local-api.ts b/src/servers/volume/server/local-api.ts index 8a4a514db..387d72a31 100644 --- a/src/servers/volume/server/local-api.ts +++ b/src/servers/volume/server/local-api.ts @@ -121,7 +121,7 @@ function wrapFile(fn: string) { }, writeBinary(this: any, data: Uint8Array) { this.open(); - fs.writeSync(this.file, new Buffer(data)); + fs.writeSync(this.file, Buffer.from(data)); return true; }, writeString(this: any, data: string) { diff --git a/src/servers/volume/server/web-api.ts b/src/servers/volume/server/web-api.ts index 5040ba702..28a0b3384 100644 --- a/src/servers/volume/server/web-api.ts +++ b/src/servers/volume/server/web-api.ts @@ -60,7 +60,7 @@ function wrapResponse(fn: string, res: express.Response) { }, writeBinary(this: any, data: Uint8Array) { if (!this.headerWritten) this.writeHeader(true); - return res.write(new Buffer(data.buffer)); + return res.write(Buffer.from(data.buffer)); }, writeString(this: any, data: string) { if (!this.headerWritten) this.writeHeader(false); diff --git a/webpack.config.js b/webpack.config.js index 8271634c5..e3d711da3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -88,6 +88,7 @@ module.exports = [ createApp('viewer'), createApp('basic-wrapper'), createNodeApp('state-docs'), + createNodeEntryPoint('preprocess', 'servers/model', 'model-server'), createApp('model-server-query'), createBrowserTest('font-atlas'), -- GitLab