Compare commits

...

1207 Commits

Author SHA1 Message Date
dsehnal
d527609b6d 2.0.0-dev.3 2021-02-21 19:23:06 +01:00
dsehnal
e628f580a7 add missing React key 2021-02-21 16:28:17 +01:00
Alexander Rose
b662179b4d improved lighting example 2021-02-20 01:59:46 -08:00
Alexander Rose
fa2b8542bf 2.0.0-dev.2 2021-02-18 21:20:14 -08:00
Alexander Rose
901522f500 added atom-id and entity-id color theme 2021-02-18 21:16:46 -08:00
dsehnal
62b63c1aa5 apply magic to solve GPU MC rendering issue 2021-02-18 19:05:07 +01:00
Alexander Rose
24b36f41da 2.0.0-dev.1 2021-02-15 22:09:05 -08:00
Alexander Rose
c9c890782c try re-use boundingSphere in element visuals
- if it has not changed much
2021-02-15 21:38:13 -08:00
Alexander Rose
f2c539ebd8 psf parser, support lammps "full" style 2021-02-15 18:04:38 -08:00
dsehnal
feb922ca91 Merge branch 'gpu' 2021-02-14 20:13:16 +01:00
dsehnal
25127bb84b Merge branch 'master' of https://github.com/molstar/molstar 2021-02-14 20:13:12 +01:00
dsehnal
8fb01d2157 Merge remote-tracking branch 'origin' into gpu 2021-02-14 20:11:11 +01:00
dsehnal
c09357ea75 updateImmediate for modelIndex 2021-02-14 20:00:37 +01:00
dsehnal
9f2513dae0 fix examples 2021-02-14 19:38:58 +01:00
dsehnal
11a52c0390 add missing TrajectoryInfo 2021-02-14 19:34:32 +01:00
dsehnal
e955dc7e94 exportable trajectory animation 2021-02-14 19:26:06 +01:00
Alexander Rose
c8107272f6 2.0.0-dev.0 2021-02-13 23:11:05 -08:00
Alexander Rose
fb08fe7545 remove extra files 2021-02-13 23:06:17 -08:00
Alexander Rose
b6f054ea28 Merge pull request #130 from molstar/lint-dep
Lint dep
2021-02-13 13:24:34 -08:00
Alexander Rose
dc7e85133c moved DefaultPluginSpec to spec.ts 2021-02-13 13:04:53 -08:00
Alexander Rose
90cddf4e41 allow named tuples
- beter use downlevel-dts for backwards compatibility
2021-02-13 13:00:11 -08:00
Alexander Rose
2cddbb72a6 fix tests, remove more deps from mat4, quat 2021-02-13 12:29:45 -08:00
Alexander Rose
a16faaac4e avoid some static dependencies
- those can lead to errors due to circular dependencies
- making them runtime dependencies fixes this
2021-02-13 12:06:07 -08:00
Alexander Rose
6c5224f33e new linting rules
- no default exports
- no named tuples
2021-02-13 11:36:21 -08:00
Alexander Rose
77d013b775 webgl, ensure active attribute with divisor 0
- workaround for FF <85
- needed for `texture-mesh` geometry
2021-02-13 11:30:13 -08:00
Alexander Rose
02a466e8b9 only update repr visibility when changed
- avoids superfluous scene rendering, e.g., when animating
2021-02-13 11:27:44 -08:00
Alexander Rose
3cb65cbe3d reduce ssao quality defaults a bit
- less texture fetches
2021-02-13 11:24:07 -08:00
Alexander Rose
fe8838542c 1.3.0 2021-02-07 13:29:46 -08:00
Alexander Rose
78b5c9aac4 Merge pull request #129 from molstar/gpu
Gpu acceleration for isosurface & gaussian-surface
2021-02-07 13:25:22 -08:00
Alexander Rose
021fa7b79b clearer param names for using gpu/impostors 2021-02-07 13:23:36 -08:00
Alexander Rose
0443589b09 allow gaussian volume without blendMinMax 2021-02-07 13:18:24 -08:00
Alexander Rose
415288de9f tweak quality settings
- lower resolution
2021-02-07 12:52:10 -08:00
Alexander Rose
ecbafb086a fix mc example 2021-02-06 12:46:25 -08:00
Alexander Rose
e5dae6c0dd increased default quality for larger structures
- rational is that larger structures can take a bit longer to create
2021-02-06 12:45:00 -08:00
Alexander Rose
16f4524bdb improved gpu support for representations
- enabled in volume isosurface & structure gaussian surface
- only if suitable (check memory requirements and resolution)
- falls back to cpu code
2021-02-06 12:43:24 -08:00
Alexander Rose
6b33021f43 fix webgl stats on render-item disposal 2021-02-06 12:30:12 -08:00
Alexander Rose
fdf37100c2 improved gpu-mc
- lower memory usage
- support for 2^32 vertices in webgl2
- fix rounding issue when creating volume texture
2021-02-06 12:28:52 -08:00
Alexander Rose
e28674d0dc model format improvements
- add a source format to the mmcif format
- add pdb format
- allow undefined in typeguard .is helpers
2021-02-03 19:36:01 -08:00
Alexander Rose
fb7456286a fix label_seq_id assignment when undefined column 2021-02-03 19:32:20 -08:00
Alexander Rose
9d240f8928 allow views of undefined columns 2021-02-03 19:30:14 -08:00
David Sehnal
48ef5efb21 Merge pull request #127 from molstar/pp-res
lower resolution ssao
2021-02-01 12:59:53 +01:00
Alexander Rose
52b2e7c144 lower res ssao 2021-01-31 13:22:22 -08:00
Alexander Rose
f2d1d60f6b fix cellpack & unit creation issues
- cellpack generate color theme can be applied to 1 model trajectories
- don't clone supplied props in Unit.create
- fix cellpack structure building to share unit.props
2021-01-31 12:06:40 -08:00
dsehnal
5a176a378a 1.2.15 2021-01-31 18:32:08 +01:00
dsehnal
60151c2c24 fix getUnitsSortedByVolume 2021-01-31 18:30:13 +01:00
dsehnal
a5db6350a2 only normalize Canvas3D props when loading from a saved state 2021-01-31 18:01:42 +01:00
dsehnal
0618eb18ba 1.2.14 2021-01-31 17:10:17 +01:00
Alexander Rose
bffdff6aad gaussian surface visual improvements
- add structure.unitsSortedByVolume
- increase gaussian smoothness in coarse presets
- use slice area instead of volume to ensure reasonable resolution
- use largest units (by volume) for reasonable resolution calculation
2021-01-30 22:55:29 -08:00
Alexander Rose
7753a6ec56 renderable schema cleanup
- use base schema in direct-volume schema
2021-01-30 12:57:19 -08:00
Alexander Rose
b8aafa1d78 mol-gl improvements
- int textures (webgl2)
- read into Int32Array (webgl2)
- fix ctx.parameters.maxDrawingBuffers (webgl1)
- support setting frag out type (webgl2)
2021-01-30 12:42:48 -08:00
Alexander Rose
672875187b add renderable.state.disposed flag
- set when disposing render-objects
- don't render disposed objects (can be temporarily still in a scene)
2021-01-30 12:39:33 -08:00
Alexander Rose
547d60d573 fix texture-mesh vertex count 2021-01-30 12:33:59 -08:00
Alexander Rose
99471d2a7b add xray shading edge fallof parameter 2021-01-30 12:32:20 -08:00
Alexander Rose
45d249b71a log renderItemId in debug mode 2021-01-30 11:23:46 -08:00
Alexander Rose
1382edd81c improved trackball rotate on wide canvases 2021-01-30 11:23:15 -08:00
dsehnal
89a6102f8d 1.2.13 2021-01-30 14:49:17 +01:00
David Sehnal
163929477e Merge pull request #106 from molstar/cylinders
Cylinders geomery and link visual improvements
2021-01-30 14:45:26 +01:00
dsehnal
c10a8369e8 Canvas3d: force render on viewport resize 2021-01-30 14:10:50 +01:00
dsehnal
8fbba52de8 PD.normalizeParams update 2021-01-30 13:41:22 +01:00
dsehnal
ca3174b2c3 Fix computeUnitGaussianDensity 2021-01-30 13:08:42 +01:00
dsehnal
b9864fba80 Fix loci label custom text 2021-01-27 18:01:47 +01:00
Alexander Rose
f8e9bc1e7f limit max resolution for (gpu) gaussian-surface 2021-01-24 21:45:01 -08:00
Alexander Rose
f79f1507f7 dispose of volume & repr associated textures 2021-01-24 21:44:02 -08:00
Alexander Rose
61ab205a5d recreate visuals based on param changes
- impostor/mesh (spacefill, ball+stick, ellipsoids)
- gpu/cpu mc (isosurface, gaussian surface)
2021-01-23 16:57:21 -08:00
Alexander Rose
2c65260a4f Merge remote-tracking branch 'origin/param-normalization' into cylinders 2021-01-23 16:39:23 -08:00
Alexander Rose
0597a1ef24 Merge branch 'master' into cylinders 2021-01-23 16:35:18 -08:00
Alexander Rose
8d6557e51c moved label-options out of palette-params 2021-01-23 16:25:32 -08:00
Alexander Rose
5cff0dff3d wip, gpu mc
- int float div
- clamp 2d texture access to 3d grid bounds
2021-01-23 15:46:29 -08:00
Alexander Rose
93206e76d7 fix DVR with orthographic projection 2021-01-23 13:36:28 -08:00
dsehnal
40933a8539 1.2.12 2021-01-20 14:18:55 +01:00
dsehnal
989800783b dihedral visual update 2021-01-20 14:13:57 +01:00
dsehnal
d83b0d2c4d better typing for PD.MultiSelect & StructureMeasurementManager visualParams support 2021-01-20 10:30:59 +01:00
dsehnal
5e5d5a63dc mol-plugin: subscribe to events in initViewer
+ handle plugin resize in main render loop
2021-01-19 15:09:57 +01:00
Alexander Rose
b1755604e2 fix webgl context loss handling 2021-01-18 19:48:55 -08:00
Alexander Rose
e58da9b574 add Canvas3DContext
- can be used to create multiple Canvas3D objects
2021-01-18 11:30:42 -08:00
dsehnal
f5d6498601 ParamDefinition.normalizeParams tweaks 2021-01-17 11:50:15 +01:00
dsehnal
07f351888f add doNotForceWebGLContextLoss option 2021-01-17 11:15:15 +01:00
Alexander Rose
4588fdd5d5 wip, gpu mc webgl1 tweak 2021-01-16 17:24:26 -08:00
Alexander Rose
c3b32baf6a wip, gpu mc & vol isosurface 2021-01-16 15:18:41 -08:00
Alexander Rose
b8d60cea9b Canvas3d.fromCanvas attribs
- simplified antialias handling
- expose preserveDrawingBuffer
2021-01-16 13:20:32 -08:00
Alexander Rose
25b8956712 moved rgba/float conversion to glsl chunks 2021-01-16 11:40:54 -08:00
Alexander Rose
7015309db6 added more interesting pdb entries 2021-01-16 11:37:48 -08:00
Alexander Rose
aad861db37 use var in webpack version template 2021-01-16 11:37:20 -08:00
Alexander Rose
ae7811705d fix volume isosurface picking 2021-01-16 11:35:55 -08:00
dsehnal
7e26dac50b 1.2.11 2021-01-15 18:40:05 +01:00
dsehnal
75f43d038c PluginConfig.General.ForceWboitAntialiasing 2021-01-15 18:37:29 +01:00
dsehnal
b9ba940510 dihedral visual updates
- fix "extenders"
- add "arms" visual
2021-01-15 15:10:33 +01:00
dsehnal
35603baaaa 1.2.10 2021-01-15 13:28:01 +01:00
dsehnal
19dc32c491 Canvas3D.dispose lose webgl context 2021-01-15 13:21:34 +01:00
dsehnal
95997e6a61 PickScale plugin config 2021-01-15 12:54:02 +01:00
dsehnal
03e19a2ad7 css tweaks 2021-01-15 12:50:30 +01:00
dsehnal
765b133369 Merge branch 'master' into cylinders 2021-01-13 16:50:11 +01:00
dsehnal
703e729514 PD.normalizeParams options 2021-01-13 16:49:33 +01:00
dsehnal
b0216c4ce6 Merge branch 'master' into cylinders 2021-01-13 16:10:39 +01:00
dsehnal
6796fc1cd4 use PD.normalizeParams in canvas3d.setProps 2021-01-13 16:09:48 +01:00
dsehnal
87c504f9a8 mol-state: use PD.normalizeParams first time a cell is evaluated 2021-01-13 15:59:50 +01:00
dsehnal
2e770cb733 ParamDefinition.normalizeParams 2021-01-13 15:44:05 +01:00
David Sehnal
9f440f68e0 Merge pull request #118 from JonStargaryen/modelserverfixes
ModelServer: filename parameter
2021-01-13 12:57:01 +01:00
JonStargaryen
40028b27ba cleanup 2021-01-12 10:47:18 -08:00
JonStargaryen
4676ad8738 gracefully handle empty param category 2021-01-12 10:44:47 -08:00
JonStargaryen
e1c7833826 filename param 2021-01-12 10:25:55 -08:00
Alexander Rose
dd1bca0fee Merge branch 'master' into cylinders 2021-01-10 00:45:18 -08:00
Alexander Rose
c38ab2c638 use existing gl context for capability testing
- fixes unit-test
2021-01-10 00:38:16 -08:00
Alexander Rose
459c5aa5a7 wip, gpu mc
- reduced texture sizes
- structure gaussian surface texture-mesh
2021-01-10 00:17:41 -08:00
Alexander Rose
b8bf07d393 byto-count info for webgl resources 2021-01-10 00:09:20 -08:00
Alexander Rose
ea87ac2094 add and use gpu half-float support
- add texture_half_float, texture_half_float_linear, color_buffer_half_float
- use in multie-sample, gaussian-density
2021-01-10 00:07:12 -08:00
Alexander Rose
e1b830a59d improved atomicDetail preset 2021-01-09 14:23:19 -08:00
Alexander Rose
41e1ac76c0 improve peptide entity-subtype derivation 2021-01-09 12:51:34 -08:00
Alexander Rose
98b118fd1e parse pdb conect records
- heuristic to test if list of bonds is exhaustive to skip auto-bonding
2021-01-09 12:49:44 -08:00
Alexander Rose
5f691913e4 fix webgl1 screendoor transparency
- webgl1 only allows const array access
2021-01-09 11:16:32 -08:00
Alexander Rose
26e2516097 fix traceOnly param getting ignored 2021-01-09 11:15:13 -08:00
dsehnal
3d2e4115ed 1.2.9 2021-01-08 15:17:42 +01:00
dsehnal
dbce1ccb3d alpha-orbitals: ability to clamp volume values 2021-01-08 15:16:08 +01:00
David Sehnal
03aa2be978 Merge pull request #116 from JonStargaryen/modelserverfixes
ModelServer: Add option to download text files
2021-01-07 17:33:38 +01:00
JonStargaryen
8dfc52e1ab cleanup 2021-01-07 14:49:32 +01:00
JonStargaryen
6058179f10 cleanup 2021-01-07 14:36:11 +01:00
JonStargaryen
ea9e25b03c ResultWriterParams 2021-01-07 14:30:01 +01:00
JonStargaryen
d60c3ddce3 handle non-string params faithfully 2021-01-07 14:21:32 +01:00
JonStargaryen
724e79bddf version/changelog 2021-01-07 12:53:44 +01:00
JonStargaryen
2de61215c4 better description 2021-01-07 12:35:16 +01:00
JonStargaryen
e783d9a9f1 Merge remote-tracking branch 'upstream/master' into modelserverfixes 2021-01-07 12:31:26 +01:00
JonStargaryen
e9e971d4f3 lock 2021-01-07 12:31:20 +01:00
JonStargaryen
96dea14cb1 cleanup 2021-01-07 12:26:50 +01:00
JonStargaryen
04fc157340 ModelServer: Save As param 2021-01-07 11:53:24 +01:00
dsehnal
cfc24fa99e SequenceView: fix polymers & everything modes 2021-01-07 11:22:57 +01:00
dsehnal
19c1088209 1.2.8 2021-01-06 15:29:29 +01:00
dsehnal
ee6c2e0841 canvas3d: add commited event 2021-01-06 15:22:54 +01:00
Alexander Rose
20ee659b00 wip, gaussian surface
- fix webgl1 gaussian volume broken
- fix 2d volume slice missing first row
- use scissor test to avoid useless calculations
- reduce radius for which gaussians are calculated
-
2021-01-03 15:15:03 -08:00
Alexander Rose
b6514a4a50 fix structure bond count calculation 2021-01-03 14:57:18 -08:00
Alexander Rose
07b8bdb951 noClip option for renderables
- exclude handle and axes helper from clip objects
2021-01-03 14:56:40 -08:00
Alexander Rose
afd18cabd4 tweaked renderer params to enable AO by default 2021-01-03 14:42:35 -08:00
Alexander Rose
1117ce05d5 improved picking alpha and fog shader code 2021-01-03 14:37:49 -08:00
Alexander Rose
fc15e952bf fix smaa viewport handling 2021-01-03 14:34:34 -08:00
dsehnal
249e5a3e0b SequenceView improvements
- add ability to show all polymers/chains at once
- do not redraw when structure list doesn't change (saves 3 re-renders for a typical structure load)
2020-12-29 16:29:16 +01:00
Alexander Rose
4bfe3f6bde postprocesing tweaks
- better distingush objects close to far plane from background
- draw outlines last to be cleaner
- allow larger AO radius
2020-12-21 22:38:30 -08:00
Alexander Rose
75b7e0b4d9 support to 'invert' clip object test
- e.g. to cut away everything but a sphere
2020-12-20 20:06:52 -08:00
Alexander Rose
ee4ce2fd7a simplify copy shader 2020-12-20 14:35:17 -08:00
Alexander Rose
db0aa12e75 Merge branch 'master' into cylinders 2020-12-20 13:45:50 -08:00
Alexander Rose
6d2578d3d0 repr/geo param update fixes
- texture-mesh geo
- text visual
2020-12-20 13:40:33 -08:00
Alexander Rose
99d61f48b4 Merge branch 'master' into cylinders 2020-12-20 13:00:18 -08:00
Alexander Rose
146022dc12 wip, gaussian surface & mc
- fix iso-level
- reuse gpu resources for mc (patched many memory leaks)
2020-12-20 12:55:54 -08:00
Alexander Rose
92730cad01 Merge branch 'master' into cylinders 2020-12-19 21:33:24 -08:00
Alexander Rose
d6b68b06da Merge branch 'cylinders' of https://github.com/molstar/molstar into cylinders 2020-12-19 21:31:16 -08:00
Alexander Rose
b174fbf0c6 postprocessing tweaks and fixes/improvements
- AO defaults: darker, larger radius
- handle transparent bg for outlines & AO
- handle fog for AO
- fix fog for outlines
- fragmentDepth for fog (instead of camera distance)
- webgl1 compat
2020-12-19 21:26:06 -08:00
Alexander Rose
fde1557955 Merge branch 'postprocessing' into cylinders
- added AntialiasingPass
2020-12-19 17:38:57 -08:00
AronKovacs
24a0753881 fix fog for outlines 2020-12-19 21:59:56 +01:00
dsehnal
5664e1d8be 1.2.7 2020-12-19 11:53:09 +01:00
dsehnal
4881a41256 set default camera radius/max = 0 2020-12-19 11:46:00 +01:00
dsehnal
235e41ee03 PluginConfig EnableWboit => true 2020-12-19 11:26:13 +01:00
AronKovacs
94d293a4d3 renaming, better defaults, ao bias, better outline thresholding, whitespace changes 2020-12-18 16:10:37 +01:00
AronKovacs
40f1ca207f replaced placeholder value with the correct uniform 2020-12-16 17:58:00 +01:00
AronKovacs
926fb38c1e added contributors 2020-12-16 17:43:20 +01:00
AronKovacs
5a14fcabc5 small ssao changes, e.g. better vec2 noise 2020-12-16 17:38:38 +01:00
AronKovacs
560e40773f added renderBlended postprocessing 2020-12-16 17:21:26 +01:00
AronKovacs
6561732f57 Merge remote-tracking branch 'upstream/master' into postprocessing 2020-12-15 13:30:41 +01:00
AronKovacs
b45cf206fd postprocessing init 2020-12-15 13:27:11 +01:00
Alexander Rose
70e07be64d anvil tweaks
- remove unused/broken bilayer-spheres visual
- ensure anvil prop is calculated
2020-12-12 18:23:07 -08:00
Alexander Rose
f3013f0e46 smaa param tweaks 2020-12-12 17:31:27 -08:00
Alexander Rose
2e7041bd78 remove debug statement 2020-12-12 17:29:19 -08:00
Alexander Rose
5d0447c9bb enable wboit by default 2020-12-12 16:20:59 -08:00
Alexander Rose
9eba0b91a8 add smaa antialiasing option (new default) 2020-12-12 16:13:53 -08:00
Alexander Rose
58bc6722a9 moved fxaa to separate pass 2020-12-12 15:42:56 -08:00
Alexander Rose
1acfed3233 naming and doc tweaks 2020-12-12 15:39:45 -08:00
dsehnal
8147b3aa34 1.2.6 2020-12-10 10:46:26 +01:00
dsehnal
b21552ff36 fix wboit rendering when updating alpha 2020-12-10 10:44:35 +01:00
dsehnal
c683cbe962 1.2.5 2020-12-09 15:06:17 +01:00
dsehnal
bd270e4428 fix pdbx_PDB_ins_code "prefixed" names in CIF exporter 2020-12-09 15:03:41 +01:00
dsehnal
23d942d8a5 updated packages 2020-12-09 14:55:25 +01:00
Alexander Rose
cbcd6b99d2 Merge pull request #107 from molstar/remove-3dg
remove 3dg in favor of g3d (#93)
2020-12-05 20:44:16 -08:00
Alexander Rose
ee5c098a9f remove 3dg in favor of g3d (#93) 2020-12-05 20:38:50 -08:00
Alexander Rose
070a15d679 antialiasing related tweaks (combat blurriness)
- increase default line and point size
- reduce subpixel quality in fxaa
2020-12-05 16:02:08 -08:00
Alexander Rose
befa5174f8 cylinder impostors for bonds
- inter/intra bonds
- ball & stick, ellipsoids
- new link visual helper
2020-12-05 15:49:59 -08:00
Alexander Rose
d6c4366f40 link visual helper improvements
- more configurable dashes
- better cap handling
2020-12-05 15:28:22 -08:00
Alexander Rose
181cfefa63 use bond location for repr bond iterator
- fix themes to handle Bond.Location (some did not)
2020-12-05 15:22:04 -08:00
Alexander Rose
0e7c885961 fix typo, remove unused code 2020-12-05 15:17:14 -08:00
Alexander Rose
d58e90d93f add cylinders geometry and shader 2020-12-05 15:15:29 -08:00
David Sehnal
cd872b47e6 1.2.4 2020-12-03 15:30:30 +01:00
David Sehnal
2683c5b318 Merge pull request #105 from molstar/gpu-grid
GPU grid 3d computation wrapper
2020-12-03 15:24:43 +01:00
David Sehnal
c71f60a164 ParamDefinition.DataRef 2020-12-03 15:21:42 +01:00
David Sehnal
881cbc1947 tweaks 2020-12-03 13:54:51 +01:00
David Sehnal
f3e7febbd1 Merge branch 'master' of https://github.com/molstar/molstar into gpu-grid 2020-12-03 06:33:19 +01:00
David Sehnal
e68ad13031 createGrid3dComputeRenderable yieldPeriod param 2020-12-02 12:29:01 +01:00
Alexander Rose
7fbbe1e63a representation state and hightlight fixes
- recreate state when repr changes
- take repr into account for non-hover hightlights (eg from state tree)
2020-12-01 17:48:40 -08:00
Alexander Rose
a5ca72af3c postprocessing tweaks and fixes
- fix missing enable scissor state
- better antialiasing defaults
- always allow fxaa
2020-12-01 17:46:51 -08:00
David Sehnal
1ce6641eb3 grid3d-compute util code 2020-12-01 20:58:27 +01:00
David Sehnal
5dc413ab8c wip grid3d renderable 2020-12-01 19:33:05 +01:00
David Sehnal
50b615e86c 1.2.3 2020-11-28 14:50:15 +01:00
David Sehnal
5b4c6743e7 GlobalModelTransformInfo
- support in volume streaming
- export in ModelServer if transform param is present
2020-11-28 14:46:58 +01:00
Alexander Rose
99a3906978 1.2.2 2020-11-26 11:17:22 -08:00
Alexander Rose
981db34736 Merge branch 'master' of https://github.com/molstar/molstar 2020-11-26 11:12:35 -08:00
Alexander Rose
c079a8c5a8 fixed triple linkstyle in visuals
- was ignored
2020-11-26 11:12:11 -08:00
Alexander Rose
ad70adf6ce improved & fixed fxaa
- enable linear texture interpolation to actually do subpixel fetches...
- higher quality fxaa profile with edge exploration
- exposed parameters
- enable during temproal multi sampling
2020-11-26 11:11:14 -08:00
David Sehnal
89110b52bd copyright info 2020-11-26 15:55:48 +01:00
David Sehnal
8a69f050a6 1.2.1 2020-11-26 15:28:12 +01:00
David Sehnal
9e38a44406 lint 2020-11-25 19:49:38 +01:00
David Sehnal
3514ab23c3 remove unused import 2020-11-25 17:08:08 +01:00
David Sehnal
b59e3c383d tweak 2020-11-25 17:05:38 +01:00
David Sehnal
eeba565d78 alpha-orbitals: fix async computation 2020-11-25 17:05:12 +01:00
David Sehnal
687e54cc87 alpha-orbitals: density support 2020-11-25 16:27:42 +01:00
David Sehnal
ac73939440 alpha-orbitals: data model improvements 2020-11-25 15:32:15 +01:00
David Sehnal
7a3eb8d03f fix Canvas3dInteractionHelper.leave 2020-11-25 11:00:05 +01:00
David Sehnal
3d26904e0b Merge branch 'master' of https://github.com/molstar/molstar into alpha-orbitals-density 2020-11-25 10:52:09 +01:00
Alexander Rose
468e14bc35 add fxaa option to postprocessing pass 2020-11-25 01:50:04 -08:00
David Sehnal
e2dc61212e alpha orbitals: density proof of concept 2020-11-24 15:12:53 +01:00
David Sehnal
aa911ad4bc viewer loadAllModelsOrAssemblyFromUrl options 2020-11-24 10:34:12 +01:00
Alexander Rose
bb5494264c wboit tweaks and fixes
- disable by default for now (until we settly on aa option)
- fix depth repcision issue in large scenes
- fix wrong depth tex bound
- undo pixelScale change as it was not doing anything
2020-11-23 23:47:54 -08:00
David Sehnal
c0116a3baa fix geometry quality access on empty structures 2020-11-23 22:38:29 +01:00
David Sehnal
9c7497b447 canvas3d: camera reset take 3 2020-11-23 22:31:37 +01:00
David Sehnal
fa3a79fdeb fix canvas3d camera reset condition 2020-11-23 22:21:33 +01:00
David Sehnal
2987240df4 canvas3d: do not autoreset camera if the "breaking" sphere mutually overlaps with current camera sphere 2020-11-23 22:11:35 +01:00
David Sehnal
17a1640da5 1.2.0 2020-11-23 14:11:05 +01:00
David Sehnal
a86da8ee11 mp4 encoder fixes 2020-11-23 14:04:48 +01:00
David Sehnal
20e373115d add xrayShaded option to orbital visuals 2020-11-23 13:33:28 +01:00
David Sehnal
531260fbc5 fix screenshot autocrop with transparent bg 2020-11-23 12:56:54 +01:00
David Sehnal
47a3dfcef9 enable wboit by default, use devicePixelRatio by default 2020-11-23 12:54:31 +01:00
Alexander Rose
c5ca51fd80 Merge branch 'master' into wboit 2020-11-21 23:30:37 -08:00
Alexander Rose
2f2e44c032 added xray-shaded option
- mesh geometry
- direct-volume geometry
- spheres geometry
2020-11-21 23:04:13 -08:00
Alexander Rose
26acb37098 remove transparency variant
- keep only single layer screndoor transparency
- fallback if wboit is not available
2020-11-21 22:06:35 -08:00
Alexander Rose
466308cde8 transparent object rendering improvement
- changed output to be pre-multiplied alpha
- point and text tweaks
- better handle opaque vs transparent volumes in blended rendering
2020-11-21 21:56:32 -08:00
Alexander Rose
dc9af9d8b0 fix drawing buffer uniform assignment
- fixes issues with texture fetches when size differs from canvas size
2020-11-21 11:25:41 -08:00
Alexander Rose
c17bfd65e7 ensure subtype assignment for all entities, #100 2020-11-21 11:13:15 -08:00
Alexander Rose
6de07ab8c2 interaction improvements
- add page xy to click event
- check if inside viewport before hover event
2020-11-21 11:11:59 -08:00
David Sehnal
0b8aab802c StateSelection improvements
- add findAncestor
- add findAncestorOfType
- add findRoot
2020-11-21 12:55:35 +01:00
David Sehnal
13f28fbe33 symmetryColor representation preset option 2020-11-19 14:18:20 +01:00
David Sehnal
2eda679966 Revert "Merge pull request #98 from AronKovacs/wboit"
- Move to a separate branch while issues are fixed.
2020-11-19 13:10:53 +01:00
David Sehnal
35c778b644 fix use-behavior bug 2020-11-19 11:48:09 +01:00
David Sehnal
96f8ba5a80 Merge pull request #98 from AronKovacs/wboit
Wboit
2020-11-18 11:38:00 +01:00
AronKovacs
0daaa94958 fix tests 2020-11-17 16:15:14 +01:00
AronKovacs
e672503fda fog patch by arose 2020-11-17 16:05:17 +01:00
AronKovacs
4d86c9e0ae renaming and bug fixes 2020-11-16 18:08:27 +01:00
AronKovacs
80fbc474f6 Merge pull request #2 from arose/wboit
wip, wboit integration
2020-11-16 13:50:45 +01:00
AronKovacs
dacdc6abfc Merge branch 'wboit' into wboit 2020-11-16 13:50:31 +01:00
Alexander Rose
58bc8b58de wip, wboit integration 2020-11-15 19:41:25 -08:00
AronKovacs
07ead670dd split drawpass._render() into _renderStandard() and _renderWboit() 2020-11-15 18:03:26 +01:00
David Sehnal
00fd760f71 1.1.33 2020-11-14 13:59:46 +01:00
David Sehnal
a71186905d animation improvements/fixes
- added AnimateStateSnapshots
- added "getAnimationDuration" to exportable animations
2020-11-14 13:38:39 +01:00
AronKovacs
a7e0524d01 Merge pull request #1 from arose/wboit
tweaks and fixes
2020-11-14 12:50:34 +01:00
David Sehnal
7d7c1241d4 fix undefined navigator.clipboard 2020-11-14 10:49:56 +01:00
Alexander Rose
1f6e928d78 Merge branch 'master' of https://github.com/molstar/molstar into wboit 2020-11-13 22:23:16 -08:00
Alexander Rose
9bc256bdab refactored wboit into seperate pass 2020-11-13 22:19:06 -08:00
Alexander Rose
734096260d add null-texture and use for tDepth 2020-11-13 20:52:42 -08:00
Alexander Rose
1b4b6f9435 add GlobalTextureSchema missing from renderables 2020-11-13 20:51:27 -08:00
David Sehnal
54fe5c85d6 1.1.32 2020-11-13 20:31:54 +01:00
David Sehnal
f336891bf3 Merge pull request #97 from molstar/mp4-export
MP4 Export
2020-11-13 20:27:28 +01:00
David Sehnal
d2a3c9c61f Merge branch 'master' of https://github.com/molstar/molstar into mp4-export 2020-11-13 20:24:48 +01:00
David Sehnal
6968959fe2 mp4 encoder fix background reset 2020-11-13 19:18:13 +01:00
David Sehnal
7749fe5000 fix encoder viewport check 2020-11-13 16:44:25 +01:00
David Sehnal
bf45d2df5d draw screenshot preview at ~8fps 2020-11-13 15:38:48 +01:00
David Sehnal
b2222844ae redraw preview on param change 2020-11-13 15:28:28 +01:00
Aron Kovacs
3d21f1ecc6 patch and background transparency 2020-11-13 15:01:57 +01:00
Alexander Rose
cde280de60 Merge pull request #96 from JonStargaryen/modelserverfixes
handle metal ions correctly for ModelServer ligand export
2020-11-12 22:02:25 -08:00
David Sehnal
9b415ddff2 screenshot frame touch support 2020-11-12 22:43:44 +01:00
David Sehnal
906c3ac2b6 screenshot fixes 2020-11-12 21:29:39 +01:00
JonStargaryen
498611d4d4 version & CHANGELOG 2020-11-12 12:02:25 -08:00
JonStargaryen
a11bc73d68 consistency 2020-11-12 11:52:10 -08:00
JonStargaryen
9616ae5d63 handle metal ion ligand export 2020-11-12 11:50:36 -08:00
Aron Kovacs
c81476d2a7 bug fixes and wboit for text and images 2020-11-12 18:31:09 +01:00
David Sehnal
397f001352 copy screenshot workaround for browsers without ClipboardItem support 2020-11-12 18:18:50 +01:00
Aron Kovacs
7edf274477 bug fixes and reenable rendering of the helpers 2020-11-12 17:13:24 +01:00
David Sehnal
3c1a26c4f5 basic overlay task support 2020-11-12 14:55:19 +01:00
David Sehnal
1c695846d5 mp4 animation export wip 2020-11-12 14:29:10 +01:00
David Sehnal
a4c6d1e0e6 mp4 export extension wip 2020-11-12 12:20:07 +01:00
David Sehnal
e51fe83800 screenshot controls 2020-11-12 11:56:41 +01:00
David Sehnal
316076d81e screenshot: autocrop 2020-11-12 09:50:46 +01:00
Aron Kovacs
4073055d8d better direct volume frag depth 2020-11-11 22:32:44 +01:00
David Sehnal
c6e0ec1c06 screenshot cropping 2020-11-11 20:33:08 +01:00
Aron Kovacs
49aaa48e6e bug fixes 2020-11-11 18:53:15 +01:00
David Sehnal
0eb882883e screenshot perf improvements 2020-11-11 17:24:12 +01:00
David Sehnal
a6c25551dd screenshot: copy to clipboard 2020-11-11 15:17:19 +01:00
David Sehnal
0a3f73860a mp4 encoder wip 2020-11-11 14:17:52 +01:00
David Sehnal
1de159d65c ImagePass custom viewport 2020-11-10 15:32:55 +01:00
David Sehnal
e2c411fefe pass state to animation teardown 2020-11-10 15:02:00 +01:00
David Sehnal
3cf1c64e12 Camera: fix "non-invertible-matrix" error when clearing state 2020-11-10 13:12:00 +01:00
David Sehnal
b159752b72 elementLabel edgecase 2020-11-10 13:08:06 +01:00
David Sehnal
0d7db59c9e Merge branch 'master' of https://github.com/molstar/molstar into mp4-export 2020-11-10 12:48:07 +01:00
David Sehnal
a8bf90a68b camera spin animation 2020-11-10 11:26:59 +01:00
David Sehnal
96aff39272 Canvas3d: tick manualDraw option 2020-11-10 09:42:51 +01:00
Aron Kovacs
a9ae08fc1f linting fixes 2020-11-09 18:03:08 +01:00
Aron Kovacs
a24f989c01 Merge branch 'master' into wboit 2020-11-09 17:58:23 +01:00
Aron Kovacs
41ff45d14c bug fixes 2020-11-09 17:54:22 +01:00
David Sehnal
6ad80bf66b mp4 encoder animation test 2020-11-09 13:55:14 +01:00
David Sehnal
eeed48a1f7 PluginAnimationLoop 2020-11-09 13:12:06 +01:00
David Sehnal
232bc0d076 wip animation loop 2020-11-09 12:51:55 +01:00
David Sehnal
ac6b87add4 wip animation loop 2020-11-09 12:28:34 +01:00
Alexander Rose
2e3bff7d48 wip, direct-volume rendering
- fix cellDim uniform
- add per unit gaussian-volume
- add option to try to jump over empty space
- fix complex structure visual not reusing renderObject
- add support for instance transforms
- only raymarch within intersection of bounding sphere a clip planes
2020-11-08 17:09:42 -08:00
Alexander Rose
bd223b4c39 added multiSample helper
- fixes multiSample pass wih more than one viewport
2020-11-08 16:00:00 -08:00
Aron Kovacs
a75dc11427 WBOIT init 2020-11-08 20:06:01 +01:00
David Sehnal
30acaffb72 Canvas3d.setCurrentTime 2020-11-06 11:58:33 +01:00
David Sehnal
2818102b8b tweak Camera.updateClip 2020-11-04 21:33:10 +01:00
David Sehnal
519e5a6f92 1.1.31 2020-11-04 20:49:51 +01:00
David Sehnal
071740e7c1 fix "zero radius" bounding sphere issue 2020-11-04 20:45:28 +01:00
David Sehnal
7aafb2f4c3 fix camera.near for small molecules 2020-11-04 19:50:35 +01:00
David Sehnal
3c72988d77 CreateOrbitalRepresentation3D.pickable option 2020-11-04 19:15:49 +01:00
David Sehnal
3c01dfbd42 mp4 export prototype 2020-11-04 14:34:24 +01:00
David Sehnal
3a5829aa3e add mp4 encoder 2020-11-04 09:38:58 +01:00
David Sehnal
ffeeddb37a debug.ts tweak 2020-11-02 21:02:23 +01:00
David Sehnal
50945493c1 fix canvas3d.setProps 2020-11-02 20:58:08 +01:00
David Sehnal
fa80c4797a 1.1.30 2020-11-02 19:19:24 +01:00
David Sehnal
650e8bf703 canvas3d.setProps fixes/improvements 2020-11-02 19:16:29 +01:00
David Sehnal
13d57737ae mol2 schema 2020-11-02 19:09:47 +01:00
David Sehnal
a6d1a3dfdd fix elements bounding spheres 2020-11-02 19:06:48 +01:00
David Sehnal
afffdc06e5 1.1.29 2020-11-02 14:59:32 +01:00
David Sehnal
80f1b1c795 volume-servery: local query add outputFilename param 2020-11-02 14:55:10 +01:00
David Sehnal
06111e2731 1.1.28 2020-11-02 10:45:48 +01:00
David Sehnal
adb49371bb fix build error 2020-11-02 10:43:01 +01:00
Alexander Rose
7b726ded20 gaussian density, render to float texture when available 2020-11-01 17:11:13 -08:00
Alexander Rose
9f85a0c840 better webgl context resource encapsulation
- added .namedComputeRenderables, .namedFramebuffer and .namedTexture
- use for shared resourced instead of storing in closure
- required to have multiple molstar webgl contexts simultaneously
2020-11-01 16:10:13 -08:00
Alexander Rose
f92755c920 factored out Camera.targetDistance 2020-11-01 14:09:16 -08:00
Alexander Rose
d141c27765 wip, direct-volume rendering
- better near/far clipping plane support
- use quality props in volume representations
2020-11-01 14:08:31 -08:00
Alexander Rose
062ac65f0f added pageX & pageY to WheelInput 2020-10-31 15:44:34 -07:00
Alexander Rose
bb420d0806 fix IndexPairBonds created with wrong count
- needs atom count (not bond count)
2020-10-31 15:42:18 -07:00
Alexander Rose
0018032423 detect AS and BR in guessElementSymbol 2020-10-31 15:40:46 -07:00
Alexander Rose
3dd48ac73c render passes refactoring
- simpler viewport handling
- shared render targets
- stereo camera fixes & improvements
2020-10-31 15:35:50 -07:00
David Sehnal
4632a6f305 Merge branch 'master' of https://github.com/molstar/molstar 2020-10-31 20:19:37 +01:00
David Sehnal
eda570d4f1 alpha-orbitals: re-enable cutoff in GPU shader 2020-10-31 20:19:13 +01:00
Alexander Rose
b0127d746d add bool uniform support 2020-10-31 12:10:15 -07:00
Alexander Rose
5a66ca69c4 tweaks/fixes
- avoid using global `name` property
- set Promise return value for TS 4.1 compat
- avoid tuple type names for TS <= 3.9 compat
2020-10-31 11:37:19 -07:00
Alexander Rose
1c17277f03 picking improvements
- get 3d position from depth
- option to render an object only in color pass
2020-10-31 11:34:44 -07:00
David Sehnal
d771bdc8ff Merge branch 'master' into alpha-orbitals 2020-10-31 18:58:55 +01:00
David Sehnal
eace3f4259 alpha-orbitals: webgl1 support 2020-10-31 18:48:05 +01:00
David Sehnal
8f88da70a6 alpha-orbitals: use square texture for GPU comp 2020-10-31 18:11:34 +01:00
David Sehnal
b797be9642 alpha-orbitals: refactoring 2020-10-31 17:59:14 +01:00
David Sehnal
2395b7a10a alpha-orbitals: force CPU computation 2020-10-31 17:08:51 +01:00
David Sehnal
0764795c08 alpha-orbitals: optimization & webgl1 support 2020-10-31 16:52:09 +01:00
David Sehnal
ea8b7a1d56 viewer.loadVolumeFromUrl 2020-10-30 11:03:21 +01:00
David Sehnal
7c6827f5f5 load all models or assembly preset 2020-10-30 10:21:26 +01:00
David Sehnal
5a6f16ef8d viewer: option to disable volume streaming 2020-10-30 10:01:54 +01:00
David Sehnal
8dfdcdd0b7 alpha-orbitals: gpu surface option 2020-10-28 20:04:34 +01:00
David Sehnal
67a2594108 immediate mode slider, alpha-orbitals improvements 2020-10-28 19:16:53 +01:00
David Sehnal
871f9635e3 alpha-orbitals: controls 2020-10-28 18:49:25 +01:00
David Sehnal
25251f3546 Merge pull request #92 from lidaof/master
Add chromosome and region query for g3d format
2020-10-28 16:00:55 +01:00
David Sehnal
98824f477e Merge pull request #94 from JonStargaryen/modelserverfixes
create-table: add protonation variants to cca.bcif
2020-10-27 22:26:36 +01:00
David Sehnal
aae9a117e8 alpha-orbitals: simplify shader 2020-10-27 22:23:13 +01:00
David Sehnal
452639c3ce alpha-orbitals: unused import 2020-10-27 21:41:35 +01:00
David Sehnal
6bd45e0a9b alpha-orbitals: improvements and fixes 2020-10-27 21:28:19 +01:00
David Sehnal
be100a3ac6 alpha-orbitals: optimize iso value computation 2020-10-27 20:09:26 +01:00
David Sehnal
96a8cd789c alpha-orbitals: optimization 2020-10-27 17:37:30 +01:00
David Sehnal
d195e1dbf5 alpha-orbitals: gpu wip 2020-10-27 15:38:08 +01:00
David Sehnal
e6a8e788f5 alpha-orbitals: add unit test 2020-10-26 18:07:57 +01:00
David Sehnal
a755ed441e alpha-orbitals: data model tweak 2020-10-26 15:37:52 +01:00
David Sehnal
de8f294329 alpha-orbitals extension and example 2020-10-24 16:32:40 +02:00
Daofeng Li
021171c07d expose chroms array to G3dInfoData for later data based decoration 2020-10-23 13:36:20 -05:00
David Sehnal
013ddb72ed multisample camera update fix 2020-10-21 09:05:48 +02:00
JonStargaryen
207c226f66 naming 2020-10-20 12:57:31 -07:00
JonStargaryen
b4ff98499b avoid overiding of entries for atom data 2020-10-20 12:36:36 -07:00
JonStargaryen
8471d337a2 add protvar atoms to cca.bcif 2020-10-20 12:31:02 -07:00
David Sehnal
2f84b94227 Basic stereo rendering support 2020-10-20 18:36:20 +02:00
Daofeng Li
8dcd6063b7 update according to @arose's review 2020-10-20 00:08:08 -05:00
Alexander Rose
caefe7ba67 wip, direct-volume rendering
- volume marking
- position iterator
- trilinear position/vertex color interpolation
- fix missing update on traceOnly param change
2020-10-18 22:40:34 -07:00
Alexander Rose
ad6cebc59b canvas3d: fixes for custom pixel-scale & viewport 2020-10-18 13:46:32 -07:00
Daofeng Li
e8d2e6d806 update chain-test as @arose suggested 2020-10-18 10:15:19 -05:00
Alexander Rose
39352c40d1 fix indention 2020-10-18 00:34:40 -07:00
Alexander Rose
9994262abc Merge branch 'master' of https://github.com/molstar/molstar 2020-10-18 00:25:41 -07:00
Alexander Rose
5bcf923381 canvas3d: custom pixel-scale & viewport 2020-10-18 00:25:00 -07:00
Alexander Rose
ab5dd0b733 webgl & canvas3d helpers
- webgl.clear()
- canvas3d.pause()
- canvas3d pickScale adustable on creation
2020-10-17 12:48:01 -07:00
Alexander Rose
5a8a6310f8 webgl resource reuse improvements
- reuse common compute renderables
- add dRenderVariant to existing schema object
2020-10-17 12:18:52 -07:00
Alexander Rose
a634c7a587 adjust lines mapping/vertex indices
- to work well with position iterator for coloring
2020-10-17 11:12:37 -07:00
Alexander Rose
353c5d6d95 set TrajectoryInfo & AsymIdCount to dynamic model property
- fixes model-index coloring
2020-10-17 11:10:49 -07:00
David Sehnal
92698c486c Fix MappedControl edge case 2020-10-15 09:11:06 +02:00
Daofeng Li
898dd1161d Update g3dRegionQuery function params 2020-10-13 09:05:51 -05:00
Daofeng Li
361f289d0e Add chromosome and region query for g3d format 2020-10-13 00:53:45 -05:00
Alexander Rose
b49d036fcd wip, volume rendering
- fix, unset UNPACK_FLIP_Y_WEBGL for 3D tex
- gaussian-volume visual
- fixed, slice visual picking
- fixed, direct-volume renderable picking use depth
2020-10-12 00:35:53 -07:00
Alexander Rose
cfee9d86c0 multi-sample pass improvements & fixes
- use float rt when possible
- test color-float-buffer support
- fix, limit samples per frame
- include camera-helper scene
2020-10-11 23:01:00 -07:00
Alexander Rose
92622dfbd7 fix element loci .toExpression for multi model structures, #56 2020-10-10 16:55:01 -07:00
Alexander Rose
80c2876350 ui, guard focus entry list against too many items 2020-10-10 16:53:21 -07:00
Alexander Rose
fb99f6db8a tighter spheres geo bounding sphere 2020-10-10 16:52:32 -07:00
Alexander Rose
862f8193ef wip, direct-volume-rendering
- support for flip-sided and double-sided
- add single-layer isosurface option
- fix webgl1 depth pass not clearing
- fix slow out-of-bounds access when creating texture
2020-10-04 14:01:42 -07:00
Alexander Rose
490c6679eb add support for vertex colors
use in color theme with
- PositionLocation
- 'vertex'/'vertexInstance' granularity
2020-10-04 00:36:34 -07:00
Alexander Rose
dd278ca964 model & repr update/selection fixes and tweaks 2020-10-03 17:27:41 -07:00
Alexander Rose
0892bb24d0 geometry building improements
- add and use PrimitiveBuilder.addQuad
- avoid namespace lookups for ribbon building
- allow triangluar prism
2020-10-03 11:52:31 -07:00
Alexander Rose
83ce5e9422 add config item for state history-capacity 2020-10-03 11:50:37 -07:00
Alexander Rose
c4ba92c7cb input-observer: allow some non pritable keys 2020-10-03 11:49:53 -07:00
David Sehnal
846bdf10b0 1.1.27 2020-10-03 18:50:04 +02:00
David Sehnal
91a46ea7df another Slider2 fix 2020-10-03 18:47:53 +02:00
David Sehnal
e4ec68a86c 1.1.26 2020-10-03 18:20:04 +02:00
David Sehnal
410655052f fix Slider2 bug 2020-10-03 18:16:06 +02:00
Alexander Rose
17162e967a fix create-ion, add chem-comp-dict util 2020-09-30 23:55:35 -07:00
Alexander Rose
c119a1bc21 Merge pull request #88 from McMenemy/extract_ion_names_from_ccd
Extract ion names from ccd
2020-09-30 23:18:41 -07:00
David Sehnal
7f2e98f714 1.1.25 2020-09-30 18:29:45 +02:00
David Sehnal
82f5d8be21 Merge pull request #89 from JonStargaryen/modelserver-transform
Add transform functionality to ModelServer
2020-09-30 18:24:15 +02:00
JonStargaryen
73fa675346 version & CHANGELOG 2020-09-30 09:15:26 -07:00
JonStargaryen
1f2812b2e3 standardize QueryParamType 2020-09-30 08:56:25 -07:00
JonStargaryen
6f05179db8 remove createMat4 2020-09-30 08:38:12 -07:00
McMenemy
fc8848e97c revert release filter 2020-09-29 21:43:39 -07:00
JonStargaryen
b991102bfa rename param info 2020-09-29 12:24:22 -07:00
JonStargaryen
e3768805a6 rename to transform 2020-09-29 12:21:52 -07:00
JonStargaryen
cdb65665a6 transform 2020-09-29 11:33:05 -07:00
David Sehnal
3765bc410c 1.1.24 2020-09-29 18:58:15 +02:00
David Sehnal
69bbd76f33 mol-plugin: fix initViewer when settings canvas3d props in spec 2020-09-29 18:54:32 +02:00
McMenemy
b61b3e1115 fix linter error 2020-09-29 08:53:26 -07:00
McMenemy
835f717e47 only keep REL ions 2020-09-29 08:35:51 -07:00
McMenemy
6a35a3ece0 change date to 2020 2020-09-28 19:41:45 -07:00
McMenemy
518621a1bd add command to README.md 2020-09-28 16:28:48 -07:00
McMenemy
51acfa1dce revert package-lock.json changes 2020-09-28 16:26:46 -07:00
McMenemy
5be6c9176a move to separate script 2020-09-28 16:23:19 -07:00
David Sehnal
dfa83c94f7 ParamDefinition.ValueRef defaultRef option 2020-09-28 21:12:21 +02:00
David Sehnal
67aedd4770 ParamDefinition.ValueRef 2020-09-28 20:20:20 +02:00
David Sehnal
346eb59da9 color list value offset support 2020-09-28 14:05:42 +02:00
Alexander Rose
3195594ef3 Merge branch 'master' of https://github.com/molstar/molstar 2020-09-27 23:56:54 -07:00
Alexander Rose
489b412308 wip, direct-volume rendering
- separate pass to check against depth texture
- support precalculated normals
- shading in volume mode
- fixed orthographic projection
- fixed skewed grid (David)
- step size prop
- isosurface picking (needs more work)
2020-09-27 23:56:06 -07:00
Alexander Rose
2d0e8d4ca0 geo & repr data update tweaks 2020-09-27 12:12:11 -07:00
Alexander Rose
27f94c81a2 applied event for animation manager 2020-09-27 12:08:48 -07:00
Alexander Rose
1e865ecacc key event for input-observer 2020-09-27 12:08:27 -07:00
McMenemy
f293a02485 better arg help text 2020-09-25 20:13:33 -07:00
McMenemy
ddf00600c6 add command to README.md 2020-09-25 20:00:52 -07:00
McMenemy
88cd639493 add code generated types ion file 2020-09-25 19:37:06 -07:00
McMenemy
0a30ed45f9 first pass working extracting ion names 2020-09-25 19:17:42 -07:00
Josh McMenemy
b5b282c141 Merge pull request #1 from molstar/master
merge molstar master
2020-09-25 16:57:50 -07:00
David Sehnal
c4c60cb263 1.1.23 2020-09-25 19:45:51 +02:00
JonStargaryen
e3cf4e928e propagate 2020-09-21 15:33:10 -07:00
JonStargaryen
d8a08ef900 normalize query param 2020-09-21 13:54:22 -07:00
JonStargaryen
8b8f3bf492 query param def for transformation matrix 2020-09-21 13:28:22 -07:00
David Sehnal
3983073d6c mol-plugin: fix canvas bg color when setting partial renderer params 2020-09-21 12:07:49 +02:00
David Sehnal
82b22fa3f2 fix highlightOn in basic-wrapper example 2020-09-21 11:38:41 +02:00
Alexander Rose
8a38f73771 more approximate math functions 2020-09-19 18:13:08 -07:00
Alexander Rose
37da82b138 atomic detail preset tweaks
- handle structures with low residue to element ratio
2020-09-19 18:10:53 -07:00
Alexander Rose
dd17cb23d9 support label for file param controls; check event.key as well 2020-09-19 18:09:52 -07:00
Alexander Rose
8f3afd9f7c try use spacegroup cell to estimate structure volume 2020-09-19 11:32:17 -07:00
Alexander Rose
6e39188f0b unitcell repr attachment parameter 2020-09-19 11:31:32 -07:00
Alexander Rose
667cacea12 various structure update related fixes- fixes #87- update on hierarchy changes- fix select mark on object update 2020-09-19 11:29:02 -07:00
Alexander Rose
49f0ec981c check js files as well with eslint
- moved ts eslint config into overrides
2020-09-19 11:13:13 -07:00
David Sehnal
a60d6e9223 1.1.22 2020-09-19 11:07:33 +02:00
David Sehnal
2d111c1e25 mol-plugin: ability to ignore loci in highlight/select behavior 2020-09-19 10:55:40 +02:00
Alexander Rose
874cde4f72 1.1.21 2020-09-14 10:09:38 -07:00
David Sehnal
826318760e Canvas3DParams.camera.manualReset 2020-09-14 18:51:24 +02:00
Alexander Rose
de790051aa schema updates
- note that ncs.id has changed from string to number
2020-09-13 02:54:12 -07:00
Alexander Rose
00bf75839e Merge branch 'master' of https://github.com/molstar/molstar 2020-09-13 02:26:38 -07:00
Alexander Rose
b9d4501dcc more fine-grained model/structure/unit updates 2020-09-13 02:25:49 -07:00
Alexander Rose
46fb1789b0 trajectory cell handling improvements 2020-09-12 17:06:58 -07:00
Alexander Rose
a1e8bf841b color theme tweaks, more acurate granularity 2020-09-12 14:53:40 -07:00
Alexander Rose
6662dbfdd6 use unit/structure boundary for interactions geo 2020-09-12 14:51:36 -07:00
Alexander Rose
39b9710d16 fix unneccessary render & geo updates
- uniforms & defines
- bufferSubData instead of bufferData
- scene remove
- drawCount
- geo builder
2020-09-12 14:50:14 -07:00
Alexander Rose
4fe303da72 add missing DMPC lipid 2020-09-12 14:42:19 -07:00
Alexander Rose
0662506d35 add code to experiment with linear RGB workflow 2020-09-12 14:41:23 -07:00
Alexander Rose
ea987f5601 package script tweaks
- serve: use gzip
- state: set default working dir
2020-09-12 14:35:17 -07:00
Alexander Rose
bcae586122 math geo helpers 2020-09-12 14:34:14 -07:00
David Sehnal
e56f188a12 TypeScript 4.0 & update packages 2020-09-12 12:40:15 +02:00
David Sehnal
8fda9beb7b Merge pull request #86 from molstar/dependabot/npm_and_yarn/node-fetch-2.6.1
Bump node-fetch from 2.6.0 to 2.6.1
2020-09-11 17:23:18 +02:00
dependabot[bot]
0f50a6682b Bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-10 20:13:07 +00:00
David Sehnal
524d38c450 fix bounding box bug 2020-09-10 12:43:47 +02:00
Alexander Rose
68a2e52355 increase mediumResidueCount threshold to 5000, #85 2020-09-10 00:31:05 -07:00
David Sehnal
447d1f940f Grid.getHistogram
+ do not exlude any code from main build because it turned off VS Code features in the affected files
2020-09-09 18:38:54 +02:00
David Sehnal
1cbb59b5d0 1.1.20 2020-09-09 17:52:31 +02:00
Alexander Rose
6f5bcdef90 sphere3d extrema fixes 2020-09-08 23:54:54 -07:00
David Sehnal
f6f1c5a350 mol-model: optimize atomGroups query 2020-09-09 08:16:01 +02:00
Alexander Rose
f6545c38be 1.1.19 2020-09-08 01:38:58 -07:00
Alexander Rose
53fe73d3ee Structure.ofModel: merge consecutive water chains 2020-09-08 01:34:20 -07:00
Alexander Rose
3bf5ab1ef7 psf parser: segment name as auth asym id 2020-09-08 01:13:24 -07:00
Alexander Rose
b4813ff866 remove tryAdjustBoundary for now
- not precise enough/too costly
2020-09-08 01:12:43 -07:00
Alexander Rose
845269e9a5 tryAdjustBoundary tweaks 2020-09-08 01:10:50 -07:00
Alexander Rose
59968d92ab 1.1.18 2020-09-07 18:30:23 -07:00
Alexander Rose
d5b7cd370b wip, direct-volume rendering
- re-enabled for volume data
- fix normal calc
- support negative isovalues
- flat-shaded support
- ignore-light support
- support cell picking & marking
- support depth calculation/write
- support fog
- support interior coloring
- maxSteps loop counter as uniform in webgl2
- fix shifted coordinates and boundary issues
- improved geo/repr params
2020-09-07 18:02:07 -07:00
Alexander Rose
b4434cce17 fix picking in webgl1 for isosurface and slice 2020-09-07 17:55:04 -07:00
Alexander Rose
e73227519b factored out/moved common volume helpers
- createIsoValueParam
- eachVolumeLoci
2020-09-07 13:35:37 -07:00
Alexander Rose
f8e6d5cbfb add option to disable hardware antialiasing- wastful for direct volume rendering 2020-09-07 13:29:36 -07:00
Alexander Rose
70bde8c899 bounding sphere calculation for transformed boxes
- add Sphere.fromDimensionsAndTransform
- use for unitcell cage & volume
- precise image bounding sphere
2020-09-07 13:06:23 -07:00
Alexander Rose
361dce2b96 more precise sphere shader sizes 2020-09-07 12:55:56 -07:00
Alexander Rose
c83ce28bf4 no need for fragDepth in image shader 2020-09-05 14:43:24 -07:00
Alexander Rose
b9a3620a4c get EXT_float_blend together with EXT_color_buffer_float
- firfox warns to do that for best support
2020-09-05 14:42:44 -07:00
Alexander Rose
a939a57811 only dispatch hover event on changes
- camera, input changes
- better handle empty picking ids
2020-09-05 14:41:45 -07:00
Alexander Rose
8388ee8f1e make putty repr independent of secondary structure
- yields performance when secondary structure would need to be calculated
2020-09-05 14:37:23 -07:00
Alexander Rose
befa40f5a2 more boundary calc tweaks
- lower thresholds for using coarse calc
2020-09-04 00:18:34 -07:00
Alexander Rose
36257e2b0f fix SelectLoci on object-updated checks 2020-09-03 23:22:02 -07:00
Alexander Rose
769022e88c avoid creating unneccessary visual props objects 2020-09-03 23:20:26 -07:00
Alexander Rose
51c180a8f4 boundary calculation optimizations
- fast path for single transform renderables
- check conformation when remapping unit
2020-09-03 23:18:45 -07:00
Alexander Rose
2ffc5dc5c0 mol-ql: account for source when extending to whole residues 2020-09-03 23:14:18 -07:00
Alexander Rose
431ba01117 check if renderable transform matrix has reflection
- force double-sided draw to ensure the front is drawn
2020-09-03 23:11:03 -07:00
Alexander Rose
c6a4350b81 removed unused Canvas3D.getPixelData
- use .getImagePass instead
2020-09-02 22:22:25 -07:00
Alexander Rose
9ef8d0c9f8 fix missing camera radiusMax update 2020-09-02 22:20:25 -07:00
Alexander Rose
e7606477c2 fix wrong texture3d_from_2d_linear shader chunk path 2020-09-02 22:18:40 -07:00
Alexander Rose
de093b5472 support origin and model as reference for model unitcell representation 2020-09-02 22:14:44 -07:00
Alexander Rose
88cd9184d8 add FormatPropertyProvider.delete 2020-09-02 22:12:14 -07:00
Alexander Rose
055c169c1f add dontCompose arg to StructureBuilder.addWithOperator 2020-09-02 22:11:45 -07:00
Alexander Rose
1988275695 workaround for 1 pixel texture issues
- always use at least 2x2 textures
2020-09-02 22:10:54 -07:00
Alexander Rose
82451bff00 mol2 fixes
- handle multi model files
- fix optional column parsing
- correct type symbol assignment
2020-09-02 22:10:02 -07:00
Alexander Rose
e6fd0202a6 bond & interaction fixes
- add all inter-bond from index-pair (indexA >= indexB is handled by eachUnit loop)
- add inter contacts only once (not twice)
- allow same index contacts when between different units
- more granular each loci marking for interactions and bonds
- use bounding sphere from structure for inter bonds
2020-09-02 22:08:25 -07:00
David Sehnal
c21d84dd62 1.1.17 2020-09-01 12:58:52 +02:00
David Sehnal
f392ac21cd mol-state: transaction rethrowErrors option 2020-09-01 12:55:41 +02:00
David Sehnal
d4e5473b86 1.1.16 2020-09-01 11:45:21 +02:00
David Sehnal
760298c6bf mol-state: fix transation error reporting & improve task abort 2020-09-01 11:41:21 +02:00
David Sehnal
d949b99629 1.1.15 2020-09-01 09:48:16 +02:00
David Sehnal
fff9719e48 mol-plugin: TaskManager.requestAbortAll
+ modified requestAbort to accept taskId
2020-09-01 09:45:06 +02:00
Alexander Rose
5858a6eb19 Merge branch 'master' of https://github.com/molstar/molstar 2020-08-29 14:02:11 -07:00
Alexander Rose
46acc1b95e object controls movement helper 2020-08-29 14:00:03 -07:00
Alexander Rose
da4654b859 use device pixel ratio in trackball panning 2020-08-29 13:54:55 -07:00
Alexander Rose
32869a9a45 added drag event to canvas3d interactivity 2020-08-29 13:52:24 -07:00
Alexander Rose
4cfbccc5d6 added CPU unpackRGBAToDepth 2020-08-28 18:48:45 -07:00
David Sehnal
6301196e67 1.1.14 2020-08-28 10:46:27 +02:00
David Sehnal
0c61c2badd fix multi-model loading & intra bonds caching
- moved atomSourceIndex to a separate property outside the data so diffing works
2020-08-28 10:25:23 +02:00
David Sehnal
1207526161 1.1.13 2020-08-27 13:54:28 +02:00
David Sehnal
405d9d524f measurements & labels options 2020-08-27 13:48:03 +02:00
David Sehnal
f724717821 1.1.12 2020-08-27 12:30:05 +02:00
David Sehnal
6247efa8b6 mol-model: Unit.Atomic.tryRemapBonds 2020-08-27 12:26:20 +02:00
David Sehnal
7045545419 mol-model: check if bonds can be remapped in Unit.Atomic 2020-08-27 08:11:20 +02:00
Alexander Rose
17a0a2be6f support picking threshold with screendoor transparency 2020-08-26 20:29:03 -07:00
Alexander Rose
0e92cfa007 more acurate trackball panning 2020-08-26 20:28:26 -07:00
David Sehnal
04e17872d0 mol-repr: link cylinder offset based on atom radius 2020-08-26 16:48:04 +02:00
Alexander Rose
59255c720d 1.1.11 2020-08-25 18:49:11 -07:00
Alexander Rose
eb71e2c606 use only unit ids in inter unit graph
not units themselves, so the graph can be reused for structures with same topology but different coordinates
2020-08-25 18:44:54 -07:00
Alexander Rose
db2905ba9f ensure themes with dependencies are updated 2020-08-25 18:42:32 -07:00
Alexander Rose
d097a4abd2 use isH in ellipsoid mesh builder 2020-08-25 18:41:09 -07:00
Alexander Rose
459cfd7ab8 avoid using lookup3d when boundary is sufficient 2020-08-25 18:40:24 -07:00
Alexander Rose
317229afee Merge branch 'master' of https://github.com/molstar/molstar 2020-08-25 14:49:31 -07:00
David Sehnal
1e2f16d6b3 1.1.10 2020-08-24 08:52:23 +02:00
David Sehnal
be07c1668f Merge branch 'master' of https://github.com/molstar/molstar 2020-08-23 10:35:06 +02:00
David Sehnal
90ddb3dc34 remove Model.customData 2020-08-23 10:34:43 +02:00
Alexander Rose
f968e86387 move remapModel to structure & pass interUnitBonds 2020-08-22 23:59:21 -07:00
Alexander Rose
56639f0bda use structure.root.boundary for volume 2020-08-22 23:58:41 -07:00
Alexander Rose
8ae40bfd7c get boundary from unit (not lookup) 2020-08-22 23:58:17 -07:00
Alexander Rose
a7901c53ce added approx log 2020-08-22 23:57:20 -07:00
Alexander Rose
76f856fa4f Merge branch 'master' of https://github.com/molstar/molstar 2020-08-22 13:55:33 -07:00
Alexander Rose
63a4cda442 handle in-place structure updates in focus manager 2020-08-22 13:55:24 -07:00
Alexander Rose
603aa89609 increase threshold for tryAdjustBoundary to 5% 2020-08-22 13:54:26 -07:00
Alexander Rose
51dd388912 refactored bond & element ignore test 2020-08-22 13:54:04 -07:00
Alexander Rose
c4708f0260 add derived atomicNumber 2020-08-22 13:02:51 -07:00
Alexander Rose
dcfe2e3072 unit boundary handling improvements
- tryAdjustBoundary from previous boundary
- box3d & boundary tweaks
2020-08-22 12:34:02 -07:00
Alexander Rose
9d536fefff add oldData to in-place State.ObjectEvent 2020-08-22 12:26:55 -07:00
David Sehnal
ed69d15ee1 gaussian surface getUnitExtraRadius 2020-08-22 14:21:25 +02:00
David Sehnal
4cd7f0575e mol-model: Model.customData & G3d support improvements 2020-08-22 14:12:42 +02:00
Alexander Rose
ad1507dadf Merge branch 'master' of https://github.com/molstar/molstar 2020-08-21 11:12:49 -07:00
David Sehnal
c358259437 Improved G3d support 2020-08-21 17:28:19 +02:00
Alexander Rose
6b961c532f avoid unnecessary theme recreation 2020-08-20 17:59:23 -07:00
Alexander Rose
bb8f872a13 removed unused code 2020-08-20 17:58:04 -07:00
Alexander Rose
93df8a65cd add names to anonymous function for easier debugging 2020-08-20 17:55:59 -07:00
Alexander Rose
de9fd2fcd7 increase max allowed fps parameter 2020-08-20 17:55:09 -07:00
Alexander Rose
24ae8dfda8 use array.fill instead of for loop 2020-08-20 17:54:42 -07:00
Alexander Rose
909e4b3a9f perf improvement for intra unit bond visuals
- reorder some if statement to have common case first
- avoid no-op and fixed functions
- const enum
2020-08-20 17:54:22 -07:00
Alexander Rose
09c46447d9 approx exp, use for gaussian summation 2020-08-20 17:50:59 -07:00
Alexander Rose
239a7cc072 small perf tweak for chunked array 2020-08-20 17:49:31 -07:00
Alexander Rose
f7ccff61e0 avoid namespace lookups for better performance
- in performance critical code
2020-08-20 17:48:20 -07:00
Alexander Rose
f8a7483467 mol-geo: add cos sin cache, remove unused wave param 2020-08-20 17:44:05 -07:00
David Sehnal
0a7b3fa396 Fix gaussian surface bounding sphere radius 2020-08-20 21:57:36 +02:00
David Sehnal
e5cf8bcc04 dihedral angle label fix 2020-08-18 21:54:04 +02:00
David Sehnal
f93230ce44 1.1.9 2020-08-18 11:21:21 +02:00
David Sehnal
bdde2cea31 mol-math: IntAdjacencyGraph.areEqual, remove hashCode 2020-08-18 11:17:45 +02:00
David Sehnal
d44bb6c908 mol-model: Fast unit conformation comparison 2020-08-18 11:02:31 +02:00
David Sehnal
052e30b739 1.1.8 2020-08-18 10:14:28 +02:00
Alexander Rose
48a7ac80f5 arg fix 2020-08-17 19:10:38 -07:00
Alexander Rose
c9717c2332 avoid unneccesary marking 2020-08-17 18:58:12 -07:00
Alexander Rose
aaed0a9a63 hashCode for bonds to avoid re-creating repr
- TODO might be better solved with a unique id/version/identity check when unit bond can be reused
2020-08-17 18:57:35 -07:00
Alexander Rose
c29648ac9b more reusable units, added model.parent, finer repr updates 2020-08-17 18:51:22 -07:00
Alexander Rose
cb1f52a8f4 index-pairs bonds fixes & improvements, better cif-core bond handling 2020-08-17 18:38:39 -07:00
Alexander Rose
5f759edc1b optimized cylinder meshBuilder 2020-08-17 18:34:50 -07:00
Alexander Rose
8897261836 decoupled structure.boundary from lookup 2020-08-17 18:34:21 -07:00
David Sehnal
23b1426567 fix computeIntraUnitBonds from IndexPairBonds 2020-08-17 11:37:41 +02:00
David Sehnal
329658ff54 fix computeInterUnitBonds from IndexPairBonds 2020-08-17 07:42:32 +02:00
David Sehnal
482059cc9b first class Trajectory object
- baseline for interpolation and async fetching support
2020-08-14 12:47:41 +02:00
David Sehnal
4e509fc479 Fix clipping object angle (convert to rad) 2020-08-14 11:35:01 +02:00
David Sehnal
6b1edd9d10 basic G3D support 2020-08-13 12:56:42 +02:00
David Sehnal
d0c692fe03 1.1.7 2020-08-06 16:38:55 +02:00
David Sehnal
36ee1089a8 updated packages 2020-08-06 16:34:46 +02:00
David Sehnal
723bf3e657 model-server: 404 response on missing inputs 2020-08-06 10:38:32 +02:00
David Sehnal
dc08e524b3 1.1.6 2020-07-29 17:09:51 +02:00
David Sehnal
3ecd305adf Merge pull request #73 from JonStargaryen/chem-comp
Support export of charges, stereo flag and SYBYL atom types for ModelServer ligand queries
2020-07-29 17:06:36 +02:00
JonStargaryen
60eb42391e use isNonMetalBond 2020-07-28 12:35:59 -07:00
JonStargaryen
26f5210518 make ctx-aware 2020-07-28 12:33:56 -07:00
JonStargaryen
7b41d800c0 use for of to check non-metals 2020-07-28 12:19:50 -07:00
JonStargaryen
3aa9ef7595 rename chem_comp_bond to chem_comp_dict 2020-07-28 11:28:11 -07:00
JonStargaryen
fad5a40ec4 Merge remote-tracking branch 'upstream/master' into chem-comp 2020-07-28 11:27:18 -07:00
JonStargaryen
58e0ba016e rename to atoms/chem_comp and bonds/chem_comp 2020-07-28 11:20:01 -07:00
JonStargaryen
b8f168ebf5 iterators 2020-07-28 10:42:41 -07:00
JonStargaryen
560c26c73f wip mol2 2020-07-27 10:34:35 -07:00
JonStargaryen
73ada6b1f1 rewire mol/sdf 2020-07-27 10:27:30 -07:00
JonStargaryen
4f2cee3b56 introduce map, ditch getLabel 2020-07-27 09:36:57 -07:00
David Sehnal
ad6975c99d 1.1.5 2020-07-27 13:37:10 +02:00
David Sehnal
bea462b8b2 Fix servers build error 2020-07-26 20:52:22 +02:00
David Sehnal
5652fa55db updated packages 2020-07-23 12:27:09 +02:00
David Sehnal
d2208a0814 mol-plugin: createPluginAsync, initial Canvas3DProps in PluginSpec 2020-07-22 12:47:34 +02:00
David Sehnal
62a456ce82 mol-plugin-state: support ArrayBuffer/Uint8Array raw binary data 2020-07-22 12:23:19 +02:00
David Sehnal
bef1142a31 1.1.4 2020-07-21 22:37:29 +02:00
David Sehnal
8e07de62dc fix auth_comp_id property access 2020-07-21 22:33:37 +02:00
JonStargaryen
347b9ead6b add atomTablePath to default config 2020-07-20 11:31:28 -07:00
JonStargaryen
6d9a09620c propagate chem_comp_atom data 2020-07-20 11:28:20 -07:00
JonStargaryen
17349b8529 sybyl atom types 2020-07-20 10:16:37 -07:00
Alexander Rose
3a200fe2d7 add label_seq_id when undefined- serial no, 1-based for each chain, see #72 2020-07-17 23:36:53 -07:00
Alexander Rose
10bd513680 refactored pdb format label_seq_id handling
- leave undefined so it can be added later with hierarchy info
- see #72
2020-07-17 23:31:35 -07:00
Alexander Rose
9214c54e7d add CifField.ofUndefined 2020-07-17 23:28:40 -07:00
Alexander Rose
64da492d63 fix non-standard residue check when filed not given 2020-07-17 21:35:29 -07:00
JonStargaryen
cbb65aaaac fix missing data in bond table 2020-07-17 18:09:30 -07:00
JonStargaryen
78c9dda257 wip sybyl 2020-07-17 17:22:02 -07:00
JonStargaryen
20450e352f wip sybyl 2020-07-17 11:31:40 -07:00
JonStargaryen
9559c22858 mol2 encoder reports bonds again 2020-07-17 11:14:22 -07:00
Alexander Rose
0d39dc69f1 use label asym-id for coloring coarse models (pdbdev), fixes #69 2020-07-14 23:25:14 -07:00
Alexander Rose
1a29159dfd crystal-contacts preset, color theme tweaks 2020-07-14 23:10:40 -07:00
Alexander Rose
8c21d3b9d9 Merge branch 'master' of https://github.com/molstar/molstar 2020-07-13 21:11:19 -07:00
Alexander Rose
24143d7078 build docking-viewer as app
not as example (so it has umd)
2020-07-13 21:11:11 -07:00
Alexander Rose
22ead527f2 expose chain-id color params to element-symbol and illustrative 2020-07-13 21:09:39 -07:00
Alexander Rose
104666a13e reset focus repr color params
to element-symbol, when no theme given
2020-07-13 21:08:02 -07:00
David Sehnal
f9ea48fd7b mol-model: atom_site.B_iso_or_equiv added to mmCIF exporter 2020-07-11 15:19:25 +02:00
JonStargaryen
80598dc102 typo 2020-07-10 13:16:53 -07:00
JonStargaryen
fbaaa57ca2 sybyl criteria 2020-07-10 13:16:22 -07:00
JonStargaryen
b0113d6189 mol2: charges, fix to actually use label_atom_id 2020-07-09 21:27:36 -07:00
JonStargaryen
da1fa03a5f fix mol2 substructure line 2020-07-09 21:18:19 -07:00
JonStargaryen
48d0418f0e mol writing with inline charges and chiral flag 2020-07-09 21:15:54 -07:00
JonStargaryen
cf0122ce23 add component atom 2020-07-09 17:24:43 -07:00
JonStargaryen
7216a25877 creation of charge and stereo config data 2020-07-09 17:08:34 -07:00
David Sehnal
89eae0807e docs fix 2020-07-06 15:13:13 +02:00
Alexander Rose
bfc52fbc6b 1.1.3 2020-07-03 16:04:52 -07:00
Alexander Rose
94cd5d3395 support for recommended iso value volumes
- automaticlly get for volumes with emdb entryId
2020-07-03 16:02:13 -07:00
David Sehnal
30d34584bf model-server: added optional assemblyName param to /residueInteraction 2020-07-03 18:32:59 +02:00
David Sehnal
c81166d04b 1.1.2 2020-07-02 23:09:15 +02:00
David Sehnal
3384a8630b Merge pull request #71 from JonStargaryen/sdf
SDF/MOL/MOL2 export by ModelServer
2020-07-02 23:03:00 +02:00
JonStargaryen
e39c7c4e98 move encoders to mol-io 2020-07-02 09:41:41 -07:00
JonStargaryen
38e838a352 remove label 2020-07-02 09:19:14 -07:00
JonStargaryen
cea22c0ea1 use spread 2020-07-02 09:18:52 -07:00
David Sehnal
6b73361963 mol-plugin-ui: added ViewportCanvas component 2020-07-02 14:00:26 +02:00
David Sehnal
096a4ee63e mol-plugin: volume streaming 'auto' view mode 2020-07-02 13:46:58 +02:00
JonStargaryen
28c8d6bef9 description 2020-07-01 13:28:19 -07:00
JonStargaryen
37fdbfe12a omit redundant code 2020-07-01 10:35:13 -07:00
David Sehnal
295cb84cc8 Fix docking-viewer presets 2020-07-01 12:50:24 +02:00
Alexander Rose
b5252516e3 added docking-viewer example
- expects a pdbqt and a mol2 file in the url get params
2020-06-30 21:57:25 -07:00
Alexander Rose
8e2c0327d6 added Viewport.ShowControls/Settings options to plugin config 2020-06-30 21:28:53 -07:00
Alexander Rose
eaa92b75a3 tweak, use const instead of let 2020-06-30 21:18:34 -07:00
Alexander Rose
ab81c89a9a bool param for mark repr in Highlight/SelectLoci behaviors 2020-06-30 21:18:02 -07:00
Alexander Rose
e49af151c1 use mol2 mol_name for entity name when available 2020-06-30 21:16:11 -07:00
Alexander Rose
78ca5cbb43 use chain-id coloring as base for illiustrative coloring 2020-06-30 21:15:26 -07:00
Alexander Rose
48c242d59d fix chain-id coloring for multi-model structures 2020-06-30 21:14:41 -07:00
JonStargaryen
8b4603d5a1 semicolon 2020-06-30 10:05:42 -07:00
JonStargaryen
cc6dce8845 numModels param for first model 2020-06-30 09:37:35 -07:00
JonStargaryen
b2eac8092c cleanup 2020-06-29 15:33:36 -07:00
JonStargaryen
a22362bac8 hydrogen flag 2020-06-29 15:32:37 -07:00
JonStargaryen
298b283686 revert config 2020-06-29 15:24:01 -07:00
JonStargaryen
14f4de2e3f revert config 2020-06-29 15:23:02 -07:00
JonStargaryen
9bde4c40b0 enforce first model 2020-06-29 11:22:35 -07:00
JonStargaryen
61390cb64f group by query 2020-06-29 10:00:26 -07:00
Alexander Rose
1b67bc41f5 explicit pdbqt provider
- instead of trying to deduce it during parsing
2020-06-26 22:04:27 -07:00
Alexander Rose
5b698b816e basic partial charge and pdbt support
- AtomPartialCharge format property provider
- add from PDBQT and MOL2
- color theme
2020-06-26 00:36:21 -07:00
Alexander Rose
bf9303ea80 number parser fix, handle prefixed plus sign 2020-06-26 00:33:47 -07:00
JonStargaryen
017676c148 path TODO 2020-06-25 16:31:53 -07:00
JonStargaryen
526f7700b2 cleanup 2020-06-25 16:05:43 -07:00
JonStargaryen
220e01106f lint 2020-06-25 10:35:25 -07:00
JonStargaryen
240de5b24d cleanup 2020-06-25 10:30:30 -07:00
JonStargaryen
17a001427b spelling 2020-06-25 09:57:48 -07:00
JonStargaryen
a423970b9c basic ligand writing 2020-06-25 09:53:22 -07:00
JonStargaryen
56f4c8775f cleanup 2020-06-24 16:17:31 -07:00
JonStargaryen
5ed4aa0fae SdfFile tweaks 2020-06-24 14:08:25 -07:00
JonStargaryen
4f4245b895 sdf def, reader, spec 2020-06-24 12:23:31 -07:00
JonStargaryen
bc6d2112e2 refactoring 2020-06-23 16:41:38 -07:00
JonStargaryen
3b2b87d264 tweaks to sdf output 2020-06-23 09:01:15 -07:00
Alexander Rose
181646f052 membrane orientation tweaks
- registered custom repr so it shows up in components
- some renames to make it more in line with the other extensions
- fix shapes to reuse existing geometries (fails to update on prop changes otherwise)
- added label to repr visuals on hover/highlight
- ignore light forbilayer planes mesh
- TODO: layer spheres seem to be broken (e.g. 3pqr)
2020-06-23 01:08:58 -07:00
Alexander Rose
ea5a945810 Merge pull request #47 from JonStargaryen/anvil
ANVIL / Membrane placement prediction implementation
2020-06-22 23:09:59 -07:00
JonStargaryen
7cfdc8ab1b lint 2020-06-22 14:58:03 -07:00
JonStargaryen
52e011ade9 wip query mode 2020-06-22 14:53:34 -07:00
JonStargaryen
895e2ede2d mol2 stub 2020-06-22 09:49:23 -07:00
JonStargaryen
3a25769a94 style 2020-06-22 09:26:38 -07:00
JonStargaryen
5db4b48a86 putative check for compatible encoding 2020-06-22 09:25:41 -07:00
Alexander Rose
aa2899bfbd fix sequence label for non-standard residues, #70 2020-06-21 18:54:10 -07:00
JonStargaryen
40bbd87c4e unique group check 2020-06-19 20:12:30 -07:00
JonStargaryen
fb7dd66600 cleanup 2020-06-19 17:45:00 -07:00
JonStargaryen
e12dc2b089 tweak mapping 2020-06-19 17:37:40 -07:00
JonStargaryen
78242b18c3 hydrogen handling 2020-06-19 15:28:51 -07:00
JonStargaryen
9043e4c8e1 propagate atoms only if present 2020-06-19 12:05:16 -07:00
JonStargaryen
54b5e3a0cc hydrogen option 2020-06-19 10:19:23 -07:00
JonStargaryen
b6719a2f57 always write error category 2020-06-19 09:57:23 -07:00
JonStargaryen
087d5fbb68 stub for sdf writing 2020-06-18 21:12:06 -07:00
JonStargaryen
4f60c91256 impl is-transmembrane symbol correctly 2020-06-17 15:49:33 -07:00
JonStargaryen
99415ef290 reintroduce custom prop 2020-06-17 15:02:15 -07:00
JonStargaryen
d446a2d047 fix serialmapping 2020-06-17 13:07:22 -07:00
JonStargaryen
b476f738bc style of symbol description 2020-06-17 13:05:54 -07:00
JonStargaryen
4c0d1383b2 fix label_comp_id retrieval for color themes 2020-06-16 15:24:44 -07:00
JonStargaryen
6a924bf732 ui label 2020-06-16 11:18:20 -07:00
JonStargaryen
5e1f1220af cleanup 2020-06-16 11:09:42 -07:00
JonStargaryen
d13ee0a2cc ui integration 2020-06-16 10:54:55 -07:00
JonStargaryen
826127672a move symbol 2020-06-15 17:26:25 -07:00
JonStargaryen
df8dd7278a label_comp_id move 2020-06-15 16:38:34 -07:00
JonStargaryen
cbdc4a3e9d drop DefaultQueryRuntimeTable, wip moving 2020-06-15 16:11:07 -07:00
JonStargaryen
75266ad257 merge 2020-06-15 13:30:27 -07:00
JonStargaryen
0e93374b2d add to extensions 2020-06-15 13:25:52 -07:00
JonStargaryen
8e350617f2 wip sdf 2020-06-15 12:18:10 -07:00
Alexander Rose
f6acf0a60a 1.1.1 2020-06-14 20:21:24 -07:00
Alexander Rose
7982f25a45 ignoreHydrogens option for StructureFocusRepresentation
- also updated by StructureComponentManager
2020-06-13 17:03:25 -07:00
Alexander Rose
ddafa7aac1 added todo for gro parser regarding reusing static model parts 2020-06-13 17:01:22 -07:00
Alexander Rose
65946c3045 support for multi-model gro files 2020-06-13 13:24:42 -07:00
Alexander Rose
63d699d620 lower threshold for coarse boundary helper 2020-06-13 12:39:25 -07:00
Alexander Rose
e1170c0552 fix debug helper update missing 2020-06-13 12:30:55 -07:00
Alexander Rose
97612bf044 dcd nd coordinates fixes/tweaks
- cell optional
- elementCount only on frame
2020-06-13 11:58:34 -07:00
Alexander Rose
012ac33bd5 ignore water units for inter-unit bond calculation by default 2020-06-13 11:56:54 -07:00
Alexander Rose
272e208fd4 add ion & lipid as chem_comp type, charmm ion names 2020-06-12 20:11:29 -07:00
Alexander Rose
714f0623bb tweaked repr preset to better handle md systems 2020-06-12 20:10:33 -07:00
Alexander Rose
5327962409 support ignoreHydrogens & traceOnly for points visual 2020-06-11 20:28:22 -07:00
Alexander Rose
7c3529ae30 wip testing: don't partition
- partitioning does'nt agree with trajectories of water/lipid molecules...
2020-06-10 19:53:37 -07:00
Alexander Rose
61c63df9e9 ignore H-H index-pair bonds 2020-06-10 19:52:00 -07:00
Alexander Rose
9b6fcaeb79 lines fixes and tweaks 2020-06-10 19:51:35 -07:00
Alexander Rose
ef3f035f27 allow int for ply vertex property 2020-06-10 17:46:27 -07:00
Alexander Rose
e9bc67fbf4 add .visuals to PlyProvider 2020-06-10 17:46:12 -07:00
Alexander Rose
745f2aecf8 fix props destructuring in ShapeRepresentation3D 2020-06-10 17:45:55 -07:00
Alexander Rose
eff80ad5ff line representation 2020-06-09 18:57:48 -07:00
Alexander Rose
27ef44b833 throwing in hasNdbStructNtcCategories breaks non-mmcif files 2020-06-09 17:29:29 -07:00
JonStargaryen
9d0190c11c color 2020-06-09 11:53:39 -07:00
JonStargaryen
0069687233 simplify params 2020-06-09 10:49:47 -07:00
David Sehnal
478033d405 mol-plugin: added excludeTargetFromSurroundings to Focus behavior 2020-06-09 19:27:56 +02:00
JonStargaryen
58f57d5ad2 typo 2020-06-09 09:24:24 -07:00
JonStargaryen
3f80230f4f membrane orientation behavior 2020-06-09 09:14:11 -07:00
JonStargaryen
da35f0ea16 additional membrane layer scaling param 2020-06-05 11:28:26 -07:00
JonStargaryen
72bdd5bc05 asaCutoff param 2020-06-05 11:20:16 -07:00
JonStargaryen
255cc620a5 dashedLines param 2020-06-05 11:16:07 -07:00
Alexander Rose
4753271a6d 1.1.0 2020-06-04 18:02:00 -07:00
Alexander Rose
11c7024edd tweaks for dnatco confal pyramids
- added Michal and Jiří as contributors
- add preset to annotation group
- legend for color theme
- add as extension to viewer
2020-06-02 17:49:50 -07:00
Alexander Rose
47ba54199f Merge pull request #39 from MadCatX/confal_v2
Confal v2
2020-06-02 17:29:42 -07:00
JonStargaryen
cd7643e79b params 2020-06-02 09:22:02 -07:00
Michal Malý
9a797e39e5 Add README for DNATCO extensions 2020-06-02 09:42:43 +02:00
Michal Malý
7898840003 Add a preset for DNATCO Confal Pyramids representation 2020-06-02 09:01:34 +02:00
Michal Malý
8e91cb6d54 Implement Loci getter in DNATCO Confal Pyramids representation 2020-06-02 09:01:32 +02:00
Michal Malý
893401f7c4 Implement DNATCO Confal Pyramids color theme 2020-06-02 09:00:29 +02:00
Michal Malý
021e6ffeb5 Implement DNATCO Confal Pyramids location iterator 2020-06-02 09:00:27 +02:00
Michal Malý
4080c1e005 Add DNATCO Confal Pyramids representation provider 2020-06-02 08:55:24 +02:00
Michal Malý
5063e99761 Implement basic structure of DNATCO Confal Pyramids extension 2020-06-02 08:50:38 +02:00
Alexander Rose
a59f6546c5 more comp_id fixes 2020-06-01 18:13:10 -07:00
Alexander Rose
3a737099ad add micro het todos and example pdb id 2020-06-01 17:49:47 -07:00
Alexander Rose
d1f76fd48e check all micro het comp ids for isNonStandard prop 2020-06-01 17:44:22 -07:00
Alexander Rose
437d52e484 fix comp_id issues from making it a atom prop, #66 2020-06-01 17:34:57 -07:00
JonStargaryen
610977cc08 params 2020-06-01 15:36:51 -07:00
JonStargaryen
6c78adb353 adds visuals 2020-06-01 10:25:57 -07:00
Alexander Rose
abef75bfa2 fixed sequence label regression
- show comp id only when non-standard, i.e. code is X
2020-05-30 14:47:51 -07:00
Alexander Rose
8137d4acdb fix spelling of isNonStandardCrystalFrame 2020-05-30 13:38:35 -07:00
Alexander Rose
899a186808 take micoheterogeneity into account in getUniqueResidueNames 2020-05-30 13:36:42 -07:00
Alexander Rose
bb7d3e075c change comp_id to be atom property to support micro heterogeneity 2020-05-30 13:32:49 -07:00
David Sehnal
78ba9df263 tweak 2020-05-28 19:15:21 +02:00
David Sehnal
9126416389 mol-plugin: structure repr preset updates
- added "theme" object to params
- added carbonByChainId option
- added Structure.DefaultRepresentationPresetParams plugin config option
2020-05-28 18:58:05 +02:00
David Sehnal
eef944b617 StructureFocusRepresentationParams fix 2020-05-28 14:12:08 +02:00
Alexander Rose
208cc2e48e schema updates and cli path fixes 2020-05-27 17:46:11 -07:00
David Sehnal
1522bf4ae4 package.json cli fix 2020-05-27 22:07:50 +02:00
David Sehnal
422f4567f1 full commonjs build for servers and cli tools 2020-05-27 20:37:12 +02:00
David Sehnal
6c8ae32ff9 mol-plugin: do not update focus theme if not set 2020-05-27 19:46:03 +02:00
David Sehnal
e67c610b84 mol-plugin: fix Volume streaming when clearing state 2020-05-27 19:40:00 +02:00
David Sehnal
96aa003702 mol-plugin: focusTheme params for presets 2020-05-27 19:35:53 +02:00
JonStargaryen
f6262f4be5 remove density param 2020-05-27 10:28:51 -07:00
JonStargaryen
efc5bf6a45 use set 2020-05-27 09:41:11 -07:00
JonStargaryen
cbc9801477 cleanup 2020-05-27 09:40:01 -07:00
Alexander Rose
94e21e8a3a min resolution in repr quality 2020-05-26 17:35:17 -07:00
JonStargaryen
2ed118604c cleanup 2020-05-26 15:38:15 -07:00
JonStargaryen
219d4f4d33 more generic options 2020-05-26 11:16:51 -07:00
Alexander Rose
a937e3c57d lipid query and component 2020-05-25 14:24:10 -07:00
Alexander Rose
9fe16e321e add script to generate martini lipid names 2020-05-25 14:23:55 -07:00
Alexander Rose
697e9986b4 can't ignore atoms with zero occupancy
- is too often the case when just not set
2020-05-25 14:10:40 -07:00
Alexander Rose
613cdc3145 fix building of cli tools 2020-05-25 13:46:46 -07:00
David Sehnal
a2bf489017 fix bond ordering when creating structure from Topology 2020-05-25 03:52:35 +02:00
David Sehnal
aca49b9ba5 PSF parser fix, correct topology/coordinates ordering (wip) 2020-05-25 03:12:14 +02:00
David Sehnal
11d5e301f3 xtc format support
+ build tweaks
2020-05-24 17:44:29 +02:00
Alexander Rose
2797b451fb add interesting pdb entries info 2020-05-22 17:10:03 -07:00
JonStargaryen
e82918db6a membrane orientation representation 2020-05-22 13:53:18 -07:00
Alexander Rose
e0b98f70f0 1.0.5 2020-05-22 10:30:11 -07:00
Alexander Rose
297b9bd3ff update focus color in repr presets 2020-05-22 10:27:31 -07:00
Alexander Rose
013a59857d updated packages
- set "@typescript-eslint/ban-types": "off" (TODO investigate)
- remove node 8 in travis
2020-05-22 09:34:56 -07:00
David Sehnal
0b14381255 mol-io: XTC parser 2020-05-22 16:32:32 +02:00
Alexander Rose
e1e0b0f2da 1.0.4 2020-05-21 16:20:31 -07:00
Alexander Rose
2142290300 add prd_id as entity property, treat prd as ligand 2020-05-21 16:12:09 -07:00
Alexander Rose
aeb7c7033d 0.7.1-dev.13 2020-05-21 11:15:11 -07:00
Alexander Rose
0f8540e7fc trace iterator fixes 2020-05-21 11:08:25 -07:00
Alexander Rose
f14b57fe30 don't split small single atom polymer chains 2020-05-21 11:08:04 -07:00
Alexander Rose
abfb1d5992 ensure sec struct for putty repr 2020-05-21 10:16:51 -07:00
Alexander Rose
35c53b27fe 0.7.1-dev.12 2020-05-21 00:33:50 -07:00
Alexander Rose
a7f144e810 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-21 00:31:40 -07:00
Alexander Rose
f4cb3aeed7 default coloring improvments
- changed chain-id theme to assign distinct color accros the whole scene
- made chain-id the default
- added 'many-distinct' color list
- changed element-symbol theme to use cahin-id theme for carbon coloring
- indicate focus repr with translucent halo
2020-05-21 00:31:29 -07:00
Alexander Rose
bceb044552 add structure-info behavior and plugin-wide properties
- Model.AsymIdOffset
- Model.Index
- Structure.Index
2020-05-21 00:26:44 -07:00
Alexander Rose
5e41e959f8 custom property improvements
- isHidden (always attached)
- getParams uses current props as defaultValues
- add .createSimple to model & structure property provider
2020-05-21 00:23:59 -07:00
Alexander Rose
c95d54f9cd param-definition: fix areEqual, add setDefaultValues 2020-05-21 00:21:30 -07:00
Alexander Rose
8149a25ad4 fix unit cell spelling 2020-05-20 14:13:26 -07:00
Alexander Rose
d500393501 added Model.TrajectoryInfo
- replaces model.trajectoryInfo
2020-05-20 13:07:34 -07:00
David Sehnal
9d2fa3e749 mol-plugin: StructureFocus component customization 2020-05-20 20:32:59 +02:00
JonStargaryen
ee886244fc begin separating calc and representation 2020-05-20 10:45:57 -07:00
JonStargaryen
f2557fe80a refactor membrane orientation 2020-05-20 10:01:51 -07:00
JonStargaryen
bf904a5b32 OPM stub 2020-05-20 09:53:25 -07:00
Alexander Rose
76a5ce8f14 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-20 09:34:25 -07:00
JonStargaryen
1ff83d9648 parameters 2020-05-20 09:26:09 -07:00
Alexander Rose
d121ed8b6c always calculate stats when all stats related values are zero, fixes #48 2020-05-20 01:52:23 -07:00
JonStargaryen
6c27deed74 unused import 2020-05-19 16:53:48 -07:00
JonStargaryen
7e2d15f329 unused import 2020-05-19 16:52:58 -07:00
JonStargaryen
10bd7853f3 move ASA request 2020-05-19 16:52:17 -07:00
JonStargaryen
4a7bfe953c package-lock 2020-05-19 16:34:47 -07:00
JonStargaryen
3598d13a3d package-lock 2020-05-19 16:33:51 -07:00
JonStargaryen
96ac561279 merge 2020-05-19 16:30:39 -07:00
JonStargaryen
2c81267ca7 avoid overlap 2020-05-19 16:26:21 -07:00
JonStargaryen
395fa5dad1 less sphere points 2020-05-19 16:10:39 -07:00
JonStargaryen
d15340e62e typo 2020-05-19 16:04:05 -07:00
JonStargaryen
eab4c08836 reintroduce ASA calc 2020-05-19 15:59:37 -07:00
JonStargaryen
69c5bf0094 lint 2020-05-19 15:54:55 -07:00
JonStargaryen
6c112f83e8 cleanup 2020-05-19 15:50:12 -07:00
JonStargaryen
f49c34c551 cleanup 2020-05-19 15:41:52 -07:00
Alexander Rose
3ab4458cb2 add OT1 and OT2 to protein backbone atoms- commonly used 2020-05-19 15:34:40 -07:00
JonStargaryen
ad3c07c634 use correct score 2020-05-19 14:49:47 -07:00
JonStargaryen
68525c2109 fix bugs 2020-05-19 12:07:02 -07:00
JonStargaryen
9e9851472d debugging 2020-05-19 10:31:42 -07:00
JonStargaryen
c0edb27323 circumvent repr provider for now 2020-05-18 17:30:16 -07:00
JonStargaryen
0a70783b5e draft for ANVIL impl 2020-05-18 17:29:09 -07:00
Alexander Rose
a3d101cdf9 0.7.1-dev.11 2020-05-18 17:18:46 -07:00
Alexander Rose
7255e08ecf tweak combined color ui
- use short label
2020-05-18 17:16:51 -07:00
Alexander Rose
b1bdb8e66b fix partial polymer trace curve calculation 2020-05-18 16:20:50 -07:00
Alexander Rose
49c8c7f396 focus manager: only union loci when from same structure 2020-05-18 15:21:24 -07:00
Alexander Rose
d3b4280589 ensure transformed structure is used in camera.focusLoci 2020-05-18 14:51:36 -07:00
Alexander Rose
bb9acaaa9c fix intra-interactions visual doubly transformed 2020-05-18 14:13:40 -07:00
Alexander Rose
fc10b9bf7b ensure rendering after scene changes
- add/remove/update representations
2020-05-18 11:55:15 -07:00
JonStargaryen
5fcb495d24 centroid and extent calculation 2020-05-18 11:40:27 -07:00
Alexander Rose
b2fdcba674 mouse control tweak
- always do camera center/focus on right click
2020-05-18 11:14:07 -07:00
Alexander Rose
0d01948ba9 0.7.1-dev.10 2020-05-18 08:59:56 -07:00
Alexander Rose
c4370670cb changed nucleic trace atom to O3' 2020-05-16 22:21:10 -07:00
Alexander Rose
1b19136c18 remove alpha/opacity from overpaint params
- does not play well with layers and freely assigning colors as it is per representation
2020-05-16 11:52:27 -07:00
Alexander Rose
217e983da8 add transparency to component theme 2020-05-16 11:37:54 -07:00
Alexander Rose
57338bdad1 ui, always delete full component
- one click less, undo to get back
2020-05-15 19:44:46 -07:00
Alexander Rose
0e84bf9513 component ui related tweaks and fixes
- theme reset should only act on selection
- on-screen ui act similar to controls-ui
- stick to component as name consistently
2020-05-15 19:07:05 -07:00
Alexander Rose
0be28cacdf support change of component label 2020-05-15 19:05:05 -07:00
Alexander Rose
017c608439 simplified cmara/focus binding defaults 2020-05-15 16:53:35 -07:00
Alexander Rose
20ee9496e3 add lighten/darken buttons to CombinedColorControl 2020-05-15 16:52:52 -07:00
Alexander Rose
6fd81d0961 0.7.1-dev.9 2020-05-15 12:08:03 -07:00
Alexander Rose
823a68f9bf package updates 2020-05-15 12:05:50 -07:00
Alexander Rose
deab18e805 only apply structure focus for appropriate granularity 2020-05-15 11:53:37 -07:00
Alexander Rose
19016b6730 seperated camera and repr focus more; always do camera focus with primary-alt 2020-05-15 11:39:21 -07:00
Alexander Rose
4319ae251c 0.7.1-dev.8 2020-05-15 10:25:29 -07:00
Alexander Rose
e5920e29b4 improved presets for coarse-grained structures 2020-05-15 09:58:57 -07:00
Alexander Rose
c376ddfc9d Merge branch 'master' of https://github.com/molstar/molstar 2020-05-14 22:59:46 -07:00
Alexander Rose
8fe2d3f724 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-14 22:58:32 -07:00
Alexander Rose
4d7a128528 clip object support for non mesh geometries
- spheres
- lines
- points
- text
2020-05-14 22:57:57 -07:00
Alexander Rose
663ec9695e fixes for structure focus & selection 2020-05-14 17:18:20 -07:00
JonStargaryen
5e6eb7ed49 tmp vis of asa 2020-05-14 16:38:20 -07:00
Alexander Rose
dfaa4dacdb 0.7.1-dev.7 2020-05-14 16:26:27 -07:00
Alexander Rose
f7adb8b589 fix icon typo 2020-05-14 16:24:50 -07:00
Alexander Rose
cb6b1bf19d 0.7.1-dev.6 2020-05-14 16:09:37 -07:00
Alexander Rose
27a4e1d7d9 icon tweaks 2020-05-14 16:06:38 -07:00
Alexander Rose
0cba88ad8c 0.7.1-dev.5 2020-05-14 15:50:50 -07:00
Alexander Rose
e535c4efa8 fix expected texture resource count 2020-05-14 15:49:08 -07:00
Alexander Rose
31f58ee110 export LocalStateSnapshots ui classes 2020-05-14 15:44:36 -07:00
JonStargaryen
2a9f6c88a0 modify structure-test 2020-05-14 15:25:11 -07:00
Alexander Rose
feb167dcf8 fix case of DDmanHep and LDmanHep 2020-05-14 11:19:38 -07:00
Alexander Rose
1b53ea846b added 6 more common saccharide names 2020-05-14 10:56:58 -07:00
Alexander Rose
88b9be5fd1 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-14 00:11:52 -07:00
Alexander Rose
89486ea9e2 clip objects & per group clipping
- variants: instance, pixel
2020-05-14 00:08:51 -07:00
Alexander Rose
86c09ead98 added Model helpers
- .hasCarbohydrate
- .hasProtein
- .hasNucleic
2020-05-13 16:40:22 -07:00
Alexander Rose
1f60d887a8 add gap even for consecutive residues if they are not connected 2020-05-13 14:18:24 -07:00
Alexander Rose
a672115505 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-12 19:25:46 -07:00
Alexander Rose
8f54ea137d small tweaks 2020-05-12 19:24:53 -07:00
David Sehnal
4171008c3f apps/Viewer: removed unused async 2020-05-13 02:00:17 +02:00
David Sehnal
3a9c3780ac apps/viewer tweaks
- added loadStructureFromData
- fixed loadStructureFromUrl format param
2020-05-13 01:58:42 +02:00
David Sehnal
fe55f33bd1 mol-plugin-ui: make SVG icons "static" 2020-05-13 01:37:13 +02:00
Alexander Rose
71bc88c041 0.7.1-dev.4 2020-05-12 11:35:31 -07:00
Alexander Rose
a5aadfef0e removed material-ui dependency
- included used icons as svg
2020-05-12 11:29:42 -07:00
Alexander Rose
0b368ef804 removed bcif-static option from structure download action 2020-05-12 09:34:21 -07:00
Alexander Rose
f398993d33 0.7.1-dev.3 2020-05-11 12:21:46 -07:00
Alexander Rose
b6f59ca9c3 package updates
- updated all
- removed unused jest-raw-loader
- removed unused circular-dependency-plugin
- removed unused resolve-url-loader
2020-05-11 12:18:45 -07:00
Alexander Rose
c857c17bb4 removed custom name 'deposited' for structures from model
- use 'model' instead
2020-05-11 11:24:01 -07:00
Alexander Rose
3415fe0847 0.7.1-dev.2 2020-05-09 11:54:33 -07:00
Alexander Rose
1569958a29 debug-mode url param, canvas3d console stats 2020-05-09 11:52:09 -07:00
Alexander Rose
3543faa0c2 fix snapshot loading 2020-05-09 11:03:58 -07:00
Alexander Rose
251dbf3877 0.7.1-dev.1 2020-05-08 15:30:57 -07:00
Alexander Rose
32d35efef0 add grid size to volume transform description and incr version 2020-05-08 15:27:39 -07:00
Alexander Rose
8b6428a61d 0.7.0 2020-05-08 10:45:43 -07:00
Alexander Rose
dda43370cf add setProductionMode, setDebugMode exports 2020-05-08 10:42:38 -07:00
Alexander Rose
92c1e979c0 add version to viewer module export 2020-05-08 10:36:26 -07:00
Alexander Rose
ad38a33943 basic support for aligning coarse structures 2020-05-08 10:20:09 -07:00
Alexander Rose
88c276a4c7 inline option for ToggleSelectionModeButton 2020-05-07 16:16:32 -07:00
Alexander Rose
0a3d19235d 0.7.0-dev.21 2020-05-06 20:16:36 -07:00
Alexander Rose
0d90fd1f06 tweak version script
- so the build contains the correct version number
2020-05-06 20:14:52 -07:00
Alexander Rose
02d3274e83 0.7.0-dev.20 2020-05-06 18:49:10 -07:00
Alexander Rose
2531af2b94 use cursor icon for selection mode 2020-05-06 18:02:53 -07:00
Alexander Rose
850328be4e fix coloring of bonds via overpaint 2020-05-06 17:29:55 -07:00
Alexander Rose
f8ce9cbb65 determine type of sequence for alignment 2020-05-06 15:38:51 -07:00
Alexander Rose
2af9d1cabf limit by chains superposition to polymers 2020-05-06 11:32:31 -07:00
Alexander Rose
e8d1737d40 backbone/sidechain query fixes
- handle non-polymer components in polymers
2020-05-06 10:56:01 -07:00
Alexander Rose
0328e93518 interactivity: selectOnly, only deselect for the structure of the given loci 2020-05-06 10:37:11 -07:00
Alexander Rose
8a4ab9bdb9 more selection helper fixes
- use structure from last decorator as reference
- handle that oldObj is not defined for inserts
2020-05-05 22:10:53 -07:00
Alexander Rose
410cdb193d selection manager fixes
- add removed/updated events to substructure-parent-helper
- remap selections
2020-05-05 17:03:04 -07:00
Alexander Rose
a278337b4c Merge branch 'master' of https://github.com/molstar/molstar 2020-05-05 11:08:46 -07:00
Alexander Rose
b1308de0b9 StructureSelectionManager improvements
- remap/clear referenceLoci onUpdate
- remap/clear history onUpdate
- removed unused prevHighlight
- support group-by-structure in modifyHistory
2020-05-05 11:08:05 -07:00
Alexander Rose
9705078970 set writeDepth specifically for points and text geo 2020-05-05 10:12:51 -07:00
Alexander Rose
b1ca98e945 ignore atoms with zero occupancy for bond computation
- assuming they are not actually atoms
2020-05-05 09:54:47 -07:00
David Sehnal
35054eaca9 0.7.0-dev.19 2020-05-05 17:45:21 +02:00
David Sehnal
2747c743c9 fix ElementLocationIterator.advance
- extra element was added if last unit size === 1
2020-05-05 17:41:17 +02:00
Alexander Rose
031d08a8d4 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-04 19:31:09 -07:00
Alexander Rose
7cc6c4a9c8 superposition fixes 2020-05-04 19:30:57 -07:00
David Sehnal
ff27098514 refactored PluginSpec.config 2020-05-05 00:32:43 +02:00
David Sehnal
545cd65066 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-04 22:32:53 +02:00
David Sehnal
84bfc6e7a9 VolumeStreamingControls show "update" button with "reset params" button 2020-05-04 22:31:55 +02:00
David Sehnal
2f71c4c5e4 VolumeStreamingCustomControls bounded ranges for fine grained control 2020-05-04 22:09:28 +02:00
Alexander Rose
1448f7aeb6 added PluginConfig.Structure.SizeThresholds 2020-05-04 13:00:45 -07:00
David Sehnal
79d66a5cfc revert select binding change 2020-05-04 19:42:33 +02:00
Alexander Rose
2ec19ac04c fixed rsrz label 2020-05-04 10:08:48 -07:00
David Sehnal
f62a6d4512 Selection mode: change binding to right-click
- this way the non-selection mode behavior stays the same and the right click adds functionality
2020-05-04 17:48:37 +02:00
David Sehnal
4fbcee3953 Basic Selection mode UI help
- could use some improvement
2020-05-04 17:42:31 +02:00
David Sehnal
12bb283b97 StructureSelectionManager.clear also clears selection history 2020-05-04 17:19:48 +02:00
David Sehnal
13d776c7cb Icon tweaks
- measurement remove
- selection mode
2020-05-04 17:14:40 +02:00
David Sehnal
f45b48c6e1 slider CSS fix 2020-05-04 17:00:02 +02:00
David Sehnal
ff14c94a90 PluginContext.isBusy fix + related UI fix 2020-05-04 12:08:57 +02:00
David Sehnal
0a0ef35b74 CombinedColorControl: RGB input as separate boxes 2020-05-04 11:48:45 +02:00
David Sehnal
e3dc10c085 ObjectListEditor: bugfix 2020-05-04 11:31:30 +02:00
David Sehnal
46113bf3d4 PluginStateAnimation.canApply 2020-05-03 20:43:49 +02:00
David Sehnal
0f3ef61f7d isBusy behavior bugfix
- was causing the animation button not to display if the state was loaded too fast
2020-05-03 13:10:52 +02:00
Alexander Rose
86aae08257 assembly-symmetry: dihedral cage fixes 2020-05-02 12:59:54 -07:00
Alexander Rose
06bf2c39a1 add pdb-dev download bcif encoding 2020-05-02 12:59:31 -07:00
Alexander Rose
66a23bc2a2 alignment fixes 2020-05-02 12:58:32 -07:00
David Sehnal
51e86f1e43 Superposition UI: add "toggle selection" button to help 2020-05-02 13:40:27 +02:00
Alexander Rose
78c70b3f5b structure superposition by chains or by atoms
- superposition by chains can be guided by sequence alignment
- TODO not working with already transformed structures in the general case
2020-05-01 19:08:31 -07:00
Alexander Rose
8f52ffe061 move state/session io warning to snapshot ui 2020-05-01 13:06:25 -07:00
Alexander Rose
e95b91ab84 typo 2020-04-30 15:51:54 -07:00
Alexander Rose
f4dbd66496 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-30 15:49:31 -07:00
Alexander Rose
5895df0499 tweaked elementInstances granularity label 2020-04-30 15:49:16 -07:00
Alexander Rose
6d0d88f3be added sidechain queries 2020-04-30 15:44:41 -07:00
David Sehnal
7e71428cc3 RemoteStateSnapshots: fix unmounted setState 2020-05-01 00:15:22 +02:00
David Sehnal
2e215440f7 Merge branch 'master' of https://github.com/molstar/molstar 2020-05-01 00:09:29 +02:00
David Sehnal
c04fa56c6c fixed expandConnected query, added expand to cov/metallic bonds 2020-05-01 00:09:13 +02:00
Alexander Rose
6c70b5e38f take structure volume into account in getQualityProps for resolution 2020-04-30 15:00:40 -07:00
Alexander Rose
ad9160a4a3 guard against overly high surface resolution 2020-04-30 15:00:07 -07:00
Alexander Rose
c747d3928e always apply marker in shader 2020-04-30 11:34:50 -07:00
David Sehnal
68e8d67054 mol-plugin: PluginState.dispose unregisters behaviors 2020-04-30 18:29:47 +02:00
David Sehnal
9e8fc76d28 StructureSelectionManager: loci events 2020-04-30 16:02:16 +02:00
Alexander Rose
d8970305de cellpack: cleanup
- renamed GetAllAssamblyinOne to StructureFromAssemblies
- removed GetAllAssamblyinOneStructure
2020-04-29 22:21:22 -07:00
Alexander Rose
824675a658 cellpack: split color themes 2020-04-29 21:49:37 -07:00
Alexander Rose
090ad613cc Merge pull request #35 from corredD/forkdev
Forkdev
2020-04-29 20:49:00 -07:00
Alexander Rose
ea35e09c96 focus repr carbon color tweaks 2020-04-29 14:19:45 -07:00
Alexander Rose
d8b9a1a560 basic nw sequence alignment 2020-04-29 13:54:00 -07:00
Alexander Rose
c259f58e63 make carbon color configurable in element symbol color theme 2020-04-29 13:33:31 -07:00
Alexander Rose
9d4c2a1147 support setting pdb/emdb provider in viewer index.html 2020-04-29 13:32:58 -07:00
David Sehnal
f13c3fe38b Viewport resize handling fix 2020-04-29 15:14:35 +02:00
David Sehnal
60409df145 better Viewport resize handling 2020-04-29 15:13:53 +02:00
autin
1d7321cd6f Merge branch 'master' of https://github.com/molstar/molstar into forkdev
# Conflicts:
#	src/extensions/cellpack/property.ts
2020-04-29 10:01:39 +02:00
Alexander Rose
eb68ccbf6b very basic handle-helper 2020-04-28 23:59:54 -07:00
Alexander Rose
b1ece44c49 0.7.0-dev.18 2020-04-28 17:06:40 -07:00
Alexander Rose
37ae274fb6 force bond compute for sequence positions with micro-heterogeneity
- see e.g. 3NIR
2020-04-28 17:04:13 -07:00
Alexander Rose
c900045fcd refactored sequence to handle partial structures 2020-04-28 16:34:12 -07:00
Alexander Rose
50d95ccf6a volume refactoring
- renamed VolumeData to Grid
- renamed VolumeData.data to cells
- renamed VolumeData.dataStats to stats
- added grid to Volume
- added label to Volume
- added custom props to volume
- use Volume instead of VolumeData/Grid as main object
2020-04-28 12:19:42 -07:00
Alexander Rose
c9171444eb added State.root and fix StateAction.createDefaultParams/.params 2020-04-28 10:06:22 -07:00
autin
56ea62af71 Merge branch 'master' of https://github.com/molstar/molstar into forkdev 2020-04-28 11:06:27 +02:00
Alexander Rose
9e81626928 use extensions in embedded viewer to not break compat 2020-04-27 23:35:21 -07:00
Alexander Rose
84fda6e35d 0.7.0-dev.17 2020-04-27 20:01:02 -07:00
Alexander Rose
0f758cf554 fix webpack prod build setup 2020-04-27 19:59:25 -07:00
Alexander Rose
a6605052db 0.7.0-dev.16 2020-04-27 19:54:37 -07:00
Alexander Rose
8514175da2 add build/viewer/ to published files 2020-04-27 19:53:01 -07:00
Alexander Rose
6a49427fc0 0.7.0-dev.15 2020-04-27 19:44:01 -07:00
Alexander Rose
7c18e5eb86 refactored viewer app to make it usable for simple embedded use-cases 2020-04-27 19:41:43 -07:00
Alexander Rose
2a7d258715 add Download providers to Config 2020-04-27 19:32:42 -07:00
Alexander Rose
54fb9beeee add State.Snapshots.OpenUrl 2020-04-27 19:31:55 -07:00
Alexander Rose
27ebbc50d5 allow animation button to be hidden 2020-04-27 19:31:07 -07:00
Alexander Rose
2a1b6e52b2 be clear that StateAction.params need to work without data object 2020-04-27 19:29:55 -07:00
David Sehnal
3110e82d92 0.7.0-dev.14 2020-04-28 01:03:33 +02:00
David Sehnal
4be999ce32 StructureMeasurementManagerState add options 2020-04-28 01:01:17 +02:00
David Sehnal
f0d7a4ed2a custom label for distance/angle/dihedral 2020-04-27 18:15:43 +02:00
David Sehnal
2dacfcb485 Dihedrals: fix arcs and labels 2020-04-27 18:08:22 +02:00
David Sehnal
6218cc5371 PluginComponent.subscribe returns the subscription 2020-04-27 17:24:58 +02:00
autin
b4808f2909 resampling optional. added the latest models 2020-04-27 12:32:20 +02:00
autin
1a2e9eaa84 Merge branch 'master' of https://github.com/molstar/molstar into forkdev 2020-04-27 09:24:00 +02:00
David Sehnal
056ce42097 mol-plugin: canvas3d.initialized event/behavior fix 2020-04-27 03:25:58 +02:00
David Sehnal
b14b5ca626 0.7.0-dev.13 2020-04-27 02:05:52 +02:00
David Sehnal
ffbaa944f2 tweak publish scripts 2020-04-27 02:03:47 +02:00
David Sehnal
e2ba96174a Merge branch 'master' of https://github.com/molstar/molstar 2020-04-27 02:02:31 +02:00
David Sehnal
8c5d99bb54 higher quality logo, add link, move to corner 2020-04-27 02:02:21 +02:00
Alexander Rose
b18b3be070 basic mol2 format support 2020-04-26 14:08:19 -07:00
Alexander Rose
2e69b7c419 CubeProvider tweaks, check if orbitals 2020-04-26 13:06:35 -07:00
Alexander Rose
5007f5fb72 added VolumeData.sourceData: ModelFormat 2020-04-26 13:05:39 -07:00
Alexander Rose
6fe83a9a70 cellpack: fixed pdb fallback when opm fails 2020-04-26 12:27:30 -07:00
Alexander Rose
20af084127 increate outline threshold max value 2020-04-26 11:49:54 -07:00
Alexander Rose
d6501170e6 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-26 11:34:29 -07:00
Alexander Rose
5f33364514 ignore pickable=false renderObjects completely 2020-04-26 11:34:07 -07:00
David Sehnal
7924c008fa proteopedia-wrapper: return result of snapshot.fetch 2020-04-26 20:32:12 +02:00
David Sehnal
2d2a53f28e 0.7.0-dev.12 2020-04-26 19:00:27 +02:00
David Sehnal
1f7ffabef9 added PhysicalSizeTheme.scale 2020-04-26 18:59:17 +02:00
David Sehnal
16d5c07224 0.7.0-dev.11 2020-04-26 18:04:53 +02:00
David Sehnal
2392bfb579 ParamDefinition.mergeParam fix 2020-04-26 17:54:42 +02:00
David Sehnal
b4036f576c proteopedia-wrapper tweaks 2020-04-26 13:19:10 +02:00
autin
7e3cca5780 Merge branch 'master' of https://github.com/molstar/molstar into forkdev
# Conflicts:
#	src/extensions/cellpack/model.ts
2020-04-26 11:50:33 +02:00
Alexander Rose
690d6812dc cellpack: simple cache to avoid parsing trajectories more than once 2020-04-26 00:56:03 -07:00
Alexander Rose
a44aa02f13 cellpack: support for loading zip files containing model.json and ingredients 2020-04-25 23:50:27 -07:00
Alexander Rose
65ddd6d68a Mol file description and extension tweaks 2020-04-25 15:56:13 -07:00
Alexander Rose
754025b3b1 fix bond label between identically named elements/atoms 2020-04-25 13:11:17 -07:00
Alexander Rose
f0649c5aa3 improved structure selection query labels 2020-04-25 12:51:08 -07:00
Alexander Rose
6df045211c fixed atomicDetail repr preset 2020-04-25 12:50:32 -07:00
autin
0b9371527e Merge branch 'master' of https://github.com/molstar/molstar into forkdev 2020-04-25 08:30:19 +02:00
Alexander Rose
8a00540de0 0.7.0-dev.10 2020-04-24 19:12:20 -07:00
Alexander Rose
0d78905686 icon css tweak 2020-04-24 19:11:24 -07:00
Alexander Rose
6edab203c2 0.7.0-dev.9 2020-04-24 18:49:20 -07:00
Alexander Rose
0abfdb5ee3 material icon css tweaks 2020-04-24 18:48:17 -07:00
Alexander Rose
88369158c9 0.7.0-dev.8 2020-04-24 18:01:32 -07:00
Alexander Rose
8926575283 larger volume-cell bounding-sphere radius 2020-04-24 18:00:00 -07:00
Alexander Rose
15b0288ce4 selection ui tooltip tweaks 2020-04-24 17:59:39 -07:00
Alexander Rose
28853ec19d 0.7.0-dev.7 2020-04-24 17:30:18 -07:00
Alexander Rose
e3480a076a tooltip tweaks 2020-04-24 16:28:32 -07:00
Alexander Rose
abf6452124 package updates 2020-04-24 16:20:05 -07:00
Alexander Rose
2cdd811dd3 repr preset tweaks- higher opacity since not double-side by default anymore- add snfg3d symbols for auto all-atom preset 2020-04-24 16:12:36 -07:00
Alexander Rose
be6fea39bf fog and image shader tweaks 2020-04-24 15:58:08 -07:00
Alexander Rose
ed1bc2cd07 don't set doubleSided=true when alpha<1 in getQualityProps 2020-04-24 15:57:41 -07:00
Alexander Rose
28d3d5861a add missing , BaseGeometry.CustomQualityParamInfo 2020-04-24 15:56:46 -07:00
Alexander Rose
95d3ef491f structure selection query improvements
- moved out of selection.tsx
- added queries for entities (based on entity description)
2020-04-24 13:21:30 -07:00
Alexander Rose
5c37ddfc6d add names for all elements 2020-04-24 13:20:00 -07:00
Alexander Rose
4d9e2d9c91 support title in ControlGroup and ActionMenu 2020-04-24 13:19:41 -07:00
Alexander Rose
0b1c18913d added MolScript.core.list.equal and MolScript.structureQuery.atomProperty.macromolecular.entityDescription 2020-04-24 12:35:08 -07:00
autin
7aee2d805d eslint fix 2020-04-24 15:01:21 +02:00
autin
06f03f399a lipid membrane tiles as assembly support, added ingredient colors if provided. 2020-04-24 14:57:14 +02:00
Alexander Rose
c8c2355d3e 0.7.0-dev.6 2020-04-23 20:43:57 -07:00
Alexander Rose
3d1366024d added more structure selection queries
- whole residues
- non-standard residues from current structures
- elements from current structures
2020-04-23 20:43:00 -07:00
Alexander Rose
f6964d2a66 added Structure.uniqueElementSymbols 2020-04-23 20:42:15 -07:00
Alexander Rose
de60f70af5 relax isApplicable validation-report checks 2020-04-23 16:33:41 -07:00
Alexander Rose
8f2e619162 fix assembly symmetry cage alignement 2020-04-23 16:32:44 -07:00
Alexander Rose
fbcef01c55 0.7.0-dev.5 2020-04-23 14:40:43 -07:00
Alexander Rose
641e0639d4 fix filehandle usage in server/ 2020-04-23 14:39:32 -07:00
Alexander Rose
5048573976 0.7.0-dev.4 2020-04-23 12:53:29 -07:00
Alexander Rose
78e4d8536d tweaked ligand definition 2020-04-23 12:51:52 -07:00
Alexander Rose
a01d088205 allow spaces in download id list 2020-04-23 12:48:23 -07:00
Alexander Rose
4b1d1a045d cube tweaks
- swapped visuals colors
- add orbitals flag to header
- TODO add format data to volumes as in structures
2020-04-23 11:55:58 -07:00
Alexander Rose
e2857d00b4 volume label improvements
- add cell value to loci label
- add file name to volume data objects
2020-04-23 10:51:07 -07:00
Alexander Rose
a55a71d31a bounding sphere calc for volume cell loci 2020-04-23 10:04:43 -07:00
David Sehnal
acf793f112 Tensor.Space.getCoords 2020-04-23 12:21:25 +02:00
Alexander Rose
2d58ea28ea Merge branch 'master' of https://github.com/molstar/molstar 2020-04-22 19:07:18 -07:00
Alexander Rose
b21de78eb5 camera focus for non-structure loci 2020-04-22 19:06:40 -07:00
Alexander Rose
376d4b4ee1 volume improvements and slice repr 2020-04-22 19:06:18 -07:00
Alexander Rose
e39304c7cf add dataOffset method Tensor.Space 2020-04-22 16:02:05 -07:00
Alexander Rose
7cba9cda0c support flipY for textures 2020-04-22 16:01:29 -07:00
Alexander Rose
04c690e8f9 add .writeDepth to renderable state
- renders transparent with writeDepth=true before writeDepth=true
2020-04-22 16:00:38 -07:00
David Sehnal
170d0fbc9d fix VolumeData.One matrix, removed pesky console.logs 2020-04-23 00:28:21 +02:00
David Sehnal
40d632a7b1 Volume streaming UI: toggle channel visibility 2020-04-23 00:17:10 +02:00
David Sehnal
2e754d23f4 0.7.0-dev.3 2020-04-22 18:59:20 +02:00
David Sehnal
5639a4b37c build: plugin version that does not rely on external variables 2020-04-22 14:45:57 +02:00
David Sehnal
8c959f8a60 QueryRuntimeTable.removeSymbol/CustomProp 2020-04-22 14:07:11 +02:00
David Sehnal
d42c9a6e15 0.7.0-dev.2 2020-04-22 13:09:14 +02:00
David Sehnal
da4dabc3f5 fix package.json bin path 2020-04-22 13:08:17 +02:00
David Sehnal
92217905f8 0.7.0-dev.1 2020-04-22 12:27:57 +02:00
Alexander Rose
598441a727 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-21 18:18:01 -07:00
Alexander Rose
f707cb19a4 volume loci, picking and repr improvements
- Volume.Loci
- Volume.Isosurface.Loci
- Volume.Cell.Loci
- picking
- wip: slice
2020-04-21 18:17:51 -07:00
David Sehnal
63fc408be6 ajaxGet: support custom http headers 2020-04-21 23:36:56 +02:00
David Sehnal
69dedd8c22 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-21 22:51:22 +02:00
David Sehnal
5480805754 AssignColorVolume
+ UI bugfix
2020-04-21 22:50:49 +02:00
David Sehnal
655ae65b8d dxbin support 2020-04-21 21:59:27 +02:00
David Sehnal
1a23cb672e dx parser 2020-04-21 21:24:59 +02:00
Alexander Rose
19e18b4089 MC: ensure winding-order and normals dir are same for neg/pos iso-level 2020-04-21 11:36:41 -07:00
Alexander Rose
3d909d5012 fix, register Dsn6Provider as dsn6 2020-04-21 11:12:38 -07:00
David Sehnal
ad521948b6 VolumeData.transform 2020-04-21 20:10:22 +02:00
Alexander Rose
2f3b6a28c1 support older REMARK 350 format, #34 2020-04-21 10:42:05 -07:00
Alexander Rose
c779da674c Merge branch 'master' of https://github.com/molstar/molstar 2020-04-21 10:18:57 -07:00
Alexander Rose
d9b140f9f2 added Model.probablyHasDensityMap 2020-04-21 10:18:39 -07:00
David Sehnal
052648023e VolumeSourceControls
- initial version, needs more work
2020-04-21 19:07:08 +02:00
David Sehnal
f5d12d440e DownloadFile state action 2020-04-21 17:24:56 +02:00
David Sehnal
99d7a90863 Basic cube format support
- TODO: non-orthogonal frames
2020-04-21 17:07:22 +02:00
Alexander Rose
901d5c86e6 wip, stub for volume-slice representation 2020-04-20 19:09:39 -07:00
Alexander Rose
df9efd05e6 image geometry 2020-04-20 19:04:55 -07:00
David Sehnal
26b8adaec4 extensions/cellpack: use plugin.runTask instead of Task.run 2020-04-21 02:43:09 +02:00
David Sehnal
fc6f5a0336 Merge pull request #33 from corredD/forkdev
Forkdev
2020-04-21 02:34:04 +02:00
Alexander Rose
f823a887b7 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-20 10:25:26 -07:00
Alexander Rose
b346d4d85d tweaked selection/focus remove icon 2020-04-20 10:21:43 -07:00
Alexander Rose
70bd035898 shader refactoring
- add dRenderVariant
- add convenince defines
2020-04-20 10:21:04 -07:00
David Sehnal
7e5cdd8e06 mol-plugin-ui: improved selection controls 2020-04-20 18:55:28 +02:00
David Sehnal
a21dac60e0 Rename "full state" to Session
+ ProteopediaWrapper.snapshot tweaks
2020-04-20 18:11:38 +02:00
David Sehnal
9bd2e0d96e typo fix 2020-04-20 17:52:21 +02:00
autin
dd15a000e1 clean the console.log 2020-04-20 13:39:01 +02:00
autin
ebcfa44f22 OPM support 2020-04-20 13:19:21 +02:00
David Sehnal
43845adb71 import materialui icons separately
- avoids loading extra ~5k modules in webpack
2020-04-19 17:02:52 +02:00
David Sehnal
9e3fff65a7 eslint config fix 2020-04-19 16:08:20 +02:00
David Sehnal
05c35a3a3a mol-model: cif export copyAllCategories option
- support in model-server
- moved servers build config
- fixed swagger template not working with the separate server build
2020-04-19 16:01:47 +02:00
David Sehnal
6f46965344 model-server: change response header for query-many exceeded limit 2020-04-19 14:02:05 +02:00
Alexander Rose
27ee576340 improved .hasDensityMap and .isFromPdbArchive helpers 2020-04-18 13:39:44 -07:00
David Sehnal
58492328df max height for Screenshot / State Snapshot panel 2020-04-18 16:01:17 +02:00
David Sehnal
fd102bede1 mol-plugin-ui: close Screenshot/snapshot panel after saving/opening state 2020-04-18 15:54:50 +02:00
David Sehnal
3d8c47eefa proteopedia-wrapper: support zipped state loading 2020-04-18 15:51:25 +02:00
David Sehnal
c4e43228a2 add Component: option to check if an equivalent component already exists 2020-04-18 15:31:51 +02:00
David Sehnal
6526090b8b mol-plugin-ui: added "add representation" to selection mode 2020-04-18 15:03:49 +02:00
David Sehnal
094a018b5b mol-plugin: global state save options 2020-04-18 14:28:58 +02:00
Alexander Rose
a0a9c994b2 basic asset support for volume streaming 2020-04-17 20:37:14 -07:00
Alexander Rose
524ed90e3f lru cache set returns removed entry 2020-04-17 20:36:20 -07:00
Alexander Rose
7abba750b4 0.7.0-dev.0 2020-04-17 18:26:41 -07:00
Alexander Rose
ecff1641d2 package updates 2020-04-17 18:21:02 -07:00
Alexander Rose
47ecf04386 add version field to state snapshot 2020-04-17 18:20:51 -07:00
Alexander Rose
c4697a9f45 use mean not boundary center for transform in cellpack 2020-04-17 17:47:41 -07:00
Alexander Rose
53d5414492 cellpack improvements
- support asset-manager
- allow bcif as ingredient files
- load pdb entries as bcif
2020-04-17 17:29:06 -07:00
Alexander Rose
311f5c09f5 use Asset.File[] for PD.FileList 2020-04-17 17:27:14 -07:00
Alexander Rose
be4439451f Merge branch 'master' of https://github.com/molstar/molstar 2020-04-17 11:52:23 -07:00
Alexander Rose
09c83e83ba improved Model.isFromPdbArchive 2020-04-17 11:49:23 -07:00
Alexander Rose
bea4c64d85 use asset-manager for custom-properties
- obtain function needs to return a value and assets
- assets are stored per descriptor in model/structure
- assets shold be released via customProperties.dispose()
2020-04-17 11:42:59 -07:00
David Sehnal
0387dcd444 proteopedia-wrapper: focusFirst label options 2020-04-17 20:42:44 +02:00
Alexander Rose
a89f21dafd Merge branch 'master' of https://github.com/molstar/molstar 2020-04-17 11:24:06 -07:00
Alexander Rose
7921c05d55 use .molx and .molj for file input 2020-04-17 11:08:37 -07:00
Alexander Rose
dafa946937 Asset.getUrlAsset support body 2020-04-17 11:07:50 -07:00
David Sehnal
95673b0131 do not build browserTests in production build, added build-viewer task
- reduced the production build time by several minutes
  (it took 30+s for each "subproject" and webpack was building them linearly)
2020-04-17 19:10:05 +02:00
David Sehnal
0118136869 fix build error with latest express type annotations 2020-04-17 18:55:21 +02:00
David Sehnal
573c2a7ad6 proteopedia-wrapper: support bcif 2020-04-17 18:37:01 +02:00
David Sehnal
41977ea758 DownloadStructure: support static updated bcif from PDBe 2020-04-17 17:30:01 +02:00
David Sehnal
75ccded612 support plain string in ParamDefinition.UrlParam 2020-04-17 17:08:29 +02:00
David Sehnal
2429111a59 state file export improvements
- save full state including all snapshots instead of just the current one
2020-04-17 15:39:13 +02:00
David Sehnal
c475cb292e support drag & drop for state files 2020-04-17 12:58:39 +02:00
David Sehnal
04d34b369a add snapshot download UI to "screenshot" panel 2020-04-17 12:50:21 +02:00
David Sehnal
cfe4c6c559 mol-plugin: moved state related events to PluginState 2020-04-17 12:36:22 +02:00
David Sehnal
4d13f99d22 mol-plugin: refactoring managers 2020-04-17 12:30:34 +02:00
David Sehnal
62ebd4d8a9 mol-plugin-state: PluginStateSnapshotManager refactor 2020-04-17 12:14:55 +02:00
David Sehnal
026c25621f add missing imports 2020-04-17 00:08:20 +02:00
David Sehnal
c096ae299d Merge branch 'master' of https://github.com/molstar/molstar 2020-04-17 00:06:54 +02:00
David Sehnal
ae306d1761 data asset handling improvements 2020-04-17 00:06:41 +02:00
Alexander Rose
4caae32933 add missing type 2020-04-16 13:58:15 -07:00
Alexander Rose
6bbf20980e Merge branch 'master' of https://github.com/molstar/molstar 2020-04-16 13:54:46 -07:00
David Sehnal
0fd00ecab8 mol-plugin-ui: support AssetManager in DownloadBlob 2020-04-16 22:33:21 +02:00
David Sehnal
70de73a95b mol-state: call StateTransformer.dispose when recreating object 2020-04-16 21:58:42 +02:00
Alexander Rose
578ad69c36 add current structure-focus to state snapshots 2020-04-16 11:01:07 -07:00
David Sehnal
af263b8c88 removed unused code 2020-04-16 17:09:03 +02:00
David Sehnal
bef6775de5 refactored AssetManager
- support assets in OpenFile and Download transforms
2020-04-16 17:04:21 +02:00
Alexander Rose
3c27450e82 zipped snapshot that include files from asset-manager 2020-04-15 18:29:43 -07:00
Alexander Rose
9400f27f82 basic asset manager for file objects 2020-04-15 18:28:47 -07:00
Alexander Rose
c176313f7b added zip data type that returns object of Uint8Arrays 2020-04-15 18:27:39 -07:00
Alexander Rose
77461d5a23 fix focus control breaks for non-atomic units 2020-04-15 16:00:53 -07:00
Alexander Rose
a5c039bf11 fix Si-Si bonds 2020-04-15 13:11:23 -07:00
Alexander Rose
e3c08f23bf avoid adding many identical single atom units in builder 2020-04-15 12:22:41 -07:00
Alexander Rose
67a26e93e4 occupancy handling improvements
- add occ of 1 to cif-core if not defined
- check if occ is defined before disallowing bonds
2020-04-15 12:15:26 -07:00
David Sehnal
a1d261b7c8 ui tweaks 2020-04-15 17:32:24 +02:00
David Sehnal
3826394940 Support SVG icon for CollapsableControls & fixed logo image 2020-04-15 17:13:43 +02:00
David Sehnal
791a54aeec ui tweaks 2020-04-15 13:46:20 +02:00
David Sehnal
48f1bb7755 icon tweaks 2020-04-15 11:56:42 +02:00
Alexander Rose
53e028325f updated packages, removed font building code 2020-04-14 17:09:00 -07:00
David Sehnal
02eda0a1e2 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-15 01:55:32 +02:00
David Sehnal
92600160ff lint config fix 2020-04-15 01:54:27 +02:00
Alexander Rose
6ec67a7faf Merge branch 'master' of https://github.com/molstar/molstar 2020-04-14 16:52:55 -07:00
Alexander Rose
a4386744a2 fix Model.hasCrystalSymmetry test 2020-04-14 16:52:09 -07:00
David Sehnal
09210279e1 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-15 01:42:35 +02:00
David Sehnal
e78cf18a38 separate build for servers
- because of problems with ES6 modules (might revert later)
+ css tweaks
2020-04-15 01:40:52 +02:00
Alexander Rose
9d1d7bbf72 moved pdbe code to extensions folder 2020-04-14 16:35:41 -07:00
Alexander Rose
60d5e85b4c moved rcsb code to extensions folder 2020-04-14 16:35:34 -07:00
David Sehnal
2c263e216f Merge branch 'master' of https://github.com/molstar/molstar 2020-04-15 01:21:04 +02:00
David Sehnal
e1f671a5b3 use material ui icons instead of fontello, do not import google font 2020-04-15 01:20:14 +02:00
Alexander Rose
7ffaea48cb read cif-core bfactor field 2020-04-14 15:39:34 -07:00
Alexander Rose
0e4527613c handle charge in cif-core type_symbol field #31 2020-04-14 15:36:20 -07:00
Alexander Rose
f363621de3 moved cellpack to toplevel extensions dir and register as behavior 2020-04-14 12:24:03 -07:00
Alexander Rose
4901ec3b5d added/removed events for StateActionManager 2020-04-14 12:23:55 -07:00
David Sehnal
c592b8a53f fix Mat4Control in Firefox, track Transform in StructureHierarchy, fix findUpdateRoots when there is error 2020-04-14 19:34:59 +02:00
David Sehnal
325e4e44dc Structure.transform parent revert 2020-04-14 15:22:49 +02:00
David Sehnal
a81f7f6cfd Merge branch 'master' of https://github.com/molstar/molstar 2020-04-14 15:21:08 +02:00
David Sehnal
31b83e9675 StructureSourceControls: added 'conformation transform' section 2020-04-14 15:20:11 +02:00
David Sehnal
dc89f33cd0 FocusLoci fix
- was calling camera.focusLoci twice
- broken for transformed structures
2020-04-14 15:05:58 +02:00
David Sehnal
f5f9237a78 apply Structure.coordinateSystem to interactions visual 2020-04-14 14:56:15 +02:00
David Sehnal
4429ff0ac1 Coordinate system changes- remove StructureCoordinateSystem transform * TransformStructureConformation should be enough- update Structure.coordinateSystem- update Structure.transform to keep parent's parent 2020-04-14 14:27:09 +02:00
David Sehnal
a0d38e6b10 Coordinate system changes
- remove StructureCoordinateSystem transform
  * TransformStructureConformation should be enough
- update Structure.coordinateSystem
- update Structure.transform to keep parent's parent
2020-04-14 14:13:16 +02:00
David Sehnal
c060664f84 SubstructureParentHelper.get takes decorators into account 2020-04-14 13:57:25 +02:00
David Sehnal
10f7f15f70 mol-plugin-ui: Mat4 UI & removed NumericInput in favor of TextInput.numeric 2020-04-14 13:16:31 +02:00
Alexander Rose
d40ff29337 0.6.8 2020-04-13 19:45:10 -07:00
Alexander Rose
7ca666ae98 fix wrong TransformStructureConformation params 2020-04-13 19:43:12 -07:00
Alexander Rose
dcaea9d40b tweaked focus repr params
- bigger than standard params
2020-04-13 17:09:04 -07:00
Alexander Rose
b878273d81 some basic bird molecule support 2020-04-13 15:26:39 -07:00
Alexander Rose
c15d29f2da linting 2020-04-13 13:06:32 -07:00
Alexander Rose
3e3a13070a Merge branch 'master' of https://github.com/molstar/molstar 2020-04-13 13:03:42 -07:00
Alexander Rose
11bcd84e66 optionally transpose mat4 in structure transformation transforms 2020-04-13 13:03:06 -07:00
Alexander Rose
44b63e5953 json imput for Mat4 paraemter ui 2020-04-13 13:01:05 -07:00
David Sehnal
fb0634a0f4 added semicolons to linting rules 2020-04-13 21:17:39 +02:00
David Sehnal
0b651db35b mol-plugin-ui: cache focus options in StructureFocusControls 2020-04-13 13:42:52 +02:00
David Sehnal
b24062b575 tweak proteopedia-wrapper.ModelInfo 2020-04-13 13:00:40 +02:00
Alexander Rose
35c5c4cfc0 linting improvements 2020-04-11 13:15:26 -07:00
Alexander Rose
4b8bf57d1a simplified cellpack loadMembrane 2020-04-11 12:56:30 -07:00
Alexander Rose
a81f0d911a linting style 2020-04-11 12:37:06 -07:00
Alexander Rose
28e2227989 Merge pull request #30 from corredD/forkdev
Forkdev
2020-04-11 12:13:44 -07:00
DESKTOP-O6LIMN9\ludov
4f97b6836a eslint formating 2020-04-11 14:31:31 +02:00
DESKTOP-O6LIMN9\ludov
5ab0dfaba8 formatting 2020-04-11 14:24:11 +02:00
DESKTOP-O6LIMN9\ludov
66751fa006 eslint format 2020-04-11 14:19:07 +02:00
DESKTOP-O6LIMN9\ludov
f1d78e4805 support for membrane in list files and on the server if available as bcif
clean the console.log
2020-04-11 14:13:43 +02:00
DESKTOP-O6LIMN9\ludov
715c78a04f Merge branch 'master' into forkdev 2020-04-11 11:27:41 +02:00
DESKTOP-O6LIMN9\ludov
0cd8b4ee8c Merge branch 'master' of https://github.com/molstar/molstar 2020-04-11 11:26:57 +02:00
Alexander Rose
c6efa475a5 better cif-core data naming 2020-04-10 19:47:54 -07:00
Alexander Rose
e846e1fdd7 fixed EllipsoidParams.linkCap param 2020-04-10 19:32:22 -07:00
Alexander Rose
4221067f8f added AtomSiteAnisotrop support for cifCore 2020-04-10 19:27:52 -07:00
Alexander Rose
36951d6f19 make AtomSiteAnisotrop less dependent on mmCIF 2020-04-10 19:27:24 -07:00
Alexander Rose
ac45500e35 added FormatRegistry.isApplicable and properly check AtomSiteAnisotrop 2020-04-10 19:26:22 -07:00
Alexander Rose
0f22eab8b9 support matrix type for cif-core schema 2020-04-10 19:25:05 -07:00
Alexander Rose
5a8fd6d518 beter symmetry handling in index-pair bonds 2020-04-10 15:07:18 -07:00
Alexander Rose
60ee04b9b9 linting improvements
- check tsx as well
- check brace-style
- error more instead of warn
2020-04-10 12:18:07 -07:00
David Sehnal
d99b5bd505 mol-state: throw error when trying to reuse StateBuilder 2020-04-10 15:47:40 +02:00
David Sehnal
6312c1f99b use StateBuilder.commit() instead of PluginContext.updateDataState() 2020-04-10 15:42:28 +02:00
David Sehnal
ef870a510f fix empty strings loci labels 2020-04-10 15:10:06 +02:00
David Sehnal
394ff05626 refactored format registry & added StateBuilder.commit() 2020-04-10 14:55:50 +02:00
Alexander Rose
e90ccfdd20 basic support for models from cif-core files 2020-04-09 18:42:33 -07:00
Alexander Rose
92a86e324b more general Model.hasCrystalSymmetry
- not just limited to mmCIF
2020-04-09 18:12:46 -07:00
Alexander Rose
e5d6816392 allow for improper rotations
- in Mat4.isRotationAndTranslation
2020-04-09 17:55:14 -07:00
Alexander Rose
a1b2de16a3 removed console.log 2020-04-09 17:41:17 -07:00
Alexander Rose
f605021cfb tweaked naming 2020-04-09 17:33:55 -07:00
Alexander Rose
619a2ccb3a use MOL (not UNK) as name for unknown ligand molecules
- UNK is for unknown amino acids in CCD
2020-04-09 17:33:16 -07:00
Alexander Rose
0cc077c346 more cif-core fields 2020-04-09 17:31:17 -07:00
Alexander Rose
e34aad991b fixed dics build path of cifschema app 2020-04-09 17:30:49 -07:00
Alexander Rose
2a925cdd6a tweaked bond calc
- use avg element threshold
2020-04-09 17:30:04 -07:00
Alexander Rose
36c5e444ca apply options when adding new structure component
- use StructureComponentManager.state.options
2020-04-09 14:37:54 -07:00
Alexander Rose
c7f6041aa4 handle empty File or FileList params 2020-04-09 10:11:31 -07:00
DESKTOP-O6LIMN9\ludov
68401b3556 Merge branch 'master' of github.com:corredD/molstar-proto into forkdev 2020-04-09 09:45:11 +02:00
DESKTOP-O6LIMN9\ludov
3843064eac Merge branch 'master' of https://github.com/molstar/molstar
# Conflicts:
#	.github/workflows/lint.yml
2020-04-09 09:08:46 +02:00
ludovic autin
d0de9073e7 Create lint.yml 2020-04-09 09:04:11 +02:00
DESKTOP-O6LIMN9\ludov
35bd0ec5d8 Merge branch 'master' of https://github.com/molstar/molstar into forkdev
# Conflicts:
#	src/apps/viewer/extensions/cellpack/model.ts
2020-04-09 08:55:29 +02:00
Alexander Rose
373a69abbd cellpack, add support for local ingredient files 2020-04-08 22:40:35 -07:00
Alexander Rose
9fa56bf76c readded citschema and cif2bcif apps back from ciftools package
- easier to maintain
2020-04-08 20:08:35 -07:00
David Sehnal
3ad42fc7e0 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-09 03:18:28 +02:00
David Sehnal
7dd6efafb2 fixed some cyclical references & drawcall in mol-canvas3d 2020-04-09 03:18:21 +02:00
Alexander Rose
61e26df637 try different lint workflow 2020-04-08 18:02:47 -07:00
Alexander Rose
a47283bf5b change lint gh action path 2020-04-08 17:48:57 -07:00
Alexander Rose
d7e5385b04 add lint github action 2020-04-08 17:41:25 -07:00
Alexander Rose
8eaac83238 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-08 17:26:37 -07:00
Alexander Rose
9fbe224f00 reset color of all components when setting assembly-symmetry off 2020-04-08 17:24:09 -07:00
Alexander Rose
26dc7b2f65 0.6.7 2020-04-08 16:36:37 -07:00
Alexander Rose
bb6b6f9690 updated data.rcsb.org url and schema 2020-04-08 16:23:13 -07:00
Alexander Rose
0fabfc9873 0.6.6 2020-04-08 16:01:39 -07:00
Alexander Rose
9c3e057410 fix water-water hbond detection and set to off by default 2020-04-08 14:58:16 -07:00
Alexander Rose
f4cbb1ec73 ignore mouse moves when no button is held in SelectionViewportControls 2020-04-08 13:45:35 -07:00
Alexander Rose
1175f589eb slightly increased nci link size 2020-04-08 13:39:13 -07:00
Alexander Rose
8c7563d7f2 allow MET.SD as metal binding partner 2020-04-08 13:37:55 -07:00
Alexander Rose
33533cbb09 only color by assembly-symmetry-cluster if repr was added 2020-04-08 11:19:23 -07:00
Alexander Rose
0ec37a7b95 0.6.5 2020-04-08 09:48:05 -07:00
Alexander Rose
f3db0c171b added optional priority to LociLabelProvider 2020-04-08 09:47:15 -07:00
David Sehnal
cd10d23371 updated basic-wrapper, moved some apps to examples
+ fixed lighting demo
2020-04-08 17:18:57 +02:00
DESKTOP-O6LIMN9\ludov
d60c88c506 parsing the selection string 2020-04-08 14:53:36 +02:00
DESKTOP-O6LIMN9\ludov
7266aab4be support for latest cellpack model.
Example is ExosomeModel.json present in the repo
2020-04-08 14:31:52 +02:00
Alexander Rose
54c2ef7a0b better isApplicable checks for random-coil and density-fit colorings 2020-04-07 19:59:57 -07:00
Alexander Rose
b882a72d77 refactored assembly-symmetry behavior
- use tag and applyOrUpdate
- set default color theme when off
2020-04-07 19:55:15 -07:00
Alexander Rose
1eab4dac96 0.6.4 2020-04-07 16:59:43 -07:00
Alexander Rose
b2376aea70 mol format tweaks 2020-04-07 16:56:04 -07:00
Alexander Rose
1641cfbd03 improved assembly symmetry init and cage size 2020-04-07 16:34:30 -07:00
Alexander Rose
f27540ca02 fix assembly-symmetry init issues
- ensure that the default is a non C1 symmetry
2020-04-07 12:17:42 -07:00
David Sehnal
b4320de291 mol-plugin-state: added PubChem as DownloadStructure source 2020-04-07 17:03:13 +02:00
David Sehnal
1b26aa4b36 basic MOL/SDF support 2020-04-07 16:51:59 +02:00
Alexander Rose
1ca91f35e2 wrap all sequence residues in zero-width chars for proper line breaks 2020-04-06 18:35:22 -07:00
Alexander Rose
1c5ac56ecf 0.6.3 2020-04-06 17:59:02 -07:00
Alexander Rose
ee85e13206 fix assembly symmetry cage orientation calc 2020-04-06 17:57:09 -07:00
Alexander Rose
440474d53b focus improvements- support shift to add in focus menu- keep section in focus menu open- always include loci label 2020-04-06 17:20:02 -07:00
Alexander Rose
d9c251b2ce action menu improvements
- pass MouseEvent to OnSelect
- try to keep previously expanded sections
2020-04-06 16:17:38 -07:00
Alexander Rose
975b4aee2a show error when no entry for streaming is found 2020-04-06 14:37:03 -07:00
1164 changed files with 162816 additions and 51518 deletions

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
node_modules/*
build/*
lib/*

View File

@@ -3,63 +3,94 @@
"browser": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"impliedStrict": true
}
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/ban-types": "warn",
"@typescript-eslint/class-name-casing": "off",
"@typescript-eslint/indent": [
"warn",
4
],
"@typescript-eslint/member-delimiter-style": [
"off",
{
"multiline": {
"delimiter": "none",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/prefer-namespace-keyword": "warn",
"@typescript-eslint/quotes": [
"warn",
"single",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
],
"@typescript-eslint/semi": [
"off",
null
],
"@typescript-eslint/type-annotation-spacing": "warn",
"indent": "off",
"arrow-parens": [
"off",
"as-needed"
],
"brace-style": "off",
"comma-spacing": "off",
"space-infix-ops": "error",
"comma-dangle": "off",
"eqeqeq": [
"warn",
"error",
"smart"
],
"import/order": "off",
"no-eval": "warn",
"no-new-wrappers": "warn",
"no-trailing-spaces": "warn",
"no-trailing-spaces": "error",
"no-unsafe-finally": "warn",
"no-var": "warn",
"spaced-comment": "warn"
}
"no-var": "error",
"spaced-comment": "error",
"semi": "warn",
"no-restricted-syntax": [
"error",
{
"selector": "ExportDefaultDeclaration",
"message": "Default exports are not allowed"
}
]
},
"overrides": [
{
"files": ["**/*.ts", "**/*.tsx"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["tsconfig.json", "tsconfig.commonjs.json"],
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/class-name-casing": "off",
"@typescript-eslint/indent": [
"error",
4
],
"@typescript-eslint/member-delimiter-style": [
"off",
{
"multiline": {
"delimiter": "none",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/prefer-namespace-keyword": "warn",
"@typescript-eslint/quotes": [
"error",
"single",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
],
"@typescript-eslint/semi": [
"off",
null
],
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/brace-style": [
"error",
"1tbs", { "allowSingleLine": true }
],
"@typescript-eslint/comma-spacing": "error"
}
}
]
}

18
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
on:
push:
pull_request:
jobs:
eslint:
name: eslint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: yarn install
run: yarn install
- name: eslint
uses: icrawl/action-eslint@v1

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ node_modules/
debug.log
npm-debug.log
tsconfig.tsbuildinfo
tsconfig.commonjs.tsbuildinfo
*.sublime-workspace
.idea

1
.npmignore Normal file
View File

@@ -0,0 +1 @@
tsconfig.commonjs.buildinfo

View File

@@ -14,6 +14,5 @@ before_install:
node_js:
- "12"
- "10"
- "8"
before_script:
- export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start

View File

@@ -41,7 +41,7 @@ Moreover, the project contains the implementation of `servers`, including
- `servers/volume` A tool for accessing volumetric experimental data related to molecular structures.
- `servers/plugin-state` A basic server to store Mol* Plugin states.
The project also contains performance tests (`perf-tests`), `examples`, and basic proof of concept `apps` (CIF to BinaryCIF converter and JSON domain annotation to CIF converter).
The project also contains performance tests (`perf-tests`), `examples`, and basic proof of concept `cli` apps (CIF to BinaryCIF converter and JSON domain annotation to CIF converter).
## Previous Work
This project builds on experience from previous solutions:
@@ -89,21 +89,29 @@ and navigate to `build/viewer`
### Code generation
**CIF schemas**
Install CIFTools `npm install ciftools -g`
cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/mmcif.ts -p mmCIF
cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/ccd.ts -p CCD
cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/bird.ts -p BIRD
cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/cif-core.ts -p CifCore -aa
node ./lib/commonjs/cli/cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/mmcif.ts -p mmCIF
node ./lib/commonjs/cli/cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/ccd.ts -p CCD
node ./lib/commonjs/cli/cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/bird.ts -p BIRD
node ./lib/commonjs/cli/cifschema -mip ../../../../mol-data -o src/mol-io/reader/cif/schema/cif-core.ts -p CifCore -aa
**Lipid names**
node lib/commonjs/cli/lipid-params -o src/mol-model/structure/model/types/lipids.ts
**Ion names**
node --max-old-space-size=4096 lib/commonjs/cli/chem-comp-dict/create-ions.js src/mol-model/structure/model/types/ions.ts
**GraphQL schemas**
./node_modules/.bin/graphql-codegen -c ./data/rcsb-graphql/codegen.yml
node node_modules//@graphql-codegen/cli/bin -c src/extensions/rcsb/graphql/codegen.yml
### Other scripts
**Create chem comp bond table**
export NODE_PATH="lib"; node --max-old-space-size=4096 lib/apps/chem-comp-bond/create-table.js build/data/ccb.bcif -b
node --max-old-space-size=4096 lib/commonjs/cli/chem-comp-dict/create-table.js build/data/ccb.bcif -b
**Test model server**
@@ -115,9 +123,13 @@ Install CIFTools `npm install ciftools -g`
**Convert any CIF to BinaryCIF**
node build/model-server/preprocess -i file.cif -ob file.bcif
node lib/servers/model/preprocess -i file.cif -ob file.bcif
To see all available commands, use ``node build/model-server/preprocess -h``.
To see all available commands, use ``node lib/servers/model/preprocess -h``.
Or
node lib/commonjs/cli/cif2bcif
## Development
@@ -165,3 +177,4 @@ Funding sources include but are not limited to:
* [RCSB PDB](https://www.rcsb.org) funding by a grant [DBI-1338415; PI: SK Burley] from the NSF, the NIH, and the US DoE
* [PDBe, EMBL-EBI](https://pdbe.org)
* [CEITEC](https://www.ceitec.eu/)
* [EntosAI](https://www.entos.ai) (``alpha-orbitals`` extension)

View File

@@ -0,0 +1,88 @@
pdbx_reference_molecule.prd_id
pdbx_reference_molecule.name
pdbx_reference_molecule.represent_as
pdbx_reference_molecule.type
pdbx_reference_molecule.type_evidence_code
pdbx_reference_molecule.class
pdbx_reference_molecule.class_evidence_code
pdbx_reference_molecule.formula
pdbx_reference_molecule.chem_comp_id
pdbx_reference_molecule.formula_weight
pdbx_reference_molecule.release_status
pdbx_reference_molecule.replaces
pdbx_reference_molecule.replaced_by
pdbx_reference_molecule.compound_details
pdbx_reference_molecule.description
pdbx_reference_molecule.representative_PDB_id_code
pdbx_reference_entity_list.prd_id
pdbx_reference_entity_list.ref_entity_id
pdbx_reference_entity_list.component_id
pdbx_reference_entity_list.type
pdbx_reference_entity_list.details
pdbx_reference_entity_nonpoly.prd_id
pdbx_reference_entity_nonpoly.ref_entity_id
pdbx_reference_entity_nonpoly.name
pdbx_reference_entity_nonpoly.chem_comp_id
pdbx_reference_entity_link.prd_id
pdbx_reference_entity_link.link_id
pdbx_reference_entity_link.link_class
pdbx_reference_entity_link.ref_entity_id_1
pdbx_reference_entity_link.entity_seq_num_1
pdbx_reference_entity_link.comp_id_1
pdbx_reference_entity_link.atom_id_1
pdbx_reference_entity_link.ref_entity_id_2
pdbx_reference_entity_link.entity_seq_num_2
pdbx_reference_entity_link.comp_id_2
pdbx_reference_entity_link.atom_id_2
pdbx_reference_entity_link.value_order
pdbx_reference_entity_link.component_1
pdbx_reference_entity_link.component_2
pdbx_reference_entity_link.details
pdbx_reference_entity_poly_link.prd_id
pdbx_reference_entity_poly_link.ref_entity_id
pdbx_reference_entity_poly_link.link_id
pdbx_reference_entity_poly_link.atom_id_1
pdbx_reference_entity_poly_link.comp_id_1
pdbx_reference_entity_poly_link.entity_seq_num_1
pdbx_reference_entity_poly_link.atom_id_2
pdbx_reference_entity_poly_link.comp_id_2
pdbx_reference_entity_poly_link.entity_seq_num_2
pdbx_reference_entity_poly_link.value_order
pdbx_reference_entity_poly_link.component_id
pdbx_reference_entity_poly.prd_id
pdbx_reference_entity_poly.ref_entity_id
pdbx_reference_entity_poly.db_code
pdbx_reference_entity_poly.db_name
pdbx_reference_entity_poly.type
pdbx_reference_entity_sequence.prd_id
pdbx_reference_entity_sequence.ref_entity_id
pdbx_reference_entity_sequence.type
pdbx_reference_entity_sequence.NRP_flag
pdbx_reference_entity_sequence.one_letter_codes
pdbx_reference_entity_poly_seq.prd_id
pdbx_reference_entity_poly_seq.ref_entity_id
pdbx_reference_entity_poly_seq.num
pdbx_reference_entity_poly_seq.mon_id
pdbx_reference_entity_poly_seq.parent_mon_id
pdbx_reference_entity_poly_seq.hetero
pdbx_reference_entity_poly_seq.observed
pdbx_reference_entity_src_nat.prd_id
pdbx_reference_entity_src_nat.ref_entity_id
pdbx_reference_entity_src_nat.ordinal
pdbx_reference_entity_src_nat.taxid
pdbx_reference_entity_src_nat.organism_scientific
pdbx_reference_entity_src_nat.db_code
pdbx_reference_entity_src_nat.db_name
pdbx_prd_audit.prd_id
pdbx_prd_audit.date
pdbx_prd_audit.processing_site
pdbx_prd_audit.action_type
1 pdbx_reference_molecule.prd_id
2 pdbx_reference_molecule.name
3 pdbx_reference_molecule.represent_as
4 pdbx_reference_molecule.type
5 pdbx_reference_molecule.type_evidence_code
6 pdbx_reference_molecule.class
7 pdbx_reference_molecule.class_evidence_code
8 pdbx_reference_molecule.formula
9 pdbx_reference_molecule.chem_comp_id
10 pdbx_reference_molecule.formula_weight
11 pdbx_reference_molecule.release_status
12 pdbx_reference_molecule.replaces
13 pdbx_reference_molecule.replaced_by
14 pdbx_reference_molecule.compound_details
15 pdbx_reference_molecule.description
16 pdbx_reference_molecule.representative_PDB_id_code
17 pdbx_reference_entity_list.prd_id
18 pdbx_reference_entity_list.ref_entity_id
19 pdbx_reference_entity_list.component_id
20 pdbx_reference_entity_list.type
21 pdbx_reference_entity_list.details
22 pdbx_reference_entity_nonpoly.prd_id
23 pdbx_reference_entity_nonpoly.ref_entity_id
24 pdbx_reference_entity_nonpoly.name
25 pdbx_reference_entity_nonpoly.chem_comp_id
26 pdbx_reference_entity_link.prd_id
27 pdbx_reference_entity_link.link_id
28 pdbx_reference_entity_link.link_class
29 pdbx_reference_entity_link.ref_entity_id_1
30 pdbx_reference_entity_link.entity_seq_num_1
31 pdbx_reference_entity_link.comp_id_1
32 pdbx_reference_entity_link.atom_id_1
33 pdbx_reference_entity_link.ref_entity_id_2
34 pdbx_reference_entity_link.entity_seq_num_2
35 pdbx_reference_entity_link.comp_id_2
36 pdbx_reference_entity_link.atom_id_2
37 pdbx_reference_entity_link.value_order
38 pdbx_reference_entity_link.component_1
39 pdbx_reference_entity_link.component_2
40 pdbx_reference_entity_link.details
41 pdbx_reference_entity_poly_link.prd_id
42 pdbx_reference_entity_poly_link.ref_entity_id
43 pdbx_reference_entity_poly_link.link_id
44 pdbx_reference_entity_poly_link.atom_id_1
45 pdbx_reference_entity_poly_link.comp_id_1
46 pdbx_reference_entity_poly_link.entity_seq_num_1
47 pdbx_reference_entity_poly_link.atom_id_2
48 pdbx_reference_entity_poly_link.comp_id_2
49 pdbx_reference_entity_poly_link.entity_seq_num_2
50 pdbx_reference_entity_poly_link.value_order
51 pdbx_reference_entity_poly_link.component_id
52 pdbx_reference_entity_poly.prd_id
53 pdbx_reference_entity_poly.ref_entity_id
54 pdbx_reference_entity_poly.db_code
55 pdbx_reference_entity_poly.db_name
56 pdbx_reference_entity_poly.type
57 pdbx_reference_entity_sequence.prd_id
58 pdbx_reference_entity_sequence.ref_entity_id
59 pdbx_reference_entity_sequence.type
60 pdbx_reference_entity_sequence.NRP_flag
61 pdbx_reference_entity_sequence.one_letter_codes
62 pdbx_reference_entity_poly_seq.prd_id
63 pdbx_reference_entity_poly_seq.ref_entity_id
64 pdbx_reference_entity_poly_seq.num
65 pdbx_reference_entity_poly_seq.mon_id
66 pdbx_reference_entity_poly_seq.parent_mon_id
67 pdbx_reference_entity_poly_seq.hetero
68 pdbx_reference_entity_poly_seq.observed
69 pdbx_reference_entity_src_nat.prd_id
70 pdbx_reference_entity_src_nat.ref_entity_id
71 pdbx_reference_entity_src_nat.ordinal
72 pdbx_reference_entity_src_nat.taxid
73 pdbx_reference_entity_src_nat.organism_scientific
74 pdbx_reference_entity_src_nat.db_code
75 pdbx_reference_entity_src_nat.db_name
76 pdbx_prd_audit.prd_id
77 pdbx_prd_audit.date
78 pdbx_prd_audit.processing_site
79 pdbx_prd_audit.action_type

View File

@@ -0,0 +1,60 @@
chem_comp.id
chem_comp.name
chem_comp.type
chem_comp.pdbx_type
chem_comp.formula
chem_comp.mon_nstd_parent_comp_id
chem_comp.pdbx_synonyms
chem_comp.pdbx_formal_charge
chem_comp.pdbx_initial_date
chem_comp.pdbx_modified_date
chem_comp.pdbx_ambiguous_flag
chem_comp.pdbx_release_status
chem_comp.pdbx_replaced_by
chem_comp.pdbx_replaces
chem_comp.formula_weight
chem_comp.one_letter_code
chem_comp.three_letter_code
chem_comp.pdbx_model_coordinates_details
chem_comp.pdbx_model_coordinates_missing_flag
chem_comp.pdbx_ideal_coordinates_details
chem_comp.pdbx_ideal_coordinates_missing_flag
chem_comp.pdbx_model_coordinates_db_code
chem_comp.pdbx_processing_site
chem_comp_atom.comp_id
chem_comp_atom.atom_id
chem_comp_atom.alt_atom_id
chem_comp_atom.type_symbol
chem_comp_atom.charge
chem_comp_atom.pdbx_align
chem_comp_atom.pdbx_aromatic_flag
chem_comp_atom.pdbx_leaving_atom_flag
chem_comp_atom.pdbx_stereo_config
chem_comp_atom.model_Cartn_x
chem_comp_atom.model_Cartn_y
chem_comp_atom.model_Cartn_z
chem_comp_atom.pdbx_model_Cartn_x_ideal
chem_comp_atom.pdbx_model_Cartn_y_ideal
chem_comp_atom.pdbx_model_Cartn_z_ideal
chem_comp_atom.pdbx_ordinal
chem_comp_bond.comp_id
chem_comp_bond.atom_id_1
chem_comp_bond.atom_id_2
chem_comp_bond.value_order
chem_comp_bond.pdbx_aromatic_flag
chem_comp_bond.pdbx_stereo_config
chem_comp_bond.pdbx_ordinal
pdbx_chem_comp_descriptor.comp_id
pdbx_chem_comp_descriptor.type
pdbx_chem_comp_descriptor.program
pdbx_chem_comp_descriptor.program_version
pdbx_chem_comp_descriptor.descriptor
pdbx_chem_comp_identifier.comp_id
pdbx_chem_comp_identifier.type
pdbx_chem_comp_identifier.program
pdbx_chem_comp_identifier.program_version
pdbx_chem_comp_identifier.identifier
1 chem_comp.id
2 chem_comp.name
3 chem_comp.type
4 chem_comp.pdbx_type
5 chem_comp.formula
6 chem_comp.mon_nstd_parent_comp_id
7 chem_comp.pdbx_synonyms
8 chem_comp.pdbx_formal_charge
9 chem_comp.pdbx_initial_date
10 chem_comp.pdbx_modified_date
11 chem_comp.pdbx_ambiguous_flag
12 chem_comp.pdbx_release_status
13 chem_comp.pdbx_replaced_by
14 chem_comp.pdbx_replaces
15 chem_comp.formula_weight
16 chem_comp.one_letter_code
17 chem_comp.three_letter_code
18 chem_comp.pdbx_model_coordinates_details
19 chem_comp.pdbx_model_coordinates_missing_flag
20 chem_comp.pdbx_ideal_coordinates_details
21 chem_comp.pdbx_ideal_coordinates_missing_flag
22 chem_comp.pdbx_model_coordinates_db_code
23 chem_comp.pdbx_processing_site
24 chem_comp_atom.comp_id
25 chem_comp_atom.atom_id
26 chem_comp_atom.alt_atom_id
27 chem_comp_atom.type_symbol
28 chem_comp_atom.charge
29 chem_comp_atom.pdbx_align
30 chem_comp_atom.pdbx_aromatic_flag
31 chem_comp_atom.pdbx_leaving_atom_flag
32 chem_comp_atom.pdbx_stereo_config
33 chem_comp_atom.model_Cartn_x
34 chem_comp_atom.model_Cartn_y
35 chem_comp_atom.model_Cartn_z
36 chem_comp_atom.pdbx_model_Cartn_x_ideal
37 chem_comp_atom.pdbx_model_Cartn_y_ideal
38 chem_comp_atom.pdbx_model_Cartn_z_ideal
39 chem_comp_atom.pdbx_ordinal
40 chem_comp_bond.comp_id
41 chem_comp_bond.atom_id_1
42 chem_comp_bond.atom_id_2
43 chem_comp_bond.value_order
44 chem_comp_bond.pdbx_aromatic_flag
45 chem_comp_bond.pdbx_stereo_config
46 chem_comp_bond.pdbx_ordinal
47 pdbx_chem_comp_descriptor.comp_id
48 pdbx_chem_comp_descriptor.type
49 pdbx_chem_comp_descriptor.program
50 pdbx_chem_comp_descriptor.program_version
51 pdbx_chem_comp_descriptor.descriptor
52 pdbx_chem_comp_identifier.comp_id
53 pdbx_chem_comp_identifier.type
54 pdbx_chem_comp_identifier.program
55 pdbx_chem_comp_identifier.program_version
56 pdbx_chem_comp_identifier.identifier

View File

@@ -0,0 +1,76 @@
audit.block_doi
database_code.depnum_ccdc_archive
database_code.depnum_ccdc_fiz
database_code.ICSD
database_code.MDF
database_code.NBS
database_code.CSD
database_code.COD
chemical.name_systematic
chemical.name_common
chemical.melting_point
chemical_formula.moiety
chemical_formula.sum
chemical_formula.weight
atom_type.symbol
atom_type.description
atom_type_scat.dispersion_real
atom_type_scat.dispersion_imag
atom_type_scat.source
space_group.crystal_system
space_group.name_H-M_full
space_group.IT_number
space_group_symop.operation_xyz
cell.length_a
cell.length_b
cell.length_c
cell.angle_alpha
cell.angle_beta
cell.angle_gamma
cell.volume
cell.formula_units_Z
atom_site.label
atom_site.type_symbol
atom_site.fract_x
atom_site.fract_y
atom_site.fract_z
atom_site.U_iso_or_equiv
atom_site.adp_type
atom_site.occupancy
atom_site.calc_flag
atom_site.refinement_flags
atom_site.disorder_assembly
atom_site.disorder_group
atom_site.site_symmetry_multiplicity
atom_site_aniso.label
atom_site_aniso.U
atom_site_aniso.U_11
atom_site_aniso.U_22
atom_site_aniso.U_33
atom_site_aniso.U_23
atom_site_aniso.U_13
atom_site_aniso.U_12
atom_site_aniso.U_su
atom_site_aniso.U_11_su
atom_site_aniso.U_22_su
atom_site_aniso.U_33_su
atom_site_aniso.U_23_su
atom_site_aniso.U_13_su
atom_site_aniso.U_12_su
geom_bond.atom_site_label_1
geom_bond.atom_site_label_2
geom_bond.distance
geom_bond.site_symmetry_1
geom_bond.site_symmetry_2
geom_bond.publ_flag
geom_bond.valence
1 audit.block_doi
2 database_code.depnum_ccdc_archive
3 database_code.depnum_ccdc_fiz
4 database_code.ICSD
5 database_code.MDF
6 database_code.NBS
7 database_code.CSD
8 database_code.COD
9 chemical.name_systematic
10 chemical.name_common
11 chemical.melting_point
12 chemical_formula.moiety
13 chemical_formula.sum
14 chemical_formula.weight
15 atom_type.symbol
16 atom_type.description
17 atom_type_scat.dispersion_real
18 atom_type_scat.dispersion_imag
19 atom_type_scat.source
20 space_group.crystal_system
21 space_group.name_H-M_full
22 space_group.IT_number
23 space_group_symop.operation_xyz
24 cell.length_a
25 cell.length_b
26 cell.length_c
27 cell.angle_alpha
28 cell.angle_beta
29 cell.angle_gamma
30 cell.volume
31 cell.formula_units_Z
32 atom_site.label
33 atom_site.type_symbol
34 atom_site.fract_x
35 atom_site.fract_y
36 atom_site.fract_z
37 atom_site.U_iso_or_equiv
38 atom_site.adp_type
39 atom_site.occupancy
40 atom_site.calc_flag
41 atom_site.refinement_flags
42 atom_site.disorder_assembly
43 atom_site.disorder_group
44 atom_site.site_symmetry_multiplicity
45 atom_site_aniso.label
46 atom_site_aniso.U
47 atom_site_aniso.U_11
48 atom_site_aniso.U_22
49 atom_site_aniso.U_33
50 atom_site_aniso.U_23
51 atom_site_aniso.U_13
52 atom_site_aniso.U_12
53 atom_site_aniso.U_su
54 atom_site_aniso.U_11_su
55 atom_site_aniso.U_22_su
56 atom_site_aniso.U_33_su
57 atom_site_aniso.U_23_su
58 atom_site_aniso.U_13_su
59 atom_site_aniso.U_12_su
60 geom_bond.atom_site_label_1
61 geom_bond.atom_site_label_2
62 geom_bond.distance
63 geom_bond.site_symmetry_1
64 geom_bond.site_symmetry_2
65 geom_bond.publ_flag
66 geom_bond.valence

View File

@@ -0,0 +1,805 @@
atom_sites.entry_id
atom_sites.fract_transf_matrix
atom_sites.fract_transf_vector
atom_site.group_PDB
atom_site.id
atom_site.type_symbol
atom_site.label_atom_id
atom_site.label_alt_id
atom_site.label_comp_id
atom_site.label_asym_id
atom_site.label_entity_id
atom_site.label_seq_id
atom_site.pdbx_PDB_ins_code
atom_site.pdbx_formal_charge
atom_site.Cartn_x
atom_site.Cartn_y
atom_site.Cartn_z
atom_site.occupancy
atom_site.B_iso_or_equiv
atom_site.auth_atom_id
atom_site.auth_comp_id
atom_site.auth_asym_id
atom_site.auth_seq_id
atom_site.pdbx_PDB_model_num
atom_site.ihm_model_id
atom_site_anisotrop.id
atom_site_anisotrop.U
atom_site_anisotrop.U_esd
atom_site_anisotrop.pdbx_PDB_ins_code
atom_site_anisotrop.pdbx_auth_asym_id
atom_site_anisotrop.pdbx_auth_atom_id
atom_site_anisotrop.pdbx_auth_comp_id
atom_site_anisotrop.pdbx_auth_seq_id
atom_site_anisotrop.pdbx_label_alt_id
atom_site_anisotrop.pdbx_label_asym_id
atom_site_anisotrop.pdbx_label_atom_id
atom_site_anisotrop.pdbx_label_comp_id
atom_site_anisotrop.pdbx_label_seq_id
atom_site_anisotrop.type_symbol
chem_comp.id
chem_comp.type
chem_comp.mon_nstd_flag
chem_comp.name
chem_comp.pdbx_synonyms
chem_comp.formula
chem_comp.formula_weight
chem_comp_bond.comp_id
chem_comp_bond.pdbx_stereo_config
chem_comp_bond.pdbx_ordinal
chem_comp_bond.pdbx_aromatic_flag
chem_comp_bond.atom_id_1
chem_comp_bond.atom_id_2
chem_comp_bond.value_order
pdbx_chem_comp_identifier.comp_id
pdbx_chem_comp_identifier.type
pdbx_chem_comp_identifier.program
pdbx_chem_comp_identifier.program_version
pdbx_chem_comp_identifier.identifier
pdbx_chem_comp_related.comp_id
pdbx_chem_comp_related.related_comp_id
pdbx_chem_comp_related.relationship_type
pdbx_chem_comp_related.details
pdbx_chem_comp_synonyms.comp_id
pdbx_chem_comp_synonyms.name
pdbx_chem_comp_synonyms.provenance
cell.entry_id
cell.length_a
cell.length_b
cell.length_c
cell.angle_alpha
cell.angle_beta
cell.angle_gamma
cell.Z_PDB
cell.pdbx_unique_axis
pdbx_database_related.db_name
pdbx_database_related.details
pdbx_database_related.db_id
pdbx_database_related.content_type
pdbx_database_status.status_code
pdbx_database_status.status_code_sf
pdbx_database_status.status_code_mr
pdbx_database_status.entry_id
pdbx_database_status.recvd_initial_deposition_date
pdbx_database_status.SG_entry
pdbx_database_status.deposit_site
pdbx_database_status.process_site
pdbx_database_status.status_code_cs
pdbx_database_status.methods_development_category
pdbx_database_status.pdb_format_compatible
entity.id
entity.type
entity.src_method
entity.pdbx_description
entity.formula_weight
entity.pdbx_number_of_molecules
entity.details
entity.pdbx_mutation
entity.pdbx_fragment
entity.pdbx_ec
entity_poly.entity_id
entity_poly.type
entity_poly.nstd_linkage
entity_poly.nstd_monomer
entity_poly.pdbx_seq_one_letter_code
entity_poly.pdbx_seq_one_letter_code_can
entity_poly.pdbx_strand_id
entity_poly.pdbx_target_identifier
entity_poly_seq.entity_id
entity_poly_seq.num
entity_poly_seq.mon_id
entity_poly_seq.hetero
entity_src_gen.entity_id
entity_src_gen.pdbx_src_id
entity_src_gen.pdbx_beg_seq_num
entity_src_gen.pdbx_end_seq_num
entity_src_gen.pdbx_gene_src_gene
entity_src_gen.pdbx_gene_src_scientific_name
entity_src_gen.plasmid_name
entity_src_nat.entity_id
entity_src_nat.pdbx_src_id
entity_src_nat.pdbx_beg_seq_num
entity_src_nat.pdbx_end_seq_num
entity_src_nat.pdbx_organism_scientific
entity_src_nat.pdbx_plasmid_name
pdbx_entity_instance_feature.ordinal
pdbx_entity_instance_feature.feature_type
pdbx_entity_instance_feature.details
pdbx_entity_instance_feature.asym_id
pdbx_entity_instance_feature.comp_id
pdbx_entity_instance_feature.seq_num
pdbx_entity_instance_feature.auth_asym_id
pdbx_entity_instance_feature.auth_comp_id
pdbx_entity_instance_feature.auth_seq_num
pdbx_entity_src_syn.entity_id
pdbx_entity_src_syn.pdbx_src_id
pdbx_entity_src_syn.pdbx_beg_seq_num
pdbx_entity_src_syn.pdbx_end_seq_num
pdbx_entity_src_syn.organism_scientific
pdbx_entity_branch.entity_id
pdbx_entity_branch.type
pdbx_entity_branch_list.entity_id
pdbx_entity_branch_list.comp_id
pdbx_entity_branch_list.num
pdbx_entity_branch_list.hetero
pdbx_entity_branch_link.link_id
pdbx_entity_branch_link.entity_id
pdbx_entity_branch_link.entity_branch_list_num_1
pdbx_entity_branch_link.comp_id_1
pdbx_entity_branch_link.atom_id_1
pdbx_entity_branch_link.leaving_atom_id_1
pdbx_entity_branch_link.atom_stereo_config_1
pdbx_entity_branch_link.entity_branch_list_num_2
pdbx_entity_branch_link.comp_id_2
pdbx_entity_branch_link.atom_id_2
pdbx_entity_branch_link.leaving_atom_id_2
pdbx_entity_branch_link.atom_stereo_config_2
pdbx_entity_branch_link.value_order
pdbx_entity_branch_link.details
pdbx_branch_scheme.asym_id
pdbx_branch_scheme.entity_id
pdbx_branch_scheme.mon_id
pdbx_branch_scheme.num
pdbx_branch_scheme.auth_asym_id
pdbx_branch_scheme.auth_mon_id
pdbx_branch_scheme.auth_seq_num
pdbx_branch_scheme.hetero
pdbx_branch_scheme.pdb_mon_id
pdbx_branch_scheme.pdb_asym_id
pdbx_branch_scheme.pdb_seq_num
pdbx_entity_branch_descriptor.ordinal
pdbx_entity_branch_descriptor.entity_id
pdbx_entity_branch_descriptor.descriptor
pdbx_entity_branch_descriptor.type
pdbx_entity_branch_descriptor.program
pdbx_entity_branch_descriptor.program_version
pdbx_entity_nonpoly.entity_id
pdbx_entity_nonpoly.name
pdbx_entity_nonpoly.comp_id
pdbx_nonpoly_scheme.asym_id
pdbx_nonpoly_scheme.entity_id
pdbx_nonpoly_scheme.mon_id
pdbx_nonpoly_scheme.ndb_seq_num
pdbx_nonpoly_scheme.pdb_seq_num
pdbx_nonpoly_scheme.auth_seq_num
pdbx_nonpoly_scheme.pdb_mon_id
pdbx_nonpoly_scheme.auth_mon_id
pdbx_nonpoly_scheme.pdb_strand_id
pdbx_nonpoly_scheme.pdb_ins_code
entry.id
audit_conform.dict_name
audit_conform.dict_version
audit_conform.dict_location
database_2.database_id
database_2.database_code
audit_author.name
audit_author.pdbx_ordinal
audit_author.identifier_ORCID
citation.id
citation.title
citation.journal_abbrev
citation.journal_volume
citation.page_first
citation.page_last
citation.year
citation.journal_id_ASTM
citation.country
citation.journal_id_ISSN
citation.journal_id_CSD
citation.book_publisher
citation.pdbx_database_id_PubMed
citation.pdbx_database_id_DOI
citation_author.citation_id
citation_author.name
citation_author.ordinal
exptl.entry_id
exptl.method
struct.entry_id
struct.title
struct.pdbx_descriptor
struct_asym.id
struct_asym.pdbx_blank_PDB_chainid_flag
struct_asym.pdbx_modified
struct_asym.entity_id
struct_asym.details
struct_conf.conf_type_id
struct_conf.id
struct_conf.pdbx_PDB_helix_id
struct_conf.beg_label_comp_id
struct_conf.beg_label_asym_id
struct_conf.beg_label_seq_id
struct_conf.pdbx_beg_PDB_ins_code
struct_conf.end_label_comp_id
struct_conf.end_label_asym_id
struct_conf.end_label_seq_id
struct_conf.pdbx_end_PDB_ins_code
struct_conf.beg_auth_comp_id
struct_conf.beg_auth_asym_id
struct_conf.beg_auth_seq_id
struct_conf.end_auth_comp_id
struct_conf.end_auth_asym_id
struct_conf.end_auth_seq_id
struct_conf.pdbx_PDB_helix_class
struct_conf.details
struct_conf.pdbx_PDB_helix_length
struct_conn.id
struct_conn.conn_type_id
struct_conn.pdbx_PDB_id
struct_conn.ptnr1_label_asym_id
struct_conn.ptnr1_label_comp_id
struct_conn.ptnr1_label_seq_id
struct_conn.ptnr1_label_atom_id
struct_conn.pdbx_ptnr1_label_alt_id
struct_conn.pdbx_ptnr1_PDB_ins_code
struct_conn.pdbx_ptnr1_standard_comp_id
struct_conn.ptnr1_symmetry
struct_conn.ptnr2_label_asym_id
struct_conn.ptnr2_label_comp_id
struct_conn.ptnr2_label_seq_id
struct_conn.ptnr2_label_atom_id
struct_conn.pdbx_ptnr2_label_alt_id
struct_conn.pdbx_ptnr2_PDB_ins_code
struct_conn.ptnr1_auth_asym_id
struct_conn.ptnr1_auth_comp_id
struct_conn.ptnr1_auth_seq_id
struct_conn.ptnr2_auth_asym_id
struct_conn.ptnr2_auth_comp_id
struct_conn.ptnr2_auth_seq_id
struct_conn.ptnr2_symmetry
struct_conn.pdbx_ptnr3_label_atom_id
struct_conn.pdbx_ptnr3_label_seq_id
struct_conn.pdbx_ptnr3_label_comp_id
struct_conn.pdbx_ptnr3_label_asym_id
struct_conn.pdbx_ptnr3_label_alt_id
struct_conn.pdbx_ptnr3_PDB_ins_code
struct_conn.details
struct_conn.pdbx_dist_value
struct_conn.pdbx_value_order
struct_conn_type.id
struct_conn_type.criteria
struct_conn_type.reference
struct_keywords.entry_id
struct_keywords.pdbx_keywords
struct_keywords.text
struct_ncs_oper.id
struct_ncs_oper.code
struct_ncs_oper.matrix
struct_ncs_oper.vector
struct_ncs_oper.details
struct_sheet_range.sheet_id
struct_sheet_range.id
struct_sheet_range.beg_label_comp_id
struct_sheet_range.beg_label_asym_id
struct_sheet_range.beg_label_seq_id
struct_sheet_range.pdbx_beg_PDB_ins_code
struct_sheet_range.end_label_comp_id
struct_sheet_range.end_label_asym_id
struct_sheet_range.end_label_seq_id
struct_sheet_range.pdbx_end_PDB_ins_code
struct_sheet_range.beg_auth_comp_id
struct_sheet_range.beg_auth_asym_id
struct_sheet_range.beg_auth_seq_id
struct_sheet_range.end_auth_comp_id
struct_sheet_range.end_auth_asym_id
struct_sheet_range.end_auth_seq_id
struct_site.id
struct_site.pdbx_evidence_code
struct_site.pdbx_auth_asym_id
struct_site.pdbx_auth_comp_id
struct_site.pdbx_auth_seq_id
struct_site.pdbx_auth_ins_code
struct_site.pdbx_num_residues
struct_site.details
struct_site_gen.id
struct_site_gen.site_id
struct_site_gen.pdbx_num_res
struct_site_gen.label_comp_id
struct_site_gen.label_asym_id
struct_site_gen.label_seq_id
struct_site_gen.pdbx_auth_ins_code
struct_site_gen.auth_comp_id
struct_site_gen.auth_asym_id
struct_site_gen.auth_seq_id
struct_site_gen.label_atom_id
struct_site_gen.label_alt_id
struct_site_gen.symmetry
struct_site_gen.details
symmetry.entry_id
symmetry.cell_setting
symmetry.Int_Tables_number
symmetry.space_group_name_Hall
symmetry.space_group_name_H-M
pdbx_molecule.instance_id
pdbx_molecule.prd_id
pdbx_molecule.asym_id
pdbx_molecule_features.prd_id
pdbx_molecule_features.name
pdbx_molecule_features.type
pdbx_molecule_features.class
pdbx_molecule_features.details
pdbx_reference_entity_link.prd_id
pdbx_reference_entity_link.link_id
pdbx_reference_entity_link.link_class
pdbx_reference_entity_link.ref_entity_id_1
pdbx_reference_entity_link.entity_seq_num_1
pdbx_reference_entity_link.comp_id_1
pdbx_reference_entity_link.atom_id_1
pdbx_reference_entity_link.ref_entity_id_2
pdbx_reference_entity_link.entity_seq_num_2
pdbx_reference_entity_link.comp_id_2
pdbx_reference_entity_link.atom_id_2
pdbx_reference_entity_link.value_order
pdbx_reference_entity_link.component_1
pdbx_reference_entity_link.component_2
pdbx_reference_entity_link.details
pdbx_reference_entity_list.prd_id
pdbx_reference_entity_list.ref_entity_id
pdbx_reference_entity_list.component_id
pdbx_reference_entity_list.type
pdbx_reference_entity_list.details
pdbx_reference_entity_poly_link.prd_id
pdbx_reference_entity_poly_link.ref_entity_id
pdbx_reference_entity_poly_link.link_id
pdbx_reference_entity_poly_link.atom_id_1
pdbx_reference_entity_poly_link.comp_id_1
pdbx_reference_entity_poly_link.entity_seq_num_1
pdbx_reference_entity_poly_link.atom_id_2
pdbx_reference_entity_poly_link.comp_id_2
pdbx_reference_entity_poly_link.entity_seq_num_2
pdbx_reference_entity_poly_link.value_order
pdbx_reference_entity_poly_link.component_id
pdbx_struct_assembly.id
pdbx_struct_assembly.details
pdbx_struct_assembly.method_details
pdbx_struct_assembly.oligomeric_details
pdbx_struct_assembly.oligomeric_count
pdbx_struct_assembly_gen.assembly_id
pdbx_struct_assembly_gen.oper_expression
pdbx_struct_assembly_gen.asym_id_list
pdbx_struct_oper_list.id
pdbx_struct_oper_list.type
pdbx_struct_oper_list.name
pdbx_struct_oper_list.symmetry_operation
pdbx_struct_oper_list.matrix
pdbx_struct_oper_list.vector
pdbx_struct_mod_residue.id
pdbx_struct_mod_residue.label_asym_id
pdbx_struct_mod_residue.label_seq_id
pdbx_struct_mod_residue.label_comp_id
pdbx_struct_mod_residue.auth_asym_id
pdbx_struct_mod_residue.auth_seq_id
pdbx_struct_mod_residue.auth_comp_id
pdbx_struct_mod_residue.PDB_ins_code
pdbx_struct_mod_residue.parent_comp_id
pdbx_struct_mod_residue.details
pdbx_unobs_or_zero_occ_residues.id
pdbx_unobs_or_zero_occ_residues.PDB_model_num
pdbx_unobs_or_zero_occ_residues.polymer_flag
pdbx_unobs_or_zero_occ_residues.occupancy_flag
pdbx_unobs_or_zero_occ_residues.auth_asym_id
pdbx_unobs_or_zero_occ_residues.auth_comp_id
pdbx_unobs_or_zero_occ_residues.auth_seq_id
pdbx_unobs_or_zero_occ_residues.PDB_ins_code
pdbx_unobs_or_zero_occ_residues.label_asym_id
pdbx_unobs_or_zero_occ_residues.label_comp_id
pdbx_unobs_or_zero_occ_residues.label_seq_id
ihm_struct_assembly.id
ihm_struct_assembly.name
ihm_struct_assembly.description
ihm_struct_assembly_details.id
ihm_struct_assembly_details.assembly_id
ihm_struct_assembly_details.parent_assembly_id
ihm_struct_assembly_details.entity_description
ihm_struct_assembly_details.entity_id
ihm_struct_assembly_details.asym_id
ihm_struct_assembly_details.entity_poly_segment_id
ihm_model_representation.id
ihm_model_representation.name
ihm_model_representation.details
ihm_model_representation_details.id
ihm_model_representation_details.representation_id
ihm_model_representation_details.entity_id
ihm_model_representation_details.entity_description
ihm_model_representation_details.entity_asym_id
ihm_model_representation_details.entity_poly_segment_id
ihm_model_representation_details.model_object_primitive
ihm_model_representation_details.starting_model_id
ihm_model_representation_details.model_mode
ihm_model_representation_details.model_granularity
ihm_model_representation_details.model_object_count
ihm_external_reference_info.reference_id
ihm_external_reference_info.reference_provider
ihm_external_reference_info.reference_type
ihm_external_reference_info.reference
ihm_external_reference_info.refers_to
ihm_external_reference_info.associated_url
ihm_external_files.id
ihm_external_files.reference_id
ihm_external_files.file_path
ihm_external_files.content_type
ihm_external_files.file_size_bytes
ihm_external_files.details
ihm_dataset_list.id
ihm_dataset_list.data_type
ihm_dataset_list.database_hosted
ihm_dataset_group.id
ihm_dataset_group.name
ihm_dataset_group.application
ihm_dataset_group.details
ihm_dataset_group_link.group_id
ihm_dataset_group_link.dataset_list_id
ihm_dataset_external_reference.id
ihm_dataset_external_reference.dataset_list_id
ihm_dataset_external_reference.file_id
ihm_dataset_related_db_reference.id
ihm_dataset_related_db_reference.dataset_list_id
ihm_dataset_related_db_reference.db_name
ihm_dataset_related_db_reference.accession_code
ihm_dataset_related_db_reference.version
ihm_dataset_related_db_reference.details
ihm_related_datasets.dataset_list_id_derived
ihm_related_datasets.dataset_list_id_primary
ihm_poly_residue_feature.ordinal_id
ihm_poly_residue_feature.feature_id
ihm_poly_residue_feature.entity_id
ihm_poly_residue_feature.asym_id
ihm_poly_residue_feature.seq_id_begin
ihm_poly_residue_feature.comp_id_begin
ihm_poly_residue_feature.seq_id_end
ihm_poly_residue_feature.comp_id_end
ihm_feature_list.feature_id
ihm_feature_list.feature_type
ihm_feature_list.entity_type
ihm_cross_link_list.id
ihm_cross_link_list.group_id
ihm_cross_link_list.entity_description_1
ihm_cross_link_list.entity_id_1
ihm_cross_link_list.seq_id_1
ihm_cross_link_list.comp_id_1
ihm_cross_link_list.entity_description_2
ihm_cross_link_list.entity_id_2
ihm_cross_link_list.seq_id_2
ihm_cross_link_list.comp_id_2
ihm_cross_link_list.linker_type
ihm_cross_link_list.dataset_list_id
ihm_cross_link_restraint.id
ihm_cross_link_restraint.group_id
ihm_cross_link_restraint.entity_id_1
ihm_cross_link_restraint.asym_id_1
ihm_cross_link_restraint.seq_id_1
ihm_cross_link_restraint.atom_id_1
ihm_cross_link_restraint.comp_id_1
ihm_cross_link_restraint.entity_id_2
ihm_cross_link_restraint.asym_id_2
ihm_cross_link_restraint.seq_id_2
ihm_cross_link_restraint.atom_id_2
ihm_cross_link_restraint.comp_id_2
ihm_cross_link_restraint.restraint_type
ihm_cross_link_restraint.conditional_crosslink_flag
ihm_cross_link_restraint.model_granularity
ihm_cross_link_restraint.distance_threshold
ihm_cross_link_restraint.psi
ihm_cross_link_restraint.sigma_1
ihm_cross_link_restraint.sigma_2
ihm_cross_link_result_parameters.id
ihm_cross_link_result_parameters.restraint_id
ihm_cross_link_result_parameters.model_id
ihm_cross_link_result_parameters.psi
ihm_cross_link_result_parameters.sigma_1
ihm_cross_link_result_parameters.sigma_2
ihm_sas_restraint.id
ihm_sas_restraint.dataset_list_id
ihm_sas_restraint.model_id
ihm_sas_restraint.struct_assembly_id
ihm_sas_restraint.profile_segment_flag
ihm_sas_restraint.fitting_atom_type
ihm_sas_restraint.fitting_method
ihm_sas_restraint.fitting_state
ihm_sas_restraint.radius_of_gyration
ihm_sas_restraint.chi_value
ihm_sas_restraint.details
ihm_derived_distance_restraint.id
ihm_derived_distance_restraint.group_id
ihm_derived_distance_restraint.feature_id_1
ihm_derived_distance_restraint.feature_id_2
ihm_derived_distance_restraint.group_conditionality
ihm_derived_distance_restraint.restraint_type
ihm_derived_distance_restraint.distance_upper_limit
ihm_derived_distance_restraint.random_exclusion_fraction
ihm_derived_distance_restraint.dataset_list_id
ihm_2dem_class_average_restraint.id
ihm_2dem_class_average_restraint.dataset_list_id
ihm_2dem_class_average_restraint.number_raw_micrographs
ihm_2dem_class_average_restraint.pixel_size_width
ihm_2dem_class_average_restraint.pixel_size_height
ihm_2dem_class_average_restraint.image_resolution
ihm_2dem_class_average_restraint.image_segment_flag
ihm_2dem_class_average_restraint.number_of_projections
ihm_2dem_class_average_restraint.struct_assembly_id
ihm_2dem_class_average_restraint.details
ihm_2dem_class_average_fitting.id
ihm_2dem_class_average_fitting.restraint_id
ihm_2dem_class_average_fitting.model_id
ihm_2dem_class_average_fitting.cross_correlation_coefficient
ihm_2dem_class_average_fitting.rot_matrix
ihm_2dem_class_average_fitting.tr_vector
ihm_3dem_restraint.id
ihm_3dem_restraint.dataset_list_id
ihm_3dem_restraint.fitting_method
ihm_3dem_restraint.struct_assembly_id
ihm_3dem_restraint.number_of_gaussians
ihm_3dem_restraint.model_id
ihm_3dem_restraint.cross_correlation_coefficient
ihm_predicted_contact_restraint.id
ihm_predicted_contact_restraint.group_id
ihm_predicted_contact_restraint.entity_id_1
ihm_predicted_contact_restraint.asym_id_1
ihm_predicted_contact_restraint.seq_id_1
ihm_predicted_contact_restraint.comp_id_1
ihm_predicted_contact_restraint.rep_atom_1
ihm_predicted_contact_restraint.entity_id_2
ihm_predicted_contact_restraint.asym_id_2
ihm_predicted_contact_restraint.seq_id_2
ihm_predicted_contact_restraint.comp_id_2
ihm_predicted_contact_restraint.rep_atom_2
ihm_predicted_contact_restraint.restraint_type
ihm_predicted_contact_restraint.distance_lower_limit
ihm_predicted_contact_restraint.distance_upper_limit
ihm_predicted_contact_restraint.probability
ihm_predicted_contact_restraint.model_granularity
ihm_predicted_contact_restraint.dataset_list_id
ihm_predicted_contact_restraint.software_id
ihm_starting_model_details.starting_model_id
ihm_starting_model_details.entity_id
ihm_starting_model_details.entity_description
ihm_starting_model_details.asym_id
ihm_starting_model_details.entity_poly_segment_id
ihm_starting_model_details.starting_model_source
ihm_starting_model_details.starting_model_auth_asym_id
ihm_starting_model_details.starting_model_sequence_offset
ihm_starting_model_details.dataset_list_id
ihm_starting_comparative_models.id
ihm_starting_comparative_models.starting_model_id
ihm_starting_comparative_models.starting_model_auth_asym_id
ihm_starting_comparative_models.starting_model_seq_id_begin
ihm_starting_comparative_models.starting_model_seq_id_end
ihm_starting_comparative_models.template_auth_asym_id
ihm_starting_comparative_models.template_seq_id_begin
ihm_starting_comparative_models.template_seq_id_end
ihm_starting_comparative_models.template_sequence_identity
ihm_starting_comparative_models.template_sequence_identity_denominator
ihm_starting_comparative_models.template_dataset_list_id
ihm_starting_comparative_models.alignment_file_id
ihm_starting_model_coord.starting_model_id
ihm_starting_model_coord.group_PDB
ihm_starting_model_coord.id
ihm_starting_model_coord.type_symbol
ihm_starting_model_coord.atom_id
ihm_starting_model_coord.comp_id
ihm_starting_model_coord.entity_id
ihm_starting_model_coord.asym_id
ihm_starting_model_coord.seq_id
ihm_starting_model_coord.Cartn_x
ihm_starting_model_coord.Cartn_y
ihm_starting_model_coord.Cartn_z
ihm_starting_model_coord.B_iso_or_equiv
ihm_starting_model_coord.ordinal_id
ihm_starting_model_seq_dif.id
ihm_starting_model_seq_dif.entity_id
ihm_starting_model_seq_dif.asym_id
ihm_starting_model_seq_dif.seq_id
ihm_starting_model_seq_dif.comp_id
ihm_starting_model_seq_dif.starting_model_id
ihm_starting_model_seq_dif.db_asym_id
ihm_starting_model_seq_dif.db_seq_id
ihm_starting_model_seq_dif.db_comp_id
ihm_starting_model_seq_dif.details
ihm_modeling_protocol.id
ihm_modeling_protocol.protocol_name
ihm_modeling_protocol.num_steps
ihm_modeling_protocol_details.id
ihm_modeling_protocol_details.protocol_id
ihm_modeling_protocol_details.step_id
ihm_modeling_protocol_details.struct_assembly_id
ihm_modeling_protocol_details.dataset_group_id
ihm_modeling_protocol_details.struct_assembly_description
ihm_modeling_protocol_details.step_name
ihm_modeling_protocol_details.step_method
ihm_modeling_protocol_details.num_models_begin
ihm_modeling_protocol_details.num_models_end
ihm_modeling_protocol_details.multi_scale_flag
ihm_modeling_protocol_details.multi_state_flag
ihm_modeling_protocol_details.ordered_flag
ihm_modeling_protocol_details.software_id
ihm_modeling_protocol_details.script_file_id
ihm_modeling_post_process.id
ihm_modeling_post_process.protocol_id
ihm_modeling_post_process.analysis_id
ihm_modeling_post_process.step_id
ihm_modeling_post_process.type
ihm_modeling_post_process.feature
ihm_modeling_post_process.num_models_begin
ihm_modeling_post_process.num_models_end
ihm_ensemble_info.ensemble_id
ihm_ensemble_info.ensemble_name
ihm_ensemble_info.post_process_id
ihm_ensemble_info.model_group_id
ihm_ensemble_info.ensemble_clustering_method
ihm_ensemble_info.ensemble_clustering_feature
ihm_ensemble_info.num_ensemble_models
ihm_ensemble_info.num_ensemble_models_deposited
ihm_ensemble_info.ensemble_precision_value
ihm_ensemble_info.ensemble_file_id
ihm_localization_density_files.id
ihm_localization_density_files.file_id
ihm_localization_density_files.ensemble_id
ihm_localization_density_files.entity_id
ihm_localization_density_files.asym_id
ihm_localization_density_files.entity_poly_segment_id
ihm_model_list.model_id
ihm_model_list.model_name
ihm_model_list.assembly_id
ihm_model_list.protocol_id
ihm_model_list.representation_id
ihm_model_group.id
ihm_model_group.name
ihm_model_group.details
ihm_model_group_link.group_id
ihm_model_group_link.model_id
ihm_model_representative.id
ihm_model_representative.model_group_id
ihm_model_representative.model_id
ihm_model_representative.selection_criteria
ihm_sphere_obj_site.id
ihm_sphere_obj_site.entity_id
ihm_sphere_obj_site.seq_id_begin
ihm_sphere_obj_site.seq_id_end
ihm_sphere_obj_site.asym_id
ihm_sphere_obj_site.Cartn_x
ihm_sphere_obj_site.Cartn_y
ihm_sphere_obj_site.Cartn_z
ihm_sphere_obj_site.object_radius
ihm_sphere_obj_site.rmsf
ihm_sphere_obj_site.model_id
ihm_gaussian_obj_site.id
ihm_gaussian_obj_site.entity_id
ihm_gaussian_obj_site.seq_id_begin
ihm_gaussian_obj_site.seq_id_end
ihm_gaussian_obj_site.asym_id
ihm_gaussian_obj_site.mean_Cartn_x
ihm_gaussian_obj_site.mean_Cartn_y
ihm_gaussian_obj_site.mean_Cartn_z
ihm_gaussian_obj_site.weight
ihm_gaussian_obj_site.covariance_matrix
ihm_gaussian_obj_site.model_id
ihm_gaussian_obj_ensemble.id
ihm_gaussian_obj_ensemble.entity_id
ihm_gaussian_obj_ensemble.seq_id_begin
ihm_gaussian_obj_ensemble.seq_id_end
ihm_gaussian_obj_ensemble.asym_id
ihm_gaussian_obj_ensemble.mean_Cartn_x
ihm_gaussian_obj_ensemble.mean_Cartn_y
ihm_gaussian_obj_ensemble.mean_Cartn_z
ihm_gaussian_obj_ensemble.weight
ihm_gaussian_obj_ensemble.covariance_matrix
ihm_gaussian_obj_ensemble.ensemble_id
ihm_multi_state_modeling.state_id
ihm_multi_state_modeling.state_group_id
ihm_multi_state_modeling.population_fraction
ihm_multi_state_modeling.population_fraction_sd
ihm_multi_state_modeling.state_type
ihm_multi_state_modeling.state_name
ihm_multi_state_modeling.experiment_type
ihm_multi_state_modeling.details
1 atom_sites.entry_id
2 atom_sites.fract_transf_matrix
3 atom_sites.fract_transf_vector
4 atom_site.group_PDB
5 atom_site.id
6 atom_site.type_symbol
7 atom_site.label_atom_id
8 atom_site.label_alt_id
9 atom_site.label_comp_id
10 atom_site.label_asym_id
11 atom_site.label_entity_id
12 atom_site.label_seq_id
13 atom_site.pdbx_PDB_ins_code
14 atom_site.pdbx_formal_charge
15 atom_site.Cartn_x
16 atom_site.Cartn_y
17 atom_site.Cartn_z
18 atom_site.occupancy
19 atom_site.B_iso_or_equiv
20 atom_site.auth_atom_id
21 atom_site.auth_comp_id
22 atom_site.auth_asym_id
23 atom_site.auth_seq_id
24 atom_site.pdbx_PDB_model_num
25 atom_site.ihm_model_id
26 atom_site_anisotrop.id
27 atom_site_anisotrop.U
28 atom_site_anisotrop.U_esd
29 atom_site_anisotrop.pdbx_PDB_ins_code
30 atom_site_anisotrop.pdbx_auth_asym_id
31 atom_site_anisotrop.pdbx_auth_atom_id
32 atom_site_anisotrop.pdbx_auth_comp_id
33 atom_site_anisotrop.pdbx_auth_seq_id
34 atom_site_anisotrop.pdbx_label_alt_id
35 atom_site_anisotrop.pdbx_label_asym_id
36 atom_site_anisotrop.pdbx_label_atom_id
37 atom_site_anisotrop.pdbx_label_comp_id
38 atom_site_anisotrop.pdbx_label_seq_id
39 atom_site_anisotrop.type_symbol
40 chem_comp.id
41 chem_comp.type
42 chem_comp.mon_nstd_flag
43 chem_comp.name
44 chem_comp.pdbx_synonyms
45 chem_comp.formula
46 chem_comp.formula_weight
47 chem_comp_bond.comp_id
48 chem_comp_bond.pdbx_stereo_config
49 chem_comp_bond.pdbx_ordinal
50 chem_comp_bond.pdbx_aromatic_flag
51 chem_comp_bond.atom_id_1
52 chem_comp_bond.atom_id_2
53 chem_comp_bond.value_order
54 pdbx_chem_comp_identifier.comp_id
55 pdbx_chem_comp_identifier.type
56 pdbx_chem_comp_identifier.program
57 pdbx_chem_comp_identifier.program_version
58 pdbx_chem_comp_identifier.identifier
59 pdbx_chem_comp_related.comp_id
60 pdbx_chem_comp_related.related_comp_id
61 pdbx_chem_comp_related.relationship_type
62 pdbx_chem_comp_related.details
63 pdbx_chem_comp_synonyms.comp_id
64 pdbx_chem_comp_synonyms.name
65 pdbx_chem_comp_synonyms.provenance
66 cell.entry_id
67 cell.length_a
68 cell.length_b
69 cell.length_c
70 cell.angle_alpha
71 cell.angle_beta
72 cell.angle_gamma
73 cell.Z_PDB
74 cell.pdbx_unique_axis
75 pdbx_database_related.db_name
76 pdbx_database_related.details
77 pdbx_database_related.db_id
78 pdbx_database_related.content_type
79 pdbx_database_status.status_code
80 pdbx_database_status.status_code_sf
81 pdbx_database_status.status_code_mr
82 pdbx_database_status.entry_id
83 pdbx_database_status.recvd_initial_deposition_date
84 pdbx_database_status.SG_entry
85 pdbx_database_status.deposit_site
86 pdbx_database_status.process_site
87 pdbx_database_status.status_code_cs
88 pdbx_database_status.methods_development_category
89 pdbx_database_status.pdb_format_compatible
90 entity.id
91 entity.type
92 entity.src_method
93 entity.pdbx_description
94 entity.formula_weight
95 entity.pdbx_number_of_molecules
96 entity.details
97 entity.pdbx_mutation
98 entity.pdbx_fragment
99 entity.pdbx_ec
100 entity_poly.entity_id
101 entity_poly.type
102 entity_poly.nstd_linkage
103 entity_poly.nstd_monomer
104 entity_poly.pdbx_seq_one_letter_code
105 entity_poly.pdbx_seq_one_letter_code_can
106 entity_poly.pdbx_strand_id
107 entity_poly.pdbx_target_identifier
108 entity_poly_seq.entity_id
109 entity_poly_seq.num
110 entity_poly_seq.mon_id
111 entity_poly_seq.hetero
112 entity_src_gen.entity_id
113 entity_src_gen.pdbx_src_id
114 entity_src_gen.pdbx_beg_seq_num
115 entity_src_gen.pdbx_end_seq_num
116 entity_src_gen.pdbx_gene_src_gene
117 entity_src_gen.pdbx_gene_src_scientific_name
118 entity_src_gen.plasmid_name
119 entity_src_nat.entity_id
120 entity_src_nat.pdbx_src_id
121 entity_src_nat.pdbx_beg_seq_num
122 entity_src_nat.pdbx_end_seq_num
123 entity_src_nat.pdbx_organism_scientific
124 entity_src_nat.pdbx_plasmid_name
125 pdbx_entity_instance_feature.ordinal
126 pdbx_entity_instance_feature.feature_type
127 pdbx_entity_instance_feature.details
128 pdbx_entity_instance_feature.asym_id
129 pdbx_entity_instance_feature.comp_id
130 pdbx_entity_instance_feature.seq_num
131 pdbx_entity_instance_feature.auth_asym_id
132 pdbx_entity_instance_feature.auth_comp_id
133 pdbx_entity_instance_feature.auth_seq_num
134 pdbx_entity_src_syn.entity_id
135 pdbx_entity_src_syn.pdbx_src_id
136 pdbx_entity_src_syn.pdbx_beg_seq_num
137 pdbx_entity_src_syn.pdbx_end_seq_num
138 pdbx_entity_src_syn.organism_scientific
139 pdbx_entity_branch.entity_id
140 pdbx_entity_branch.type
141 pdbx_entity_branch_list.entity_id
142 pdbx_entity_branch_list.comp_id
143 pdbx_entity_branch_list.num
144 pdbx_entity_branch_list.hetero
145 pdbx_entity_branch_link.link_id
146 pdbx_entity_branch_link.entity_id
147 pdbx_entity_branch_link.entity_branch_list_num_1
148 pdbx_entity_branch_link.comp_id_1
149 pdbx_entity_branch_link.atom_id_1
150 pdbx_entity_branch_link.leaving_atom_id_1
151 pdbx_entity_branch_link.atom_stereo_config_1
152 pdbx_entity_branch_link.entity_branch_list_num_2
153 pdbx_entity_branch_link.comp_id_2
154 pdbx_entity_branch_link.atom_id_2
155 pdbx_entity_branch_link.leaving_atom_id_2
156 pdbx_entity_branch_link.atom_stereo_config_2
157 pdbx_entity_branch_link.value_order
158 pdbx_entity_branch_link.details
159 pdbx_branch_scheme.asym_id
160 pdbx_branch_scheme.entity_id
161 pdbx_branch_scheme.mon_id
162 pdbx_branch_scheme.num
163 pdbx_branch_scheme.auth_asym_id
164 pdbx_branch_scheme.auth_mon_id
165 pdbx_branch_scheme.auth_seq_num
166 pdbx_branch_scheme.hetero
167 pdbx_branch_scheme.pdb_mon_id
168 pdbx_branch_scheme.pdb_asym_id
169 pdbx_branch_scheme.pdb_seq_num
170 pdbx_entity_branch_descriptor.ordinal
171 pdbx_entity_branch_descriptor.entity_id
172 pdbx_entity_branch_descriptor.descriptor
173 pdbx_entity_branch_descriptor.type
174 pdbx_entity_branch_descriptor.program
175 pdbx_entity_branch_descriptor.program_version
176 pdbx_entity_nonpoly.entity_id
177 pdbx_entity_nonpoly.name
178 pdbx_entity_nonpoly.comp_id
179 pdbx_nonpoly_scheme.asym_id
180 pdbx_nonpoly_scheme.entity_id
181 pdbx_nonpoly_scheme.mon_id
182 pdbx_nonpoly_scheme.ndb_seq_num
183 pdbx_nonpoly_scheme.pdb_seq_num
184 pdbx_nonpoly_scheme.auth_seq_num
185 pdbx_nonpoly_scheme.pdb_mon_id
186 pdbx_nonpoly_scheme.auth_mon_id
187 pdbx_nonpoly_scheme.pdb_strand_id
188 pdbx_nonpoly_scheme.pdb_ins_code
189 entry.id
190 audit_conform.dict_name
191 audit_conform.dict_version
192 audit_conform.dict_location
193 database_2.database_id
194 database_2.database_code
195 audit_author.name
196 audit_author.pdbx_ordinal
197 audit_author.identifier_ORCID
198 citation.id
199 citation.title
200 citation.journal_abbrev
201 citation.journal_volume
202 citation.page_first
203 citation.page_last
204 citation.year
205 citation.journal_id_ASTM
206 citation.country
207 citation.journal_id_ISSN
208 citation.journal_id_CSD
209 citation.book_publisher
210 citation.pdbx_database_id_PubMed
211 citation.pdbx_database_id_DOI
212 citation_author.citation_id
213 citation_author.name
214 citation_author.ordinal
215 exptl.entry_id
216 exptl.method
217 struct.entry_id
218 struct.title
219 struct.pdbx_descriptor
220 struct_asym.id
221 struct_asym.pdbx_blank_PDB_chainid_flag
222 struct_asym.pdbx_modified
223 struct_asym.entity_id
224 struct_asym.details
225 struct_conf.conf_type_id
226 struct_conf.id
227 struct_conf.pdbx_PDB_helix_id
228 struct_conf.beg_label_comp_id
229 struct_conf.beg_label_asym_id
230 struct_conf.beg_label_seq_id
231 struct_conf.pdbx_beg_PDB_ins_code
232 struct_conf.end_label_comp_id
233 struct_conf.end_label_asym_id
234 struct_conf.end_label_seq_id
235 struct_conf.pdbx_end_PDB_ins_code
236 struct_conf.beg_auth_comp_id
237 struct_conf.beg_auth_asym_id
238 struct_conf.beg_auth_seq_id
239 struct_conf.end_auth_comp_id
240 struct_conf.end_auth_asym_id
241 struct_conf.end_auth_seq_id
242 struct_conf.pdbx_PDB_helix_class
243 struct_conf.details
244 struct_conf.pdbx_PDB_helix_length
245 struct_conn.id
246 struct_conn.conn_type_id
247 struct_conn.pdbx_PDB_id
248 struct_conn.ptnr1_label_asym_id
249 struct_conn.ptnr1_label_comp_id
250 struct_conn.ptnr1_label_seq_id
251 struct_conn.ptnr1_label_atom_id
252 struct_conn.pdbx_ptnr1_label_alt_id
253 struct_conn.pdbx_ptnr1_PDB_ins_code
254 struct_conn.pdbx_ptnr1_standard_comp_id
255 struct_conn.ptnr1_symmetry
256 struct_conn.ptnr2_label_asym_id
257 struct_conn.ptnr2_label_comp_id
258 struct_conn.ptnr2_label_seq_id
259 struct_conn.ptnr2_label_atom_id
260 struct_conn.pdbx_ptnr2_label_alt_id
261 struct_conn.pdbx_ptnr2_PDB_ins_code
262 struct_conn.ptnr1_auth_asym_id
263 struct_conn.ptnr1_auth_comp_id
264 struct_conn.ptnr1_auth_seq_id
265 struct_conn.ptnr2_auth_asym_id
266 struct_conn.ptnr2_auth_comp_id
267 struct_conn.ptnr2_auth_seq_id
268 struct_conn.ptnr2_symmetry
269 struct_conn.pdbx_ptnr3_label_atom_id
270 struct_conn.pdbx_ptnr3_label_seq_id
271 struct_conn.pdbx_ptnr3_label_comp_id
272 struct_conn.pdbx_ptnr3_label_asym_id
273 struct_conn.pdbx_ptnr3_label_alt_id
274 struct_conn.pdbx_ptnr3_PDB_ins_code
275 struct_conn.details
276 struct_conn.pdbx_dist_value
277 struct_conn.pdbx_value_order
278 struct_conn_type.id
279 struct_conn_type.criteria
280 struct_conn_type.reference
281 struct_keywords.entry_id
282 struct_keywords.pdbx_keywords
283 struct_keywords.text
284 struct_ncs_oper.id
285 struct_ncs_oper.code
286 struct_ncs_oper.matrix
287 struct_ncs_oper.vector
288 struct_ncs_oper.details
289 struct_sheet_range.sheet_id
290 struct_sheet_range.id
291 struct_sheet_range.beg_label_comp_id
292 struct_sheet_range.beg_label_asym_id
293 struct_sheet_range.beg_label_seq_id
294 struct_sheet_range.pdbx_beg_PDB_ins_code
295 struct_sheet_range.end_label_comp_id
296 struct_sheet_range.end_label_asym_id
297 struct_sheet_range.end_label_seq_id
298 struct_sheet_range.pdbx_end_PDB_ins_code
299 struct_sheet_range.beg_auth_comp_id
300 struct_sheet_range.beg_auth_asym_id
301 struct_sheet_range.beg_auth_seq_id
302 struct_sheet_range.end_auth_comp_id
303 struct_sheet_range.end_auth_asym_id
304 struct_sheet_range.end_auth_seq_id
305 struct_site.id
306 struct_site.pdbx_evidence_code
307 struct_site.pdbx_auth_asym_id
308 struct_site.pdbx_auth_comp_id
309 struct_site.pdbx_auth_seq_id
310 struct_site.pdbx_auth_ins_code
311 struct_site.pdbx_num_residues
312 struct_site.details
313 struct_site_gen.id
314 struct_site_gen.site_id
315 struct_site_gen.pdbx_num_res
316 struct_site_gen.label_comp_id
317 struct_site_gen.label_asym_id
318 struct_site_gen.label_seq_id
319 struct_site_gen.pdbx_auth_ins_code
320 struct_site_gen.auth_comp_id
321 struct_site_gen.auth_asym_id
322 struct_site_gen.auth_seq_id
323 struct_site_gen.label_atom_id
324 struct_site_gen.label_alt_id
325 struct_site_gen.symmetry
326 struct_site_gen.details
327 symmetry.entry_id
328 symmetry.cell_setting
329 symmetry.Int_Tables_number
330 symmetry.space_group_name_Hall
331 symmetry.space_group_name_H-M
332 pdbx_molecule.instance_id
333 pdbx_molecule.prd_id
334 pdbx_molecule.asym_id
335 pdbx_molecule_features.prd_id
336 pdbx_molecule_features.name
337 pdbx_molecule_features.type
338 pdbx_molecule_features.class
339 pdbx_molecule_features.details
340 pdbx_reference_entity_link.prd_id
341 pdbx_reference_entity_link.link_id
342 pdbx_reference_entity_link.link_class
343 pdbx_reference_entity_link.ref_entity_id_1
344 pdbx_reference_entity_link.entity_seq_num_1
345 pdbx_reference_entity_link.comp_id_1
346 pdbx_reference_entity_link.atom_id_1
347 pdbx_reference_entity_link.ref_entity_id_2
348 pdbx_reference_entity_link.entity_seq_num_2
349 pdbx_reference_entity_link.comp_id_2
350 pdbx_reference_entity_link.atom_id_2
351 pdbx_reference_entity_link.value_order
352 pdbx_reference_entity_link.component_1
353 pdbx_reference_entity_link.component_2
354 pdbx_reference_entity_link.details
355 pdbx_reference_entity_list.prd_id
356 pdbx_reference_entity_list.ref_entity_id
357 pdbx_reference_entity_list.component_id
358 pdbx_reference_entity_list.type
359 pdbx_reference_entity_list.details
360 pdbx_reference_entity_poly_link.prd_id
361 pdbx_reference_entity_poly_link.ref_entity_id
362 pdbx_reference_entity_poly_link.link_id
363 pdbx_reference_entity_poly_link.atom_id_1
364 pdbx_reference_entity_poly_link.comp_id_1
365 pdbx_reference_entity_poly_link.entity_seq_num_1
366 pdbx_reference_entity_poly_link.atom_id_2
367 pdbx_reference_entity_poly_link.comp_id_2
368 pdbx_reference_entity_poly_link.entity_seq_num_2
369 pdbx_reference_entity_poly_link.value_order
370 pdbx_reference_entity_poly_link.component_id
371 pdbx_struct_assembly.id
372 pdbx_struct_assembly.details
373 pdbx_struct_assembly.method_details
374 pdbx_struct_assembly.oligomeric_details
375 pdbx_struct_assembly.oligomeric_count
376 pdbx_struct_assembly_gen.assembly_id
377 pdbx_struct_assembly_gen.oper_expression
378 pdbx_struct_assembly_gen.asym_id_list
379 pdbx_struct_oper_list.id
380 pdbx_struct_oper_list.type
381 pdbx_struct_oper_list.name
382 pdbx_struct_oper_list.symmetry_operation
383 pdbx_struct_oper_list.matrix
384 pdbx_struct_oper_list.vector
385 pdbx_struct_mod_residue.id
386 pdbx_struct_mod_residue.label_asym_id
387 pdbx_struct_mod_residue.label_seq_id
388 pdbx_struct_mod_residue.label_comp_id
389 pdbx_struct_mod_residue.auth_asym_id
390 pdbx_struct_mod_residue.auth_seq_id
391 pdbx_struct_mod_residue.auth_comp_id
392 pdbx_struct_mod_residue.PDB_ins_code
393 pdbx_struct_mod_residue.parent_comp_id
394 pdbx_struct_mod_residue.details
395 pdbx_unobs_or_zero_occ_residues.id
396 pdbx_unobs_or_zero_occ_residues.PDB_model_num
397 pdbx_unobs_or_zero_occ_residues.polymer_flag
398 pdbx_unobs_or_zero_occ_residues.occupancy_flag
399 pdbx_unobs_or_zero_occ_residues.auth_asym_id
400 pdbx_unobs_or_zero_occ_residues.auth_comp_id
401 pdbx_unobs_or_zero_occ_residues.auth_seq_id
402 pdbx_unobs_or_zero_occ_residues.PDB_ins_code
403 pdbx_unobs_or_zero_occ_residues.label_asym_id
404 pdbx_unobs_or_zero_occ_residues.label_comp_id
405 pdbx_unobs_or_zero_occ_residues.label_seq_id
406 ihm_struct_assembly.id
407 ihm_struct_assembly.name
408 ihm_struct_assembly.description
409 ihm_struct_assembly_details.id
410 ihm_struct_assembly_details.assembly_id
411 ihm_struct_assembly_details.parent_assembly_id
412 ihm_struct_assembly_details.entity_description
413 ihm_struct_assembly_details.entity_id
414 ihm_struct_assembly_details.asym_id
415 ihm_struct_assembly_details.entity_poly_segment_id
416 ihm_model_representation.id
417 ihm_model_representation.name
418 ihm_model_representation.details
419 ihm_model_representation_details.id
420 ihm_model_representation_details.representation_id
421 ihm_model_representation_details.entity_id
422 ihm_model_representation_details.entity_description
423 ihm_model_representation_details.entity_asym_id
424 ihm_model_representation_details.entity_poly_segment_id
425 ihm_model_representation_details.model_object_primitive
426 ihm_model_representation_details.starting_model_id
427 ihm_model_representation_details.model_mode
428 ihm_model_representation_details.model_granularity
429 ihm_model_representation_details.model_object_count
430 ihm_external_reference_info.reference_id
431 ihm_external_reference_info.reference_provider
432 ihm_external_reference_info.reference_type
433 ihm_external_reference_info.reference
434 ihm_external_reference_info.refers_to
435 ihm_external_reference_info.associated_url
436 ihm_external_files.id
437 ihm_external_files.reference_id
438 ihm_external_files.file_path
439 ihm_external_files.content_type
440 ihm_external_files.file_size_bytes
441 ihm_external_files.details
442 ihm_dataset_list.id
443 ihm_dataset_list.data_type
444 ihm_dataset_list.database_hosted
445 ihm_dataset_group.id
446 ihm_dataset_group.name
447 ihm_dataset_group.application
448 ihm_dataset_group.details
449 ihm_dataset_group_link.group_id
450 ihm_dataset_group_link.dataset_list_id
451 ihm_dataset_external_reference.id
452 ihm_dataset_external_reference.dataset_list_id
453 ihm_dataset_external_reference.file_id
454 ihm_dataset_related_db_reference.id
455 ihm_dataset_related_db_reference.dataset_list_id
456 ihm_dataset_related_db_reference.db_name
457 ihm_dataset_related_db_reference.accession_code
458 ihm_dataset_related_db_reference.version
459 ihm_dataset_related_db_reference.details
460 ihm_related_datasets.dataset_list_id_derived
461 ihm_related_datasets.dataset_list_id_primary
462 ihm_poly_residue_feature.ordinal_id
463 ihm_poly_residue_feature.feature_id
464 ihm_poly_residue_feature.entity_id
465 ihm_poly_residue_feature.asym_id
466 ihm_poly_residue_feature.seq_id_begin
467 ihm_poly_residue_feature.comp_id_begin
468 ihm_poly_residue_feature.seq_id_end
469 ihm_poly_residue_feature.comp_id_end
470 ihm_feature_list.feature_id
471 ihm_feature_list.feature_type
472 ihm_feature_list.entity_type
473 ihm_cross_link_list.id
474 ihm_cross_link_list.group_id
475 ihm_cross_link_list.entity_description_1
476 ihm_cross_link_list.entity_id_1
477 ihm_cross_link_list.seq_id_1
478 ihm_cross_link_list.comp_id_1
479 ihm_cross_link_list.entity_description_2
480 ihm_cross_link_list.entity_id_2
481 ihm_cross_link_list.seq_id_2
482 ihm_cross_link_list.comp_id_2
483 ihm_cross_link_list.linker_type
484 ihm_cross_link_list.dataset_list_id
485 ihm_cross_link_restraint.id
486 ihm_cross_link_restraint.group_id
487 ihm_cross_link_restraint.entity_id_1
488 ihm_cross_link_restraint.asym_id_1
489 ihm_cross_link_restraint.seq_id_1
490 ihm_cross_link_restraint.atom_id_1
491 ihm_cross_link_restraint.comp_id_1
492 ihm_cross_link_restraint.entity_id_2
493 ihm_cross_link_restraint.asym_id_2
494 ihm_cross_link_restraint.seq_id_2
495 ihm_cross_link_restraint.atom_id_2
496 ihm_cross_link_restraint.comp_id_2
497 ihm_cross_link_restraint.restraint_type
498 ihm_cross_link_restraint.conditional_crosslink_flag
499 ihm_cross_link_restraint.model_granularity
500 ihm_cross_link_restraint.distance_threshold
501 ihm_cross_link_restraint.psi
502 ihm_cross_link_restraint.sigma_1
503 ihm_cross_link_restraint.sigma_2
504 ihm_cross_link_result_parameters.id
505 ihm_cross_link_result_parameters.restraint_id
506 ihm_cross_link_result_parameters.model_id
507 ihm_cross_link_result_parameters.psi
508 ihm_cross_link_result_parameters.sigma_1
509 ihm_cross_link_result_parameters.sigma_2
510 ihm_sas_restraint.id
511 ihm_sas_restraint.dataset_list_id
512 ihm_sas_restraint.model_id
513 ihm_sas_restraint.struct_assembly_id
514 ihm_sas_restraint.profile_segment_flag
515 ihm_sas_restraint.fitting_atom_type
516 ihm_sas_restraint.fitting_method
517 ihm_sas_restraint.fitting_state
518 ihm_sas_restraint.radius_of_gyration
519 ihm_sas_restraint.chi_value
520 ihm_sas_restraint.details
521 ihm_derived_distance_restraint.id
522 ihm_derived_distance_restraint.group_id
523 ihm_derived_distance_restraint.feature_id_1
524 ihm_derived_distance_restraint.feature_id_2
525 ihm_derived_distance_restraint.group_conditionality
526 ihm_derived_distance_restraint.restraint_type
527 ihm_derived_distance_restraint.distance_upper_limit
528 ihm_derived_distance_restraint.random_exclusion_fraction
529 ihm_derived_distance_restraint.dataset_list_id
530 ihm_2dem_class_average_restraint.id
531 ihm_2dem_class_average_restraint.dataset_list_id
532 ihm_2dem_class_average_restraint.number_raw_micrographs
533 ihm_2dem_class_average_restraint.pixel_size_width
534 ihm_2dem_class_average_restraint.pixel_size_height
535 ihm_2dem_class_average_restraint.image_resolution
536 ihm_2dem_class_average_restraint.image_segment_flag
537 ihm_2dem_class_average_restraint.number_of_projections
538 ihm_2dem_class_average_restraint.struct_assembly_id
539 ihm_2dem_class_average_restraint.details
540 ihm_2dem_class_average_fitting.id
541 ihm_2dem_class_average_fitting.restraint_id
542 ihm_2dem_class_average_fitting.model_id
543 ihm_2dem_class_average_fitting.cross_correlation_coefficient
544 ihm_2dem_class_average_fitting.rot_matrix
545 ihm_2dem_class_average_fitting.tr_vector
546 ihm_3dem_restraint.id
547 ihm_3dem_restraint.dataset_list_id
548 ihm_3dem_restraint.fitting_method
549 ihm_3dem_restraint.struct_assembly_id
550 ihm_3dem_restraint.number_of_gaussians
551 ihm_3dem_restraint.model_id
552 ihm_3dem_restraint.cross_correlation_coefficient
553 ihm_predicted_contact_restraint.id
554 ihm_predicted_contact_restraint.group_id
555 ihm_predicted_contact_restraint.entity_id_1
556 ihm_predicted_contact_restraint.asym_id_1
557 ihm_predicted_contact_restraint.seq_id_1
558 ihm_predicted_contact_restraint.comp_id_1
559 ihm_predicted_contact_restraint.rep_atom_1
560 ihm_predicted_contact_restraint.entity_id_2
561 ihm_predicted_contact_restraint.asym_id_2
562 ihm_predicted_contact_restraint.seq_id_2
563 ihm_predicted_contact_restraint.comp_id_2
564 ihm_predicted_contact_restraint.rep_atom_2
565 ihm_predicted_contact_restraint.restraint_type
566 ihm_predicted_contact_restraint.distance_lower_limit
567 ihm_predicted_contact_restraint.distance_upper_limit
568 ihm_predicted_contact_restraint.probability
569 ihm_predicted_contact_restraint.model_granularity
570 ihm_predicted_contact_restraint.dataset_list_id
571 ihm_predicted_contact_restraint.software_id
572 ihm_starting_model_details.starting_model_id
573 ihm_starting_model_details.entity_id
574 ihm_starting_model_details.entity_description
575 ihm_starting_model_details.asym_id
576 ihm_starting_model_details.entity_poly_segment_id
577 ihm_starting_model_details.starting_model_source
578 ihm_starting_model_details.starting_model_auth_asym_id
579 ihm_starting_model_details.starting_model_sequence_offset
580 ihm_starting_model_details.dataset_list_id
581 ihm_starting_comparative_models.id
582 ihm_starting_comparative_models.starting_model_id
583 ihm_starting_comparative_models.starting_model_auth_asym_id
584 ihm_starting_comparative_models.starting_model_seq_id_begin
585 ihm_starting_comparative_models.starting_model_seq_id_end
586 ihm_starting_comparative_models.template_auth_asym_id
587 ihm_starting_comparative_models.template_seq_id_begin
588 ihm_starting_comparative_models.template_seq_id_end
589 ihm_starting_comparative_models.template_sequence_identity
590 ihm_starting_comparative_models.template_sequence_identity_denominator
591 ihm_starting_comparative_models.template_dataset_list_id
592 ihm_starting_comparative_models.alignment_file_id
593 ihm_starting_model_coord.starting_model_id
594 ihm_starting_model_coord.group_PDB
595 ihm_starting_model_coord.id
596 ihm_starting_model_coord.type_symbol
597 ihm_starting_model_coord.atom_id
598 ihm_starting_model_coord.comp_id
599 ihm_starting_model_coord.entity_id
600 ihm_starting_model_coord.asym_id
601 ihm_starting_model_coord.seq_id
602 ihm_starting_model_coord.Cartn_x
603 ihm_starting_model_coord.Cartn_y
604 ihm_starting_model_coord.Cartn_z
605 ihm_starting_model_coord.B_iso_or_equiv
606 ihm_starting_model_coord.ordinal_id
607 ihm_starting_model_seq_dif.id
608 ihm_starting_model_seq_dif.entity_id
609 ihm_starting_model_seq_dif.asym_id
610 ihm_starting_model_seq_dif.seq_id
611 ihm_starting_model_seq_dif.comp_id
612 ihm_starting_model_seq_dif.starting_model_id
613 ihm_starting_model_seq_dif.db_asym_id
614 ihm_starting_model_seq_dif.db_seq_id
615 ihm_starting_model_seq_dif.db_comp_id
616 ihm_starting_model_seq_dif.details
617 ihm_modeling_protocol.id
618 ihm_modeling_protocol.protocol_name
619 ihm_modeling_protocol.num_steps
620 ihm_modeling_protocol_details.id
621 ihm_modeling_protocol_details.protocol_id
622 ihm_modeling_protocol_details.step_id
623 ihm_modeling_protocol_details.struct_assembly_id
624 ihm_modeling_protocol_details.dataset_group_id
625 ihm_modeling_protocol_details.struct_assembly_description
626 ihm_modeling_protocol_details.step_name
627 ihm_modeling_protocol_details.step_method
628 ihm_modeling_protocol_details.num_models_begin
629 ihm_modeling_protocol_details.num_models_end
630 ihm_modeling_protocol_details.multi_scale_flag
631 ihm_modeling_protocol_details.multi_state_flag
632 ihm_modeling_protocol_details.ordered_flag
633 ihm_modeling_protocol_details.software_id
634 ihm_modeling_protocol_details.script_file_id
635 ihm_modeling_post_process.id
636 ihm_modeling_post_process.protocol_id
637 ihm_modeling_post_process.analysis_id
638 ihm_modeling_post_process.step_id
639 ihm_modeling_post_process.type
640 ihm_modeling_post_process.feature
641 ihm_modeling_post_process.num_models_begin
642 ihm_modeling_post_process.num_models_end
643 ihm_ensemble_info.ensemble_id
644 ihm_ensemble_info.ensemble_name
645 ihm_ensemble_info.post_process_id
646 ihm_ensemble_info.model_group_id
647 ihm_ensemble_info.ensemble_clustering_method
648 ihm_ensemble_info.ensemble_clustering_feature
649 ihm_ensemble_info.num_ensemble_models
650 ihm_ensemble_info.num_ensemble_models_deposited
651 ihm_ensemble_info.ensemble_precision_value
652 ihm_ensemble_info.ensemble_file_id
653 ihm_localization_density_files.id
654 ihm_localization_density_files.file_id
655 ihm_localization_density_files.ensemble_id
656 ihm_localization_density_files.entity_id
657 ihm_localization_density_files.asym_id
658 ihm_localization_density_files.entity_poly_segment_id
659 ihm_model_list.model_id
660 ihm_model_list.model_name
661 ihm_model_list.assembly_id
662 ihm_model_list.protocol_id
663 ihm_model_list.representation_id
664 ihm_model_group.id
665 ihm_model_group.name
666 ihm_model_group.details
667 ihm_model_group_link.group_id
668 ihm_model_group_link.model_id
669 ihm_model_representative.id
670 ihm_model_representative.model_group_id
671 ihm_model_representative.model_id
672 ihm_model_representative.selection_criteria
673 ihm_sphere_obj_site.id
674 ihm_sphere_obj_site.entity_id
675 ihm_sphere_obj_site.seq_id_begin
676 ihm_sphere_obj_site.seq_id_end
677 ihm_sphere_obj_site.asym_id
678 ihm_sphere_obj_site.Cartn_x
679 ihm_sphere_obj_site.Cartn_y
680 ihm_sphere_obj_site.Cartn_z
681 ihm_sphere_obj_site.object_radius
682 ihm_sphere_obj_site.rmsf
683 ihm_sphere_obj_site.model_id
684 ihm_gaussian_obj_site.id
685 ihm_gaussian_obj_site.entity_id
686 ihm_gaussian_obj_site.seq_id_begin
687 ihm_gaussian_obj_site.seq_id_end
688 ihm_gaussian_obj_site.asym_id
689 ihm_gaussian_obj_site.mean_Cartn_x
690 ihm_gaussian_obj_site.mean_Cartn_y
691 ihm_gaussian_obj_site.mean_Cartn_z
692 ihm_gaussian_obj_site.weight
693 ihm_gaussian_obj_site.covariance_matrix
694 ihm_gaussian_obj_site.model_id
695 ihm_gaussian_obj_ensemble.id
696 ihm_gaussian_obj_ensemble.entity_id
697 ihm_gaussian_obj_ensemble.seq_id_begin
698 ihm_gaussian_obj_ensemble.seq_id_end
699 ihm_gaussian_obj_ensemble.asym_id
700 ihm_gaussian_obj_ensemble.mean_Cartn_x
701 ihm_gaussian_obj_ensemble.mean_Cartn_y
702 ihm_gaussian_obj_ensemble.mean_Cartn_z
703 ihm_gaussian_obj_ensemble.weight
704 ihm_gaussian_obj_ensemble.covariance_matrix
705 ihm_gaussian_obj_ensemble.ensemble_id
706 ihm_multi_state_modeling.state_id
707 ihm_multi_state_modeling.state_group_id
708 ihm_multi_state_modeling.population_fraction
709 ihm_multi_state_modeling.population_fraction_sd
710 ihm_multi_state_modeling.state_type
711 ihm_multi_state_modeling.state_name
712 ihm_multi_state_modeling.experiment_type
713 ihm_multi_state_modeling.details

View File

@@ -0,0 +1,76 @@
cell.length_a
cell.length_b
cell.length_c
cell.angle_alpha
cell.angle_beta
cell.angle_gamma
symmetry.space_group_name_H-M
entry.id
struct.title
pdbx_database_status.recvd_initial_deposition_date
pdbx_audit_revision_history.revision_date
struct_ncs_oper
pdbx_struct_assembly_gen
pdbx_struct_oper_list
entity.id
entity.type
entity.pdbx_description
entity_poly.entity_id
entity_poly.pdbx_seq_one_letter_code
entity_poly.pdbx_strand_id
exptl.method
refine.ls_d_res_low
refine.ls_R_factor_R_free
refine.ls_R_factor_R_work
atom_site.pdbx_formal_charge
atom_site.label_atom_id
atom_site.type_symbol
chem_comp.id
chem_comp.type
chem_comp.name
chem_comp_bond
atom_site.Cartn_x
atom_site.Cartn_y
atom_site.Cartn_z
atom_site.B_iso_or_equiv
atom_site.id
atom_site.label_alt_id
atom_site.occupancy
atom_site.label_seq_id
atom_site.label_comp_id
struct_sheet_range.id
struct_sheet_range.beg_label_asym_id
struct_sheet_range.beg_label_seq_id
struct_sheet_range.pdbx_beg_PDB_ins_code
struct_sheet_range.end_label_asym_id
struct_sheet_range.end_label_seq_id
struct_sheet_range.pdbx_end_PDB_ins_code
struct_conf.conf_type_id
struct_conf.id
struct_conf.beg_label_asym_id
struct_conf.beg_label_seq_id
struct_conf.pdbx_beg_PDB_ins_code
struct_conf.end_label_asym_id
struct_conf.end_label_seq_id
struct_conf.pdbx_end_PDB_ins_code
atom_site.pdbx_PDB_ins_code
atom_site.label_asym_id
atom_site.auth_asym_id
1 cell.length_a
2 cell.length_b
3 cell.length_c
4 cell.angle_alpha
5 cell.angle_beta
6 cell.angle_gamma
7 symmetry.space_group_name_H-M
8 entry.id
9 struct.title
10 pdbx_database_status.recvd_initial_deposition_date
11 pdbx_audit_revision_history.revision_date
12 struct_ncs_oper
13 pdbx_struct_assembly_gen
14 pdbx_struct_oper_list
15 entity.id
16 entity.type
17 entity.pdbx_description
18 entity_poly.entity_id
19 entity_poly.pdbx_seq_one_letter_code
20 entity_poly.pdbx_strand_id
21 exptl.method
22 refine.ls_d_res_low
23 refine.ls_R_factor_R_free
24 refine.ls_R_factor_R_work
25 atom_site.pdbx_formal_charge
26 atom_site.label_atom_id
27 atom_site.type_symbol
28 chem_comp.id
29 chem_comp.type
30 chem_comp.name
31 chem_comp_bond
32 atom_site.Cartn_x
33 atom_site.Cartn_y
34 atom_site.Cartn_z
35 atom_site.B_iso_or_equiv
36 atom_site.id
37 atom_site.label_alt_id
38 atom_site.occupancy
39 atom_site.label_seq_id
40 atom_site.label_comp_id
41 struct_sheet_range.id
42 struct_sheet_range.beg_label_asym_id
43 struct_sheet_range.beg_label_seq_id
44 struct_sheet_range.pdbx_beg_PDB_ins_code
45 struct_sheet_range.end_label_asym_id
46 struct_sheet_range.end_label_seq_id
47 struct_sheet_range.pdbx_end_PDB_ins_code
48 struct_conf.conf_type_id
49 struct_conf.id
50 struct_conf.beg_label_asym_id
51 struct_conf.beg_label_seq_id
52 struct_conf.pdbx_beg_PDB_ins_code
53 struct_conf.end_label_asym_id
54 struct_conf.end_label_seq_id
55 struct_conf.pdbx_end_PDB_ins_code
56 atom_site.pdbx_PDB_ins_code
57 atom_site.label_asym_id
58 atom_site.auth_asym_id

View File

@@ -0,0 +1,28 @@
* Cyclic polymers (1sfi, 6dny, 1HVZ)
* B-DNA (1bna)
* Missing carbonyl oxygen (1gfl)
* Mono-saccharides with alt locs (1B5F)
* Microheterogeneity
* Protein (1EJG, 3NIR)
* DNA (3VOK)
* PNA: peptide nucleic acid (5eme, 1xj9)
* Peptide derived residues
* GFP chromophores (5Z6Y)
* Nucleotides that dont have a parent base set, i.e. detect purine/pyrimidine from geometry (THX in 1AUL, OMC in e.g. 5D3G)
* Bases with modified ring atoms
* DZ has C1 instead of N1 (e.g. 6I4N)
* DP has N5 instead of C5 and C7 instead of N7 (e.g. 6I4N)
* Beta & Gamma peptides (e.g. 1GAC, 6PQF)
* Mixed (heterogeneous) all-atom/trace-only RNA model (1JGQ)
* Polymers with residues with missing trace atoms (e.g. 2QFJ)
* Modified RNA bases (1y26, 5L4O)
* Discontinuous chains, i.e. gaps in the sequence (3sn6)
* Lots of sheets (1cbs)
* DNA (2np2, 1d66)
* C-alpha only (2rcj)
* Not cyclic, but termini are backbone-only and within distance but seqIds are not compatible (6SW3)
* Close backbone atoms but not linked (e.g. 4HIV)
* Non-standard residues
* Protein (1BRR, 5Z6Y)
* DNA (5D3G)
* Multiple models with different sets of ligands or missing ligands (1J6T, 1VRC, 2ICY, 1O2F)

View File

@@ -24,7 +24,7 @@ npm run build-tsc
and run the server by
```
node lib/servers/model/server/server
node lib/commonjs/servers/model/server/server
```
## From NPM
@@ -54,12 +54,12 @@ Sometimes nodejs might run into problems with memory. This is usually resolved b
## Preprocessor
The preprocessor application allows to add custom data to CIF files and/or convert CIF to BinaryCIF. ``node lib/servers/model/preprocess`` or ``model-server-preprocess`` binary from the NPM package.
The preprocessor application allows to add custom data to CIF files and/or convert CIF to BinaryCIF. ``node lib/commonjs/servers/model/preprocess`` or ``model-server-preprocess`` binary from the NPM package.
## Local Mode
The server can be run in local/file based mode using ``node lib/servers/model/query`` (``model-server-query`` binary from the NPM package).
The server can be run in local/file based mode using ``node lib/commonjs/servers/model/query`` (``model-server-query`` binary from the NPM package).
Custom Properties
=================

View File

@@ -28,7 +28,7 @@ npm run build-tsc
and run the server by
```
node lib/servers/volume/server
node lib/commonjs/servers/volume/server
```
## From NPM
@@ -60,11 +60,11 @@ Sometimes nodejs might run into problems with memory. This is usually resolved b
## Preparing the Data
For the server to work, CCP4/MAP (models 0, 1, 2 are supported) input data need to be converted into a custom block format.
To achieve this, use the ``pack`` application (``node lib/servers/volume/pack`` or ``volume-server-pack`` binary from the NPM package).
To achieve this, use the ``pack`` application (``node lib/commonjs/servers/volume/pack`` or ``volume-server-pack`` binary from the NPM package).
## Local Mode
The program ``lib/servers/volume/pack`` (``volume-server-query`` in NPM package) can be used to query the data without running a http server.
The program ``lib/commonjs/servers/volume/pack`` (``volume-server-query`` in NPM package) can be used to query the data without running a http server.
## Navigating the Source Code

48433
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "0.6.2",
"version": "2.0.0-dev.3",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -11,39 +11,46 @@
"url": "https://github.com/molstar/molstar/issues"
},
"scripts": {
"lint": "eslint src/**/*.ts",
"lint": "eslint .",
"lint-fix": "eslint . --fix",
"test": "npm run lint && jest",
"build": "npm run build-tsc && npm run build-extra && npm run build-webpack",
"build-tsc": "tsc --incremental",
"build-extra": "cpx \"src/**/*.{scss,woff,woff2,ttf,otf,eot,svg,html,ico}\" lib/",
"build-webpack": "webpack --mode production",
"watch": "concurrently -c \"green,gray,gray\" --names \"tsc,ext,wpc\" --kill-others \"npm:watch-tsc\" \"npm:watch-extra\" \"npm:watch-webpack\"",
"build-viewer": "npm run build-tsc && npm run build-extra && npm run build-webpack-viewer",
"build-tsc": "concurrently \"tsc --incremental\" \"tsc --build tsconfig.commonjs.json --incremental\"",
"build-extra": "cpx \"src/**/*.{scss,html,ico}\" lib/",
"build-webpack": "webpack --mode production --config ./webpack.config.production.js",
"build-webpack-viewer": "webpack --mode production --config ./webpack.config.viewer.js",
"watch": "concurrently -c \"green,green,gray,gray\" --names \"tsc,srv,ext,wpc\" --kill-others \"npm:watch-tsc\" \"npm:watch-servers\" \"npm:watch-extra\" \"npm:watch-webpack\"",
"watch-viewer": "concurrently -c \"green,gray,gray\" --names \"tsc,ext,wpc\" --kill-others \"npm:watch-tsc\" \"npm:watch-extra\" \"npm:watch-webpack-viewer\"",
"watch-viewer-debug": "concurrently -c \"green,gray,gray\" --names \"tsc,ext,wpc\" --kill-others \"npm:watch-tsc\" \"npm:watch-extra\" \"npm:watch-webpack-viewer-debug\"",
"watch-tsc": "tsc --watch --incremental",
"watch-extra": "cpx \"src/**/*.{scss,woff,woff2,ttf,otf,eot,svg,html,ico}\" lib/ --watch",
"watch-servers": "tsc --build tsconfig.commonjs.json --watch --incremental",
"watch-extra": "cpx \"src/**/*.{scss,html,ico}\" lib/ --watch",
"watch-webpack": "webpack -w --mode development --display minimal",
"watch-webpack-viewer": "webpack -w --mode development --display errors-only --info-verbosity verbose --config ./webpack.config.viewer.js",
"watch-webpack-viewer-debug": "webpack -w --mode development --display errors-only --info-verbosity verbose --config ./webpack.config.viewer.debug.js",
"serve": "http-server -p 1338",
"model-server": "node lib/servers/model/server.js",
"model-server-watch": "nodemon --watch lib lib/servers/model/server.js",
"volume-server-test": "node lib/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
"plugin-state": "node lib/servers/plugin-state/index.js",
"serve": "http-server -p 1338 -g",
"model-server": "node lib/commonjs/servers/model/server.js",
"model-server-watch": "nodemon --watch lib lib/commonjs/servers/model/server.js",
"volume-server-test": "node lib/commonjs/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
"plugin-state": "node lib/commonjs/servers/plugin-state/index.js --working-folder ./build/state --port 1339",
"preversion": "npm run test",
"postversion": "git push && git push --tags",
"prepublishOnly": "npm run test && npm run build"
"version": "npm run build",
"postversion": "git push && git push --tags"
},
"files": [
"lib/"
"lib/",
"build/viewer/"
],
"bin": {
"model-server": "lib/servers/model/server.js",
"model-server-query": "lib/servers/model/local.js",
"model-server-preprocess": "lib/servers/model/preprocess.js",
"volume-server": "lib/servers/volume/server.js",
"volume-server-query": "lib/servers/volume/query.js",
"volume-server-pack": "lib/servers/volume/pack.js"
"cif2bcif": "lib/commonjs/cli/cif2bcif/index.js",
"cifschema": "lib/commonjs/cli/cifschema/index.js",
"model-server": "lib/commonjs/servers/model/server.js",
"model-server-query": "lib/commonjs/servers/model/query.js",
"model-server-preprocess": "lib/commonjs/servers/model/preprocess.js",
"volume-server": "lib/commonjs/servers/volume/server.js",
"volume-server-query": "lib/commonjs/servers/volume/query.js",
"volume-server-pack": "lib/commonjs/servers/volume/pack.js"
},
"nodemonConfig": {
"ignoreRoot": [
@@ -72,70 +79,72 @@
"contributors": [
"Alexander Rose <alexander.rose@weirdbyte.de>",
"David Sehnal <david.sehnal@gmail.com>",
"Sebastian Bittrich <sebastian.bittrich@rcsb.org>"
"Sebastian Bittrich <sebastian.bittrich@rcsb.org>",
"Áron Samuel Kovács <aron.kovacs@mail.muni.cz>",
"Ludovic Autin <autin@scripps.edu>",
"Michal Malý <michal.maly@ibt.cas.cz>",
"Jiří Černý <jiri.cerny@ibt.cas.cz>"
],
"license": "MIT",
"devDependencies": {
"@graphql-codegen/add": "^1.13.1",
"@graphql-codegen/cli": "^1.13.1",
"@graphql-codegen/time": "^1.13.1",
"@graphql-codegen/typescript": "^1.13.1",
"@graphql-codegen/typescript-graphql-files-modules": "^1.13.1",
"@graphql-codegen/typescript-graphql-request": "^1.13.1",
"@graphql-codegen/typescript-operations": "^1.13.1",
"@types/cors": "^2.8.6",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@graphql-codegen/add": "^2.0.2",
"@graphql-codegen/cli": "^1.19.4",
"@graphql-codegen/time": "^2.0.2",
"@graphql-codegen/typescript": "^1.19.0",
"@graphql-codegen/typescript-graphql-files-modules": "^1.18.1",
"@graphql-codegen/typescript-graphql-request": "^2.0.3",
"@graphql-codegen/typescript-operations": "^1.17.12",
"@types/cors": "^2.8.8",
"@typescript-eslint/eslint-plugin": "^4.9.1",
"@typescript-eslint/parser": "^4.9.1",
"benchmark": "^2.1.4",
"circular-dependency-plugin": "^5.2.0",
"concurrently": "^5.1.0",
"cpx2": "^2.0.0",
"css-loader": "^3.4.2",
"eslint": "^6.8.0",
"concurrently": "^5.3.0",
"cpx2": "^3.0.0",
"css-loader": "^5.0.1",
"eslint": "^7.15.0",
"extra-watch-webpack-plugin": "^1.0.3",
"file-loader": "^6.0.0",
"fs-extra": "^9.0.0",
"http-server": "^0.12.1",
"jest": "^25.2.7",
"jest-raw-loader": "^1.0.1",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.13.1",
"pascal-case": "^3.1.1",
"raw-loader": "^4.0.0",
"resolve-url-loader": "^3.1.1",
"sass-loader": "^8.0.2",
"simple-git": "^1.132.0",
"style-loader": "^1.1.3",
"ts-jest": "^25.3.1",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
"file-loader": "^6.2.0",
"fs-extra": "^9.0.1",
"graphql": "^15.4.0",
"http-server": "^0.12.3",
"jest": "^26.6.3",
"mini-css-extract-plugin": "^1.3.2",
"node-sass": "^5.0.0",
"raw-loader": "^4.0.2",
"sass-loader": "^10.1.0",
"simple-git": "^2.25.0",
"style-loader": "^2.0.0",
"ts-jest": "^26.4.4",
"typescript": "^4.1.2",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-version-file-plugin": "^0.4.0"
},
"dependencies": {
"@types/argparse": "^1.0.38",
"@types/benchmark": "^1.0.31",
"@types/benchmark": "^2.1.0",
"@types/compression": "1.7.0",
"@types/express": "^4.17.4",
"@types/jest": "^25.2.1",
"@types/node": "^13.11.0",
"@types/node-fetch": "^2.5.5",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
"@types/swagger-ui-dist": "3.0.5",
"@types/express": "^4.17.9",
"@types/jest": "^26.0.18",
"@types/node": "^14.14.11",
"@types/node-fetch": "^2.5.7",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/swagger-ui-dist": "3.30.0",
"argparse": "^1.0.10",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"cors": "^2.8.5",
"express": "^4.17.1",
"graphql": "^14.6.0",
"immer": "^6.0.3",
"h264-mp4-encoder": "^1.0.12",
"immer": "^8.0.0",
"immutable": "^3.8.2",
"node-fetch": "^2.6.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"rxjs": "^6.5.5",
"swagger-ui-dist": "^3.25.0",
"tslib": "^1.11.1",
"node-fetch": "^2.6.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rxjs": "^6.6.3",
"swagger-ui-dist": "^3.37.2",
"tslib": "^2.0.3",
"util.promisify": "^1.0.1",
"xhr2": "^0.2.0"
}

View File

@@ -4,40 +4,40 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
const git = require('simple-git')
const path = require('path')
const fs = require("fs")
const fse = require("fs-extra")
const git = require('simple-git');
const path = require('path');
const fs = require("fs");
const fse = require("fs-extra");
const remoteUrl = "https://github.com/molstar/molstar.github.io.git"
const buildDir = path.resolve(__dirname, '../build/')
const deployDir = path.resolve(buildDir, 'deploy/')
const localPath = path.resolve(deployDir, 'molstar.github.io/')
const remoteUrl = "https://github.com/molstar/molstar.github.io.git";
const buildDir = path.resolve(__dirname, '../build/');
const deployDir = path.resolve(buildDir, 'deploy/');
const localPath = path.resolve(deployDir, 'molstar.github.io/');
function log(command, stdout, stderr) {
if (command) {
console.log('\n###', command)
stdout.pipe(process.stdout)
stderr.pipe(process.stderr)
console.log('\n###', command);
stdout.pipe(process.stdout);
stderr.pipe(process.stderr);
}
}
function copyViewer() {
console.log('\n###', 'copy viewer files')
const viewerBuildPath = path.resolve(buildDir, '../build/viewer/')
const viewerDeployPath = path.resolve(localPath, 'viewer/')
fse.copySync(viewerBuildPath, viewerDeployPath, { overwrite: true })
console.log('\n###', 'copy viewer files');
const viewerBuildPath = path.resolve(buildDir, '../build/viewer/');
const viewerDeployPath = path.resolve(localPath, 'viewer/');
fse.copySync(viewerBuildPath, viewerDeployPath, { overwrite: true });
}
if (!fs.existsSync(localPath)) {
console.log('\n###', 'create localPath')
fs.mkdirSync(localPath, { recursive: true })
console.log('\n###', 'create localPath');
fs.mkdirSync(localPath, { recursive: true });
}
process.chdir(localPath);
if (!fs.existsSync(path.resolve(localPath, '.git/'))) {
console.log('\n###', 'clone repository')
console.log('\n###', 'clone repository');
git()
.outputHandler(log)
.clone(remoteUrl, localPath)
@@ -45,9 +45,9 @@ if (!fs.existsSync(path.resolve(localPath, '.git/'))) {
.exec(copyViewer)
.add(['-A'])
.commit('updated viewer')
.push()
.push();
} else {
console.log('\n###', 'update repository')
console.log('\n###', 'update repository');
git()
.outputHandler(log)
.fetch(['--all'])
@@ -55,5 +55,5 @@ if (!fs.existsSync(path.resolve(localPath, '.git/'))) {
.exec(copyViewer)
.add(['-A'])
.commit('updated viewer')
.push()
.push();
}

View File

@@ -1,30 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { PluginUIComponent } from '../../mol-plugin-ui/base';
import * as React from 'react';
import { TransformUpdaterControl } from '../../mol-plugin-ui/state/update-transform';
export class BasicWrapperControls extends PluginUIComponent {
render() {
return <div style={{ overflowY: 'auto', display: 'block', height: '100%' }}>
<TransformUpdaterControl nodeRef='asm' />
<TransformUpdaterControl nodeRef='seq-visual' header={{ name: 'Sequence Visual' }} />
<TransformUpdaterControl nodeRef='het-visual' header={{ name: 'HET Visual' }} />
<TransformUpdaterControl nodeRef='water-visual' header={{ name: 'Water Visual' }} initiallyCollapsed={true} />
<TransformUpdaterControl nodeRef='ihm-visual' header={{ name: 'I/HM Visual' }} initiallyCollapsed={true} />
</div>;
}
}
export class CustomToastMessage extends PluginUIComponent {
render() {
return <>
Custom <i>Toast</i> content. No timeout.
</>;
}
}

View File

@@ -1,99 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Mat4, Vec3 } from '../../mol-math/linear-algebra';
import { PluginContext } from '../../mol-plugin/context';
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { StateBuilder } from '../../mol-state';
import Expression from '../../mol-script/language/expression';
import { ColorTheme } from '../../mol-theme/color';
import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
type SupportedFormats = 'cif' | 'pdb'
export namespace StateHelper {
export function download(b: StateBuilder.To<PSO.Root>, url: string, ref?: string) {
return b.apply(StateTransforms.Data.Download, { url, isBinary: false }, { ref });
}
export function getModel(b: StateBuilder.To<PSO.Data.Binary | PSO.Data.String>, format: SupportedFormats, modelIndex = 0) {
const parsed = format === 'cif'
? b.apply(StateTransforms.Data.ParseCif).apply(StateTransforms.Model.TrajectoryFromMmCif)
: b.apply(StateTransforms.Model.TrajectoryFromPDB);
return parsed.apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex });
}
export function structure(b: StateBuilder.To<PSO.Molecule.Model>) {
return b.apply(StateTransforms.Model.StructureFromModel, void 0, { tags: 'structure' })
};
export function selectChain(b: StateBuilder.To<PSO.Molecule.Structure>, auth_asym_id: string) {
const expression = MS.struct.generator.atomGroups({
'chain-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.auth_asym_id(), auth_asym_id])
})
return b.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression, label: `Chain ${auth_asym_id}` });
}
export function select(b: StateBuilder.To<PSO.Molecule.Structure>, expression: Expression) {
return b.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression });
}
export function selectSurroundingsOfFirstResidue(b: StateBuilder.To<PSO.Molecule.Structure>, comp_id: string, radius: number) {
const expression = MS.struct.modifier.includeSurroundings({
0: MS.struct.filter.first([
MS.struct.generator.atomGroups({
'residue-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.label_comp_id(), comp_id]),
'group-by': MS.struct.atomProperty.macromolecular.residueKey()
})
]),
radius
})
return b.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression, label: `Surr. ${comp_id} (${radius} ang)` });
}
export function identityTransform(b: StateBuilder.To<PSO.Molecule.Structure>, m: Mat4) {
return b.apply(StateTransforms.Model.TransformStructureConformation,
{ transform: { name: 'components', params: { axis: Vec3.create(1, 0, 0), angle: 0, translation: Vec3.zero() } } },
{ tags: 'transform' });
}
export function transform(b: StateBuilder.To<PSO.Molecule.Structure>, matrix: Mat4) {
return b.apply(StateTransforms.Model.TransformStructureConformation, {
transform: { name: 'matrix', params: matrix }
}, { tags: 'transform' });
}
export function assemble(b: StateBuilder.To<PSO.Molecule.Model>, id?: string) {
const props = {
type: {
name: 'assembly' as const,
params: { id: id || 'deposited' }
}
}
return b.apply(StateTransforms.Model.StructureFromModel, props, { tags: 'asm' })
}
export function visual(ctx: PluginContext, visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(ctx, void 0, { type: 'cartoon' }), { tags: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(ctx, void 0, { type: 'ball-and-stick' }), { tags: 'het-visual' });
return visualRoot;
}
export function ballsAndSticks(ctx: PluginContext, visualRoot: StateBuilder.To<PSO.Molecule.Structure>, expression: Expression, color?: ColorTheme.BuiltIn) {
visualRoot
.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(ctx, void 0, { type: 'ball-and-stick', color }), { tags: 'het-visual' });
return visualRoot;
}
}

View File

@@ -1,219 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import './index.html'
import { PluginContext } from '../../mol-plugin/context';
import { PluginCommands } from '../../mol-plugin/commands';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { Color } from '../../mol-util/color';
import { PluginStateObject as PSO, PluginStateObject } from '../../mol-plugin-state/objects';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in';
import { StateBuilder, StateTransform } from '../../mol-state';
import { StripedResidues } from './coloring';
import { StaticSuperpositionTestData, buildStaticSuperposition, dynamicSuperpositionTest } from './superposition';
import { PDBeStructureQualityReport } from '../../mol-plugin/behavior/dynamic/custom-props';
import { CustomToastMessage } from './controls';
import { EmptyLoci } from '../../mol-model/loci';
import { StructureSelection } from '../../mol-model/structure';
import { Script } from '../../mol-script/script';
import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
require('mol-plugin-ui/skin/light.scss')
type SupportedFormats = 'cif' | 'pdb'
type LoadParams = { url: string, format?: SupportedFormats, assemblyId?: string }
class BasicWrapper {
plugin: PluginContext;
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
layout: {
initial: {
isExpanded: false,
showControls: false
},
controls: {
// left: 'none',
// right: BasicWrapperControls
}
},
components: {
remoteState: 'none'
}
});
this.plugin.representation.structure.themes.colorThemeRegistry.add(StripedResidues.colorThemeProvider!);
this.plugin.managers.lociLabels.addProvider(StripedResidues.labelProvider!);
this.plugin.customModelProperties.register(StripedResidues.propertyProvider, true);
}
private download(b: StateBuilder.To<PSO.Root>, url: string) {
return b.apply(StateTransforms.Data.Download, { url, isBinary: false })
}
private parse(b: StateBuilder.To<PSO.Data.Binary | PSO.Data.String>, format: SupportedFormats, assemblyId: string) {
const parsed = format === 'cif'
? b.apply(StateTransforms.Data.ParseCif).apply(StateTransforms.Model.TrajectoryFromMmCif)
: b.apply(StateTransforms.Model.TrajectoryFromPDB);
const props = {
type: {
name: 'assembly' as const,
params: { id: assemblyId || 'deposited' }
}
}
return parsed
.apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 })
.apply(StateTransforms.Model.CustomModelProperties, { autoAttach: [StripedResidues.propertyProvider.descriptor.name], properties: {} }, { ref: 'props', state: { isGhost: false } })
.apply(StateTransforms.Model.StructureFromModel, props, { ref: 'asm' });
}
private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' }, { ref: 'seq' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'cartoon' }), { ref: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'ball-and-stick' }), { ref: 'het-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'ball-and-stick', typeParams: { alpha: 0.51 } }), { ref: 'water-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'spacefill' }), { ref: 'ihm-visual' });
return visualRoot;
}
private loadedParams: LoadParams = { url: '', format: 'cif', assemblyId: '' };
async load({ url, format = 'cif', assemblyId = '' }: LoadParams) {
let loadType: 'full' | 'update' = 'full';
const state = this.plugin.state.data;
if (this.loadedParams.url !== url || this.loadedParams.format !== format) {
loadType = 'full';
} else if (this.loadedParams.url === url) {
if (state.select('asm').length > 0) loadType = 'update';
}
let tree: StateBuilder.Root;
if (loadType === 'full') {
await PluginCommands.State.RemoveObject(this.plugin, { state, ref: state.tree.root.ref });
tree = state.build();
this.visual(this.parse(this.download(tree.toRoot(), url), format, assemblyId));
} else {
const props = {
type: {
name: 'assembly' as const,
params: { id: assemblyId || 'deposited' }
}
}
tree = state.build();
tree.to('asm').update(StateTransforms.Model.StructureFromModel, p => ({ ...p, ...props }));
}
await PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree });
this.loadedParams = { url, format, assemblyId };
PluginCommands.Camera.Reset(this.plugin, { });
}
setBackground(color: number) {
const renderer = this.plugin.canvas3d!.props.renderer;
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: { renderer: { ...renderer, backgroundColor: Color(color) } } });
}
toggleSpin() {
if (!this.plugin.canvas3d) return;
const trackball = this.plugin.canvas3d.props.trackball;
const spinning = trackball.spin;
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: { trackball: { ...trackball, spin: !trackball.spin } } });
if (!spinning) PluginCommands.Camera.Reset(this.plugin, { });
}
animate = {
modelIndex: {
maxFPS: 8,
onceForward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }) },
onceBackward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }) },
palindrome: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }) },
loop: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }) },
stop: () => this.plugin.state.animation.stop()
}
}
coloring = {
applyStripes: async () => {
const state = this.plugin.state.data;
const visuals = state.selectQ(q => q.ofTransformer(StateTransforms.Representation.StructureRepresentation3D));
const tree = state.build();
const colorTheme = { name: StripedResidues.propertyProvider.descriptor.name, params: this.plugin.representation.structure.themes.colorThemeRegistry.get(StripedResidues.propertyProvider.descriptor.name).defaultValues };
for (const v of visuals) {
tree.to(v).update(old => ({ ...old, colorTheme }));
}
await PluginCommands.State.Update(this.plugin, { state, tree });
}
}
interactivity = {
highlightOn: () => {
const seq_id = 7;
const data = (this.plugin.state.data.select('asm')[0].obj as PluginStateObject.Molecule.Structure).data;
const sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
'residue-test': Q.core.rel.eq([Q.struct.atomProperty.macromolecular.label_seq_id(), seq_id]),
'group-by': Q.struct.atomProperty.macromolecular.residueKey()
}), data);
const loci = StructureSelection.toLociWithSourceUnits(sel);
this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci });
},
clearHighlight: () => {
this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci: EmptyLoci });
}
}
tests = {
staticSuperposition: async () => {
const state = this.plugin.state.data;
const tree = buildStaticSuperposition(this.plugin, StaticSuperpositionTestData);
await PluginCommands.State.RemoveObject(this.plugin, { state, ref: StateTransform.RootRef });
await PluginCommands.State.Update(this.plugin, { state, tree });
},
dynamicSuperposition: async () => {
await PluginCommands.State.RemoveObject(this.plugin, { state: this.plugin.state.data, ref: StateTransform.RootRef });
await dynamicSuperpositionTest(this.plugin, ['1tqn', '2hhb', '4hhb'], 'HEM');
},
toggleValidationTooltip: async () => {
const state = this.plugin.state.behaviors;
const tree = state.build().to(PDBeStructureQualityReport.id).update(PDBeStructureQualityReport, p => ({ ...p, showTooltip: !p.showTooltip }));
await PluginCommands.State.Update(this.plugin, { state, tree });
},
showToasts: () => {
PluginCommands.Toast.Show(this.plugin, {
title: 'Toast 1',
message: 'This is an example text, timeout 3s',
key: 'toast-1',
timeoutMs: 3000
});
PluginCommands.Toast.Show(this.plugin, {
title: 'Toast 2',
message: CustomToastMessage,
key: 'toast-2'
});
},
hideToasts: () => {
PluginCommands.Toast.Hide(this.plugin, { key: 'toast-1' });
PluginCommands.Toast.Hide(this.plugin, { key: 'toast-2' });
}
}
}
(window as any).BasicMolStarWrapper = new BasicWrapper();

View File

@@ -1,108 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
// TODO: move to an "example"
import { PluginContext } from '../../mol-plugin/context';
import { Mat4 } from '../../mol-math/linear-algebra';
import { StateHelper } from './helpers';
import { PluginCommands } from '../../mol-plugin/commands';
import { StateSelection, StateBuilder } from '../../mol-state';
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { compile } from '../../mol-script/runtime/query/compiler';
import { StructureSelection, QueryContext } from '../../mol-model/structure';
import { superposeStructures } from '../../mol-model/structure/structure/util/superposition';
import Expression from '../../mol-script/language/expression';
export type SuperpositionTestInput = {
pdbId: string,
auth_asym_id: string,
matrix: Mat4
}[];
// function getAxisAngleTranslation(m: Mat4) {
// const translation = Mat4.getTranslation(Vec3.zero(), m);
// const axis = Vec3.zero();
// const angle = 180 / Math.PI * Quat.getAxisAngle(axis, Mat4.getRotation(Quat.zero(), m));
// return { translation, axis, angle };
// }
export function buildStaticSuperposition(ctx: PluginContext, src: SuperpositionTestInput) {
const b = ctx.state.data.build().toRoot();
for (const s of src) {
StateHelper.visual(ctx,
StateHelper.transform(
StateHelper.selectChain(
StateHelper.structure(
StateHelper.getModel(StateHelper.download(b, `https://www.ebi.ac.uk/pdbe/static/entry/${s.pdbId}_updated.cif`), 'cif')),
s.auth_asym_id
),
s.matrix
)
);
}
return b;
}
export const StaticSuperpositionTestData: SuperpositionTestInput = [
{ pdbId: '1aj5', auth_asym_id: 'A', matrix: Mat4.identity() },
{ pdbId: '1df0', auth_asym_id: 'B', matrix: Mat4.ofRows([
[0.406, 0.879, 0.248, -200.633],
[0.693, -0.473, 0.544, 73.403],
[0.596, -0.049, -0.802, -14.209],
[0, 0, 0, 1]] )},
{ pdbId: '1dvi', auth_asym_id: 'A', matrix: Mat4.ofRows([
[-0.053, -0.077, 0.996, -45.633],
[-0.312, 0.949, 0.057, -12.255],
[-0.949, -0.307, -0.074, 53.562],
[0, 0, 0, 1]] )}
];
export async function dynamicSuperpositionTest(ctx: PluginContext, src: string[], comp_id: string) {
const state = ctx.state.data;
const structures = state.build().toRoot();
for (const s of src) {
StateHelper.structure(
StateHelper.getModel(StateHelper.download(structures, `https://www.ebi.ac.uk/pdbe/static/entry/${s}_updated.cif`), 'cif'));
}
await PluginCommands.State.Update(ctx, { state, tree: structures });
const pivot = MS.struct.filter.first([
MS.struct.generator.atomGroups({
'residue-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.label_comp_id(), comp_id]),
'group-by': MS.struct.atomProperty.macromolecular.residueKey()
})
]);
const rest = MS.struct.modifier.exceptBy({
0: MS.struct.generator.all(),
by: pivot
});
const query = compile<StructureSelection>(pivot);
const xs = state.select(StateSelection.Generators.rootsOfType(PSO.Molecule.Structure));
const selections = xs.map(s => StructureSelection.toLociWithCurrentUnits(query(new QueryContext(s.obj!.data))));
const transforms = superposeStructures(selections);
const visuals = state.build();
siteVisual(ctx, StateHelper.selectSurroundingsOfFirstResidue(visuals.to(xs[0].transform.ref), 'HEM', 7), pivot, rest);
for (let i = 1; i < selections.length; i++) {
const root = visuals.to(xs[i].transform.ref);
siteVisual(ctx,
StateHelper.transform(StateHelper.selectSurroundingsOfFirstResidue(root, 'HEM', 7), transforms[i - 1].bTransform),
pivot, rest);
}
await PluginCommands.State.Update(ctx, { state, tree: visuals });
}
function siteVisual(ctx: PluginContext, b: StateBuilder.To<PSO.Molecule.Structure>, pivot: Expression, rest: Expression) {
StateHelper.ballsAndSticks(ctx, b, pivot, 'residue-name');
StateHelper.ballsAndSticks(ctx, b, rest, 'uniform');
}

View File

@@ -1,252 +0,0 @@
/**
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse'
import * as util from 'util'
import * as path from 'path'
import * as fs from 'fs'
import * as zlib from 'zlib'
import fetch from 'node-fetch'
require('util.promisify').shim()
const readFile = util.promisify(fs.readFile)
const writeFile = util.promisify(fs.writeFile)
import { Progress } from '../../mol-task'
import { Database, Table, DatabaseCollection } from '../../mol-data/db'
import { CIF } from '../../mol-io/reader/cif'
import { CifWriter } from '../../mol-io/writer/cif'
import { CCD_Schema } from '../../mol-io/reader/cif/schema/ccd'
import { SetUtils } from '../../mol-util/set'
import { DefaultMap } from '../../mol-util/map'
import { mmCIF_chemCompBond_schema } from '../../mol-io/reader/cif/schema/mmcif-extras';
export async function ensureAvailable(path: string, url: string) {
if (FORCE_DOWNLOAD || !fs.existsSync(path)) {
console.log(`downloading ${url}...`)
const data = await fetch(url)
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR);
}
if (url.endsWith('.gz')) {
await writeFile(path, zlib.gunzipSync(await data.buffer()))
} else {
await writeFile(path, await data.text())
}
console.log(`done downloading ${url}`)
}
}
export async function ensureDataAvailable() {
await ensureAvailable(CCD_PATH, CCD_URL)
await ensureAvailable(PVCD_PATH, PVCD_URL)
}
export async function readFileAsCollection<S extends Database.Schema>(path: string, schema: S) {
const parsed = await parseCif(await readFile(path, 'utf8'))
return CIF.toDatabaseCollection(schema, parsed.result)
}
export async function readCCD() {
return readFileAsCollection(CCD_PATH, CCD_Schema)
}
export async function readPVCD() {
return readFileAsCollection(PVCD_PATH, CCD_Schema)
}
async function parseCif(data: string | Uint8Array) {
const comp = CIF.parse(data);
console.time('parse cif');
const parsed = await comp.run(p => console.log(Progress.format(p)), 250);
console.timeEnd('parse cif');
if (parsed.isError) throw parsed;
return parsed
}
export function getEncodedCif(name: string, database: Database<Database.Schema>, binary = false) {
const encoder = CifWriter.createEncoder({ binary, encoderName: 'mol*' });
CifWriter.Encoder.writeDatabase(encoder, name, database)
return encoder.getData();
}
type CCB = Table<CCD_Schema['chem_comp_bond']>
type CCA = Table<CCD_Schema['chem_comp_atom']>
function ccbKey(compId: string, atomId1: string, atomId2: string) {
return atomId1 < atomId2 ? `${compId}:${atomId1}-${atomId2}` : `${compId}:${atomId2}-${atomId1}`
}
function addChemCompBondToSet(set: Set<string>, ccb: CCB) {
for (let i = 0, il = ccb._rowCount; i < il; ++i) {
set.add(ccbKey(ccb.comp_id.value(i), ccb.atom_id_1.value(i), ccb.atom_id_2.value(i)))
}
return set
}
function addChemCompAtomToSet(set: Set<string>, cca: CCA) {
for (let i = 0, il = cca._rowCount; i < il; ++i) {
set.add(cca.atom_id.value(i))
}
return set
}
function checkAddingBondsFromPVCD(pvcd: DatabaseCollection<CCD_Schema>) {
const ccbSetByParent = DefaultMap<string, Set<string>>(() => new Set())
for (const k in pvcd) {
const { chem_comp, chem_comp_bond } = pvcd[k]
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0)
if (parentIds.length === 0) {
const set = ccbSetByParent.getDefault(chem_comp.id.value(0))
addChemCompBondToSet(set, chem_comp_bond)
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
const parentId = parentIds[i]
const set = ccbSetByParent.getDefault(parentId)
addChemCompBondToSet(set, chem_comp_bond)
}
}
}
}
for (const k in pvcd) {
const { chem_comp, chem_comp_atom, chem_comp_bond } = pvcd[k]
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0)
if (parentIds.length > 0) {
for (let i = 0, il = parentIds.length; i < il; ++i) {
const entryBonds = addChemCompBondToSet(new Set<string>(), chem_comp_bond)
const entryAtoms = addChemCompAtomToSet(new Set<string>(), chem_comp_atom)
const extraBonds = SetUtils.difference(ccbSetByParent.get(parentIds[i])!, entryBonds)
extraBonds.forEach(bk => {
const [a1, a2] = bk.split('|')
if (entryAtoms.has(a1) && entryAtoms.has(a2)) {
console.error(`Adding all PVCD bonds would wrongly add bond ${bk} for ${k}`)
}
})
}
}
}
}
}
async function createBonds() {
await ensureDataAvailable()
const ccd = await readCCD()
const pvcd = await readPVCD()
const ccbSet = new Set<string>()
const comp_id: string[] = []
const atom_id_1: string[] = []
const atom_id_2: string[] = []
const value_order: typeof mmCIF_chemCompBond_schema['value_order']['T'][] = []
const pdbx_aromatic_flag: typeof mmCIF_chemCompBond_schema['pdbx_aromatic_flag']['T'][] = []
const pdbx_stereo_config: typeof mmCIF_chemCompBond_schema['pdbx_stereo_config']['T'][] = []
const molstar_protonation_variant: string[] = []
function addBonds(compId: string, ccb: CCB, protonationVariant: boolean) {
for (let i = 0, il = ccb._rowCount; i < il; ++i) {
const atomId1 = ccb.atom_id_1.value(i)
const atomId2 = ccb.atom_id_2.value(i)
const k = ccbKey(compId, atomId1, atomId2)
if (!ccbSet.has(k)) {
atom_id_1.push(atomId1)
atom_id_2.push(atomId2)
comp_id.push(compId)
value_order.push(ccb.value_order.value(i))
pdbx_aromatic_flag.push(ccb.pdbx_aromatic_flag.value(i))
pdbx_stereo_config.push(ccb.pdbx_stereo_config.value(i))
molstar_protonation_variant.push(protonationVariant ? 'Y' : 'N')
ccbSet.add(k)
}
}
}
// check adding bonds from PVCD
checkAddingBondsFromPVCD(pvcd)
// add bonds from PVCD
for (const k in pvcd) {
const { chem_comp, chem_comp_bond } = pvcd[k]
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0)
if (parentIds.length === 0) {
addBonds(chem_comp.id.value(0), chem_comp_bond, false)
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
addBonds(parentIds[i], chem_comp_bond, true)
}
}
}
}
// add bonds from CCD
for (const k in ccd) {
const { chem_comp, chem_comp_bond } = ccd[k]
if (chem_comp_bond._rowCount) {
addBonds(chem_comp.id.value(0), chem_comp_bond, false)
}
}
const bondTable = Table.ofArrays(mmCIF_chemCompBond_schema, {
comp_id, atom_id_1, atom_id_2, value_order,
pdbx_aromatic_flag, pdbx_stereo_config, molstar_protonation_variant
})
const bondDatabase = Database.ofTables(
TABLE_NAME,
{ chem_comp_bond: mmCIF_chemCompBond_schema },
{ chem_comp_bond: bondTable }
)
return bondDatabase
}
async function run(out: string, binary = false) {
const bonds = await createBonds()
const cif = getEncodedCif(TABLE_NAME, bonds, binary)
if (!fs.existsSync(path.dirname(out))) {
fs.mkdirSync(path.dirname(out));
}
writeFile(out, cif)
}
const TABLE_NAME = 'CHEM_COMP_BONDS'
const DATA_DIR = path.join(__dirname, '..', '..', '..', 'build/data')
const CCD_PATH = path.join(DATA_DIR, 'components.cif')
const PVCD_PATH = path.join(DATA_DIR, 'aa-variants-v1.cif')
const CCD_URL = 'http://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif'
const PVCD_URL = 'http://ftp.wwpdb.org/pub/pdb/data/monomers/aa-variants-v1.cif'
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Create a cif file with one big table of all chem_comp_bond entries from the CCD and PVCD.'
});
parser.addArgument('out', {
help: 'Generated file output path.'
});
parser.addArgument([ '--forceDownload', '-f' ], {
action: 'storeTrue',
help: 'Force download of CCD and PVCD.'
});
parser.addArgument([ '--binary', '-b' ], {
action: 'storeTrue',
help: 'Output as BinaryCIF.'
});
interface Args {
out: string
forceDownload?: boolean
binary?: boolean
}
const args: Args = parser.parseArgs();
const FORCE_DOWNLOAD = args.forceDownload
run(args.out, args.binary)

View File

@@ -1,178 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { createPlugin, DefaultPluginSpec } from '../../../mol-plugin';
import './index.html'
import { PluginContext } from '../../../mol-plugin/context';
import { PluginCommands } from '../../../mol-plugin/commands';
import { StateTransforms } from '../../../mol-plugin-state/transforms';
import { PluginStateObject as PSO } from '../../../mol-plugin-state/objects';
import { StateBuilder } from '../../../mol-state';
import { Canvas3DProps } from '../../../mol-canvas3d/canvas3d';
import { createStructureRepresentationParams } from '../../../mol-plugin-state/helpers/structure-representation-params';
require('mol-plugin-ui/skin/light.scss')
type SupportedFormats = 'cif' | 'pdb'
type LoadParams = { url: string, format?: SupportedFormats, assemblyId?: string }
const Canvas3DPresets = {
illustrative: {
multiSample: {
mode: 'temporal' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusionEnable: true,
occlusionBias: 0.8,
occlusionKernelSize: 6,
outlineEnable: true,
},
renderer: {
ambientIntensity: 1,
lightIntensity: 0,
}
},
occlusion: {
multiSample: {
mode: 'temporal' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusionEnable: true,
occlusionBias: 0.8,
occlusionKernelSize: 6,
outlineEnable: false,
},
renderer: {
ambientIntensity: 0.4,
lightIntensity: 0.6,
}
},
standard: {
multiSample: {
mode: 'off' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusionEnable: false,
outlineEnable: false,
},
renderer: {
ambientIntensity: 0.4,
lightIntensity: 0.6,
}
}
}
type Canvas3DPreset = keyof typeof Canvas3DPresets
function getPreset(preset: Canvas3DPreset) {
switch (preset) {
case 'illustrative': return Canvas3DPresets['illustrative']
case 'standard': return Canvas3DPresets['standard']
case 'occlusion': return Canvas3DPresets['occlusion']
}
}
class LightingDemo {
plugin: PluginContext;
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
layout: {
initial: {
isExpanded: false,
showControls: false
},
controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }
}
});
this.setPreset('illustrative');
}
setPreset(preset: Canvas3DPreset) {
const props = getPreset(preset)
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: {
...props,
multiSample: {
...this.plugin.canvas3d!.props.multiSample,
...props.multiSample
},
renderer: {
...this.plugin.canvas3d!.props.renderer,
...props.renderer
},
postprocessing: {
...this.plugin.canvas3d!.props.postprocessing,
...props.postprocessing
},
}});
}
private download(b: StateBuilder.To<PSO.Root>, url: string) {
return b.apply(StateTransforms.Data.Download, { url, isBinary: false })
}
private parse(b: StateBuilder.To<PSO.Data.Binary | PSO.Data.String>, format: SupportedFormats, assemblyId: string) {
const parsed = format === 'cif'
? b.apply(StateTransforms.Data.ParseCif).apply(StateTransforms.Model.TrajectoryFromMmCif)
: b.apply(StateTransforms.Model.TrajectoryFromPDB);
const props = {
type: {
name: 'assembly' as const,
params: { id: assemblyId || 'deposited' }
}
}
return parsed
.apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 })
.apply(StateTransforms.Model.StructureFromModel, props, { ref: 'asm' });
}
private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'spacefill', color: 'illustrative' }), { ref: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
createStructureRepresentationParams(this.plugin, void 0, { type: 'ball-and-stick' }), { ref: 'het-visual' });
return visualRoot;
}
private loadedParams: LoadParams = { url: '', format: 'cif', assemblyId: '' };
async load({ url, format = 'cif', assemblyId = '' }: LoadParams) {
let loadType: 'full' | 'update' = 'full';
const state = this.plugin.state.data;
if (this.loadedParams.url !== url || this.loadedParams.format !== format) {
loadType = 'full';
} else if (this.loadedParams.url === url) {
if (state.select('asm').length > 0) loadType = 'update';
}
let tree: StateBuilder.Root;
if (loadType === 'full') {
await PluginCommands.State.RemoveObject(this.plugin, { state, ref: state.tree.root.ref });
tree = state.build();
this.visual(this.parse(this.download(tree.toRoot(), url), format, assemblyId));
} else {
const props = {
type: {
name: 'assembly' as const,
params: { id: assemblyId || 'deposited' }
}
}
tree = state.build();
tree.to('asm').update(StateTransforms.Model.StructureFromModel, p => ({ ...p, ...props }));
}
await PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree });
this.loadedParams = { url, format, assemblyId };
PluginCommands.Camera.Reset(this.plugin, { });
}
}
(window as any).LightingDemo = new LightingDemo();

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Mol* Docking Viewer</title>
<style>
#app {
position: absolute;
left: 100px;
top: 100px;
width: 800px;
height: 600px;
}
</style>
<link rel="stylesheet" type="text/css" href="molstar.css" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./molstar.js"></script>
<script type="text/javascript">
var viewer = new DockingViewer('app', [0x33DD22, 0x1133EE], true);
function getParam(name, regex) {
var r = new RegExp(name + '=' + '(' + regex + ')[&]?', 'i');
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
}
var pdbqt = getParam('pdbqt', '[^&]+').trim();
var mol2 = getParam('mol2', '[^&]+').trim();
viewer.loadStructuresFromUrlsAndMerge([
{ url: pdbqt, format: 'pdbqt' },
{ url: mol2, format: 'mol2' }
]);
</script>
</body>
</html>

View File

@@ -0,0 +1,213 @@
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import '../../mol-util/polyfill';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import './index.html';
import { PluginContext } from '../../mol-plugin/context';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginSpec } from '../../mol-plugin/spec';
import { PluginConfig } from '../../mol-plugin/config';
import { ObjectKeys } from '../../mol-util/type-helpers';
import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { Structure } from '../../mol-model/structure';
import { PluginStateTransform, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Task } from '../../mol-task';
import { StateObject } from '../../mol-state';
import { ViewportComponent, StructurePreset, ShowButtons } from './viewport';
import { PluginBehaviors } from '../../mol-plugin/behavior';
import { ColorNames } from '../../mol-util/color/names';
import { Color } from '../../mol-util/color';
require('mol-plugin-ui/skin/light.scss');
export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
export { setProductionMode, setDebugMode } from '../../mol-util/debug';
const DefaultViewerOptions = {
extensions: ObjectKeys({}),
layoutIsExpanded: true,
layoutShowControls: true,
layoutShowRemoteState: true,
layoutControlsDisplay: 'reactive' as PluginLayoutControlsDisplay,
layoutShowSequence: true,
layoutShowLog: true,
layoutShowLeftPanel: true,
viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue,
viewportShowControls: PluginConfig.Viewport.ShowControls.defaultValue,
viewportShowSettings: PluginConfig.Viewport.ShowSettings.defaultValue,
viewportShowSelectionMode: PluginConfig.Viewport.ShowSelectionMode.defaultValue,
viewportShowAnimation: PluginConfig.Viewport.ShowAnimation.defaultValue,
pluginStateServer: PluginConfig.State.DefaultServer.defaultValue,
volumeStreamingServer: PluginConfig.VolumeStreaming.DefaultServer.defaultValue,
pdbProvider: PluginConfig.Download.DefaultPdbProvider.defaultValue,
emdbProvider: PluginConfig.Download.DefaultEmdbProvider.defaultValue,
};
class Viewer {
plugin: PluginContext
constructor(elementOrId: string | HTMLElement, colors = [Color(0x992211), Color(0xDDDDDD)], showButtons = true) {
const o = { ...DefaultViewerOptions, ...{
layoutIsExpanded: false,
layoutShowControls: false,
layoutShowRemoteState: false,
layoutShowSequence: true,
layoutShowLog: false,
layoutShowLeftPanel: true,
viewportShowExpand: true,
viewportShowControls: false,
viewportShowSettings: false,
viewportShowSelectionMode: false,
viewportShowAnimation: false,
} };
const defaultSpec = DefaultPluginSpec();
const spec: PluginSpec = {
actions: [...defaultSpec.actions],
behaviors: [
PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci, { mark: false }),
PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider),
PluginSpec.Behavior(PluginBehaviors.Camera.FocusLoci),
PluginSpec.Behavior(PluginBehaviors.CustomProps.StructureInfo),
PluginSpec.Behavior(PluginBehaviors.CustomProps.Interactions),
PluginSpec.Behavior(PluginBehaviors.CustomProps.SecondaryStructure),
],
animations: [...defaultSpec.animations || []],
customParamEditors: defaultSpec.customParamEditors,
layout: {
initial: {
isExpanded: o.layoutIsExpanded,
showControls: o.layoutShowControls,
controlsDisplay: o.layoutControlsDisplay,
},
controls: {
...defaultSpec.layout && defaultSpec.layout.controls,
top: o.layoutShowSequence ? undefined : 'none',
bottom: o.layoutShowLog ? undefined : 'none',
left: o.layoutShowLeftPanel ? undefined : 'none',
}
},
components: {
...defaultSpec.components,
remoteState: o.layoutShowRemoteState ? 'default' : 'none',
viewport: {
view: ViewportComponent
}
},
config: [
[PluginConfig.Viewport.ShowExpand, o.viewportShowExpand],
[PluginConfig.Viewport.ShowControls, o.viewportShowControls],
[PluginConfig.Viewport.ShowSettings, o.viewportShowSettings],
[PluginConfig.Viewport.ShowSelectionMode, o.viewportShowSelectionMode],
[PluginConfig.Viewport.ShowAnimation, o.viewportShowAnimation],
[PluginConfig.State.DefaultServer, o.pluginStateServer],
[PluginConfig.State.CurrentServer, o.pluginStateServer],
[PluginConfig.VolumeStreaming.DefaultServer, o.volumeStreamingServer],
[PluginConfig.Download.DefaultPdbProvider, o.pdbProvider],
[PluginConfig.Download.DefaultEmdbProvider, o.emdbProvider],
[ShowButtons, showButtons]
]
};
const element = typeof elementOrId === 'string'
? document.getElementById(elementOrId)
: elementOrId;
if (!element) throw new Error(`Could not get element with id '${elementOrId}'`);
this.plugin = createPlugin(element, spec);
(this.plugin.customState as any) = {
colorPalette: {
name: 'colors',
params: { list: { colors } }
}
};
this.plugin.behaviors.canvas3d.initialized.subscribe(v => {
if (v) {
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: {
renderer: {
...this.plugin.canvas3d!.props.renderer,
backgroundColor: ColorNames.white,
},
camera: {
...this.plugin.canvas3d!.props.camera,
helper: { axes: { name: 'off', params: {} } }
}
} });
}
});
}
async loadStructuresFromUrlsAndMerge(sources: { url: string, format: BuiltInTrajectoryFormat, isBinary?: boolean }[]) {
const structures: { ref: string }[] = [];
for (const { url, format, isBinary } of sources) {
const data = await this.plugin.builders.data.download({ url, isBinary });
const trajectory = await this.plugin.builders.structure.parseTrajectory(data, format);
const model = await this.plugin.builders.structure.createModel(trajectory);
const modelProperties = await this.plugin.builders.structure.insertModelProperties(model);
const structure = await this.plugin.builders.structure.createStructure(modelProperties || model);
const structureProperties = await this.plugin.builders.structure.insertStructureProperties(structure);
structures.push({ ref: structureProperties?.ref || structure.ref });
}
// remove current structuresfrom hierarchy as they will be merged
// TODO only works with using loadStructuresFromUrlsAndMerge once
// need some more API metho to work with the hierarchy
this.plugin.managers.structure.hierarchy.updateCurrent(this.plugin.managers.structure.hierarchy.current.structures, 'remove');
const dependsOn = structures.map(({ ref }) => ref);
const data = this.plugin.state.data.build().toRoot().apply(MergeStructures, { structures }, { dependsOn });
const structure = await data.commit();
const structureProperties = await this.plugin.builders.structure.insertStructureProperties(structure);
this.plugin.behaviors.canvas3d.initialized.subscribe(async v => {
await this.plugin.builders.structure.representation.applyPreset(structureProperties || structure, StructurePreset);
});
}
}
type MergeStructures = typeof MergeStructures
const MergeStructures = PluginStateTransform.BuiltIn({
name: 'merge-structures',
display: { name: 'Merge Structures', description: 'Merge Structure' },
from: PSO.Root,
to: PSO.Molecule.Structure,
params: {
structures: PD.ObjectList({
ref: PD.Text('')
}, ({ ref }) => ref, { isHidden: true })
}
})({
apply({ params, dependencies }) {
return Task.create('Merge Structures', async ctx => {
if (params.structures.length === 0) return StateObject.Null;
const first = dependencies![params.structures[0].ref].data as Structure;
const builder = Structure.Builder({ masterModel: first.models[0] });
for (const { ref } of params.structures) {
const s = dependencies![ref].data as Structure;
for (const unit of s.units) {
// TODO invariantId
builder.addUnit(unit.kind, unit.model, unit.conformation.operator, unit.elements, unit.traits);
}
}
const structure = builder.getStructure();
return new PSO.Molecule.Structure(structure, { label: 'Merged Structure' });
});
}
});
(window as any).DockingViewer = Viewer;
export { Viewer as DockingViewer };

View File

@@ -0,0 +1,276 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as React from 'react';
import { PluginUIComponent } from '../../mol-plugin-ui/base';
import { Viewport, ViewportControls } from '../../mol-plugin-ui/viewport';
import { BackgroundTaskProgress } from '../../mol-plugin-ui/task';
import { LociLabels } from '../../mol-plugin-ui/controls';
import { Toasts } from '../../mol-plugin-ui/toast';
import { Button } from '../../mol-plugin-ui/controls/common';
import { StructureRepresentationPresetProvider, presetStaticComponent } from '../../mol-plugin-state/builder/structure/representation-preset';
import { StateObjectRef } from '../../mol-state';
import { StructureSelectionQueries, StructureSelectionQuery } from '../../mol-plugin-state/helpers/structure-selection-query';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { InteractionsRepresentationProvider } from '../../mol-model-props/computed/representations/interactions';
import { InteractionTypeColorThemeProvider } from '../../mol-model-props/computed/themes/interaction-type';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginContext } from '../../mol-plugin/context';
import { StructureRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
import { Color } from '../../mol-util/color';
import { PluginConfig } from '../../mol-plugin/config';
function shinyStyle(plugin: PluginContext) {
return PluginCommands.Canvas3D.SetSettings(plugin, { settings: {
renderer: {
...plugin.canvas3d!.props.renderer,
style: { name: 'plastic', params: {} },
},
postprocessing: {
...plugin.canvas3d!.props.postprocessing,
occlusion: { name: 'off', params: {} },
outline: { name: 'off', params: {} }
}
} });
}
function occlusionStyle(plugin: PluginContext) {
return PluginCommands.Canvas3D.SetSettings(plugin, { settings: {
renderer: {
...plugin.canvas3d!.props.renderer,
style: { name: 'flat', params: {} }
},
postprocessing: {
...plugin.canvas3d!.props.postprocessing,
occlusion: { name: 'on', params: {
samples: 64,
radius: 8,
bias: 1.0,
blurKernelSize: 13
} },
outline: { name: 'on', params: {
scale: 1.0,
threshold: 0.33
} }
}
} });
}
const ligandPlusSurroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B) of Ligand plus Ligand itself', MS.struct.modifier.union([
MS.struct.modifier.includeSurroundings({
0: StructureSelectionQueries.ligand.expression,
radius: 5,
'as-whole-residues': true
})
]));
const ligandSurroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B) of Ligand', MS.struct.modifier.union([
MS.struct.modifier.exceptBy({
0: ligandPlusSurroundings.expression,
by: StructureSelectionQueries.ligand.expression
})
]));
const PresetParams = {
...StructureRepresentationPresetProvider.CommonParams,
};
export const StructurePreset = StructureRepresentationPresetProvider({
id: 'preset-structure',
display: { name: 'Structure' },
params: () => PresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
if (!structureCell) return {};
const components = {
ligand: await presetStaticComponent(plugin, structureCell, 'ligand'),
polymer: await presetStaticComponent(plugin, structureCell, 'polymer'),
};
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, sizeFactor: 0.35 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'cartoon', typeParams: { ...typeParams }, color: 'chain-id', colorParams: { palette: (plugin.customState as any).colorPalette } }, { tag: 'polymer' }),
};
await update.commit({ revertOnError: true });
await shinyStyle(plugin);
plugin.managers.interactivity.setProps({ granularity: 'residue' });
return { components, representations };
}
});
export const IllustrativePreset = StructureRepresentationPresetProvider({
id: 'preset-illustrative',
display: { name: 'Illustrative' },
params: () => PresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
if (!structureCell) return {};
const components = {
ligand: await presetStaticComponent(plugin, structureCell, 'ligand'),
polymer: await presetStaticComponent(plugin, structureCell, 'polymer'),
};
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'spacefill', typeParams: { ...typeParams }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'spacefill', typeParams: { ...typeParams }, color: 'illustrative', colorParams: { palette: (plugin.customState as any).colorPalette } }, { tag: 'polymer' }),
};
await update.commit({ revertOnError: true });
await occlusionStyle(plugin);
plugin.managers.interactivity.setProps({ granularity: 'residue' });
return { components, representations };
}
});
const SurfacePreset = StructureRepresentationPresetProvider({
id: 'preset-surface',
display: { name: 'Surface' },
params: () => PresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
const structure = structureCell?.obj?.data;
if (!structureCell || !structure) return {};
const components = {
ligand: await presetStaticComponent(plugin, structureCell, 'ligand'),
polymer: await presetStaticComponent(plugin, structureCell, 'polymer'),
};
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'molecular-surface', typeParams: { ...typeParams, quality: 'custom', resolution: 0.5, doubleSided: true }, color: 'partial-charge' }, { tag: 'polymer' }),
};
await update.commit({ revertOnError: true });
await shinyStyle(plugin);
plugin.managers.interactivity.setProps({ granularity: 'residue' });
return { components, representations };
}
});
const PocketPreset = StructureRepresentationPresetProvider({
id: 'preset-pocket',
display: { name: 'Pocket' },
params: () => PresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
const structure = structureCell?.obj?.data;
if (!structureCell || !structure) return {};
const components = {
ligand: await presetStaticComponent(plugin, structureCell, 'ligand'),
surroundings: await plugin.builders.structure.tryCreateComponentFromSelection(structureCell, ligandSurroundings, `surroundings`),
};
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
surroundings: builder.buildRepresentation(update, components.surroundings, { type: 'molecular-surface', typeParams: { ...typeParams, includeParent: true, quality: 'custom', resolution: 0.2, doubleSided: true }, color: 'partial-charge' }, { tag: 'surroundings' }),
};
await update.commit({ revertOnError: true });
await shinyStyle(plugin);
plugin.managers.interactivity.setProps({ granularity: 'element' });
return { components, representations };
}
});
const InteractionsPreset = StructureRepresentationPresetProvider({
id: 'preset-interactions',
display: { name: 'Interactions' },
params: () => PresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
const structure = structureCell?.obj?.data;
if (!structureCell || !structure) return {};
const components = {
ligand: await presetStaticComponent(plugin, structureCell, 'ligand'),
surroundings: await plugin.builders.structure.tryCreateComponentFromSelection(structureCell, ligandSurroundings, `surroundings`),
interactions: await plugin.builders.structure.tryCreateComponentFromSelection(structureCell, ligandPlusSurroundings, `interactions`)
};
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, sizeFactor: 0.3 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
ballAndStick: builder.buildRepresentation(update, components.surroundings, { type: 'ball-and-stick', typeParams: { ...typeParams, sizeFactor: 0.1, sizeAspectRatio: 1 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ball-and-stick' }),
interactions: builder.buildRepresentation(update, components.interactions, { type: InteractionsRepresentationProvider, typeParams: { ...typeParams }, color: InteractionTypeColorThemeProvider }, { tag: 'interactions' }),
label: builder.buildRepresentation(update, components.surroundings, { type: 'label', typeParams: { ...typeParams, background: false, borderWidth: 0.1 }, color: 'uniform', colorParams: { value: Color(0x000000) } }, { tag: 'label' }),
};
await update.commit({ revertOnError: true });
await shinyStyle(plugin);
plugin.managers.interactivity.setProps({ granularity: 'element' });
return { components, representations };
}
});
export const ShowButtons = PluginConfig.item('showButtons', true);
export class ViewportComponent extends PluginUIComponent {
async _set(structures: readonly StructureRef[], preset: StructureRepresentationPresetProvider) {
await this.plugin.managers.structure.component.clear(structures);
await this.plugin.managers.structure.component.applyPreset(structures, preset);
}
set = async (preset: StructureRepresentationPresetProvider) => {
await this._set(this.plugin.managers.structure.hierarchy.selection.structures, preset);
}
structurePreset = () => this.set(StructurePreset);
illustrativePreset = () => this.set(IllustrativePreset);
surfacePreset = () => this.set(SurfacePreset);
pocketPreset = () => this.set(PocketPreset);
interactionsPreset = () => this.set(InteractionsPreset);
get showButtons () {
return this.plugin.config.get(ShowButtons);
}
render() {
const VPControls = this.plugin.spec.components?.viewport?.controls || ViewportControls;
return <>
<Viewport />
{this.showButtons && <div className='msp-viewport-top-left-controls'>
<div style={{ marginBottom: '4px' }}>
<Button onClick={this.structurePreset} >Structure</Button>
</div>
<div style={{ marginBottom: '4px' }}>
<Button onClick={this.illustrativePreset}>Illustrative</Button>
</div>
<div style={{ marginBottom: '4px' }}>
<Button onClick={this.surfacePreset}>Surface</Button>
</div>
{/* <div style={{ marginBottom: '4px' }}>
<Button onClick={this.pocketPreset}>Pocket</Button>
</div> */}
<div style={{ marginBottom: '4px' }}>
<Button onClick={this.interactionsPreset}>Interactions</Button>
</div>
</div>}
<VPControls />
<BackgroundTaskProgress />
<div className='msp-highlight-toast-wrapper'>
<LociLabels />
<Toasts />
</div>
</>;
}
}

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" href="./favicon.ico" type="image/x-icon">
<title>Embedded Mol* Viewer</title>
<style>
#app {
position: absolute;
left: 100px;
top: 100px;
width: 800px;
height: 600px;
}
</style>
<link rel="stylesheet" type="text/css" href="molstar.css" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./molstar.js"></script>
<script type="text/javascript">
var viewer = new molstar.Viewer('app', {
layoutIsExpanded: false,
layoutShowControls: false,
layoutShowRemoteState: false,
layoutShowSequence: true,
layoutShowLog: false,
layoutShowLeftPanel: true,
viewportShowExpand: true,
viewportShowSelectionMode: false,
viewportShowAnimation: false,
pdbProvider: 'rcsb',
emdbProvider: 'rcsb',
});
viewer.loadPdb('7bv2');
viewer.loadEmdb('EMD-30210', { detail: 6 });
// viewer.loadAllModelsOrAssemblyFromUrl('https://cs.litemol.org/5ire/full', 'mmcif', false, { representationParams: { theme: { globalName: 'operator-name' } } })
</script>
</body>
</html>

View File

@@ -1,96 +0,0 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ThemeDataContext } from '../../../../mol-theme/theme'
import { ParamDefinition as PD } from '../../../../mol-util/param-definition'
import { Color } from '../../../../mol-util/color'
import { getPalette } from '../../../../mol-util/color/palette'
import { ColorTheme, LocationColor } from '../../../../mol-theme/color'
import { ScaleLegend, TableLegend } from '../../../../mol-util/legend'
import { StructureElement, Bond } from '../../../../mol-model/structure'
import { Location } from '../../../../mol-model/location';
import { CellPackInfoProvider } from './property'
import { distinctColors } from '../../../../mol-util/color/distinct'
import { Hcl } from '../../../../mol-util/color/spaces/hcl'
const DefaultColor = Color(0xCCCCCC)
const Description = 'Gives every model in a CellPack packing a unique color similar to other models in the packing.'
export const CellPackColorThemeParams = {}
export type CellPackColorThemeParams = typeof CellPackColorThemeParams
export function getCellPackColorThemeParams(ctx: ThemeDataContext) {
return CellPackColorThemeParams // TODO return copy
}
export function CellPackColorTheme(ctx: ThemeDataContext, props: PD.Values<CellPackColorThemeParams>): ColorTheme<CellPackColorThemeParams> {
let color: LocationColor
let legend: ScaleLegend | TableLegend | undefined
const info = ctx.structure && CellPackInfoProvider.get(ctx.structure).value
if (ctx.structure && info) {
const colors = distinctColors(info.packingsCount)
const hcl = Hcl.fromColor(Hcl(), colors[info.packingIndex])
const hue = [Math.max(0, hcl[0] - 35), Math.min(360, hcl[0] + 35)] as [number, number]
const { models } = ctx.structure.root
let size = 0;
for (const m of models) size = Math.max(size, m.trajectoryInfo.size);
const palette = getPalette(size, { palette: {
name: 'generate',
params: {
hue, chroma: [30, 80], luminance: [15, 85],
clusteringStepCount: 50, minSampleCount: 800, maxCount: 75,
minLabel: 'Min', maxLabel: 'Max', valueLabel: (i: number) => `${i + 1}`,
}
}})
legend = palette.legend
const modelColor = new Map<number, Color>()
for (let i = 0, il = models.length; i <il; ++i) {
const idx = models[i].trajectoryInfo.index;
modelColor.set(models[i].trajectoryInfo.index, palette.color(idx))
}
color = (location: Location): Color => {
if (StructureElement.Location.is(location)) {
return modelColor.get(location.unit.model.trajectoryInfo.index)!
} else if (Bond.isLocation(location)) {
return modelColor.get(location.aUnit.model.trajectoryInfo.index)!
}
return DefaultColor
}
} else {
color = () => DefaultColor
}
return {
factory: CellPackColorTheme,
granularity: 'instance',
color,
props,
description: Description,
legend
}
}
export const CellPackColorThemeProvider: ColorTheme.Provider<CellPackColorThemeParams, 'cellpack'> = {
name: 'cellpack',
label: 'CellPack',
category: ColorTheme.Category.Chain,
factory: CellPackColorTheme,
getParams: getCellPackColorThemeParams,
defaultValues: PD.getDefaultValues(CellPackColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => {
return (
!!ctx.structure && ctx.structure.elementCount > 0 &&
ctx.structure.models[0].trajectoryInfo.size > 1 &&
!!CellPackInfoProvider.get(ctx.structure).value
)
}
}

View File

@@ -1,228 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Ludovic Autin <autin@scripps.edu>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3, Quat, Mat4 } from '../../../../mol-math/linear-algebra';
import { NumberArray } from '../../../../mol-util/type-helpers';
interface Frame {
t: Vec3,
r: Vec3,
s: Vec3,
}
const a0Tmp = Vec3()
const a1Tmp = Vec3()
const a2Tmp = Vec3()
const a3Tmp = Vec3()
function CubicInterpolate(out: Vec3, y0: Vec3, y1: Vec3, y2: Vec3, y3: Vec3, mu: number): Vec3 {
const mu2 = mu * mu;
Vec3.sub(a0Tmp, y3, y2)
Vec3.sub(a0Tmp, a0Tmp, y0)
Vec3.add(a0Tmp, a0Tmp, y1)
Vec3.sub(a1Tmp, y0, y1)
Vec3.sub(a1Tmp, a1Tmp, a0Tmp)
Vec3.sub(a2Tmp, y2, y0)
Vec3.copy(a3Tmp, y1)
out[0] = a0Tmp[0] * mu * mu2 + a1Tmp[0] * mu2 + a2Tmp[0] * mu + a3Tmp[0]
out[1] = a0Tmp[1] * mu * mu2 + a1Tmp[1] * mu2 + a2Tmp[1] * mu + a3Tmp[1]
out[2] = a0Tmp[2] * mu * mu2 + a1Tmp[2] * mu2 + a2Tmp[2] * mu + a3Tmp[2]
return out
}
const cp0 = Vec3()
const cp1 = Vec3()
const cp2 = Vec3()
const cp3 = Vec3()
const currentPosition = Vec3()
function ResampleControlPoints(points: NumberArray, segmentLength: number) {
const nP = points.length / 3
// insert a point at the end and at the begining
// controlPoints.Insert(0, controlPoints[0] + (controlPoints[0] - controlPoints[1]) / 2.0f);
// controlPoints.Add(controlPoints[nP - 1] + (controlPoints[nP - 1] - controlPoints[nP - 2]) / 2.0f);
let resampledControlPoints: Vec3[] = []
// resampledControlPoints.Add(controlPoints[0]);
// resampledControlPoints.Add(controlPoints[1]);
let idx = 1
// const currentPosition = Vec3.create(points[idx * 3], points[idx * 3 + 1], points[idx * 3 + 2])
Vec3.fromArray(currentPosition, points, idx * 3)
let lerpValue = 0.0
// Normalize the distance between control points
while (true) {
if (idx + 2 >= nP) break
Vec3.fromArray(cp0, points, (idx - 1) * 3)
Vec3.fromArray(cp1, points, idx * 3)
Vec3.fromArray(cp2, points, (idx + 1) * 3)
Vec3.fromArray(cp3, points, (idx + 2) * 3)
// const cp0 = Vec3.create(points[(idx-1)*3], points[(idx-1)*3+1], points[(idx-1)*3+2]) // controlPoints[currentPointId - 1];
// const cp1 = Vec3.create(points[idx*3], points[idx*3+1], points[idx*3+2]) // controlPoints[currentPointId];
// const cp2 = Vec3.create(points[(idx+1)*3], points[(idx+1)*3+1], points[(idx+1)*3+2]) // controlPoints[currentPointId + 1];
// const cp3 = Vec3.create(points[(idx+2)*3], points[(idx+2)*3+1], points[(idx+2)*3+2]); // controlPoints[currentPointId + 2];
let found = false
for (; lerpValue <= 1; lerpValue += 0.01) {
// lerp?slerp
// let candidate:Vec3 = Vec3.lerp(Vec3.zero(), cp0, cp1, lerpValue);
// const candidate:Vec3 = Vec3.bezier(Vec3.zero(), cp0, cp1, cp2, cp3, lerpValue);
const candidate = CubicInterpolate(Vec3(), cp0, cp1, cp2, cp3, lerpValue)
const d = Vec3.distance(currentPosition, candidate);
if (d > segmentLength) {
resampledControlPoints.push(candidate)
Vec3.copy(currentPosition, candidate)
found = true
break
}
}
if (!found) {
lerpValue = 0
idx += 1
}
}
return resampledControlPoints
}
const prevV = Vec3()
const tmpV1 = Vec3()
const tmpV2 = Vec3()
const tmpV3 = Vec3()
// easier to align to theses normals
function GetSmoothNormals(points: Vec3[]) {
const nP: number = points.length;
const smoothNormals: Vec3[] = []
if (points.length < 3) {
for (let i = 0; i < points.length; ++i)
smoothNormals.push(Vec3.normalize(Vec3(), points[i]))
return smoothNormals;
}
let p0 = points[0]
let p1 = points[1]
let p2 = points[2]
const p21 = Vec3.sub(tmpV1, p2, p1)
const p01 = Vec3.sub(tmpV2, p0, p1)
const p0121 = Vec3.cross(tmpV3, p01, p21)
Vec3.normalize(prevV, p0121)
smoothNormals.push(Vec3.clone(prevV))
for (let i = 1; i < points.length - 1; ++i) {
p0 = points[i - 1]
p1 = points[i]
p2 = points[i + 1]
const t = Vec3.normalize(tmpV1, Vec3.sub(tmpV1, p2 , p0))
const b = Vec3.normalize(tmpV2, Vec3.cross(tmpV2, t, prevV))
const n = Vec3.normalize(Vec3(), Vec3.cross(tmpV3, t, b))
Vec3.negate(n, n)
Vec3.copy(prevV, n)
smoothNormals.push(n)
}
const last = Vec3()
Vec3.normalize(last, Vec3.cross(last,
Vec3.sub(tmpV1, points[nP - 3], points[nP-2]),
Vec3.sub(tmpV2, points[nP-2] , points[nP-1]))
)
smoothNormals.push(last)
return smoothNormals;
}
const frameTmpV1 = Vec3()
const frameTmpV2 = Vec3()
const frameTmpV3 = Vec3()
function getFrame(reference: Vec3, tangent: Vec3) {
const t = Vec3.normalize(Vec3(), tangent);
// make reference vector orthogonal to tangent
const proj_r_to_t = Vec3.scale(
frameTmpV1, tangent, Vec3.dot(reference, tangent) / Vec3.dot(tangent, tangent)
)
const r = Vec3.normalize(Vec3(), Vec3.sub(frameTmpV2, reference, proj_r_to_t))
// make bitangent vector orthogonal to the others
const s = Vec3.normalize(Vec3(), Vec3.cross(frameTmpV3, t, r))
return { t, r, s }
}
const mfTmpV1 = Vec3()
const mfTmpV2 = Vec3()
const mfTmpV3 = Vec3()
const mfTmpV4 = Vec3()
const mfTmpV5 = Vec3()
const mfTmpV6 = Vec3()
const mfTmpV7 = Vec3()
const mfTmpV8 = Vec3()
const mfTmpV9 = Vec3()
// easier to align to theses normals
// https://github.com/bzamecnik/gpg/blob/master/rotation-minimizing-frame/rmf.py
function GetMiniFrame(points: Vec3[], normals: Vec3[]) {
const frames: Frame[] = [];
const t0 = Vec3.normalize(mfTmpV1, Vec3.sub(mfTmpV1, points[1], points[0]))
frames.push(getFrame(normals[0], t0))
for (let i = 0; i< points.length-2; ++i) {
const t2 = Vec3.normalize(mfTmpV1, Vec3.sub(mfTmpV1, points[i+2], points[i+1]))
const v1 = Vec3.sub(mfTmpV2, points[i + 1], points[i]) // this is tangeant
const c1 = Vec3.dot(v1, v1)
// compute r_i^L = R_1 * r_i
const v1r = Vec3.scale(mfTmpV3, v1, (2.0 / c1) * Vec3.dot(v1, frames[i].r))
const ref_L_i = Vec3.sub(mfTmpV4, frames[i].r, v1r)
// compute t_i^L = R_1 * t_i
const v1t = Vec3.scale(mfTmpV5, v1, (2.0 / c1) * Vec3.dot(v1, frames[i].t))
const tan_L_i = Vec3.sub(mfTmpV6, frames[i].t, v1t)
// # compute reflection vector of R_2
const v2 = Vec3.sub(mfTmpV7, t2 , tan_L_i)
const c2 = Vec3.dot(v2, v2)
// compute r_(i+1) = R_2 * r_i^L
const v2l = Vec3.scale(mfTmpV8, v1, (2.0/c2) * Vec3.dot(v2, ref_L_i))
const ref_next = Vec3.sub(mfTmpV9, ref_L_i, v2l) // ref_L_i - (2 / c2) * v2.dot(ref_L_i) * v2
frames.push(getFrame(ref_next, t2)) // frames.append(Frame(ref_next, tangents[i+1]))
}
return frames;
}
const rpTmpVec1 = Vec3()
export function getMatFromResamplePoints(points: NumberArray) {
const segmentLength = 3.4
const new_points = ResampleControlPoints(points, 3.4)
const npoints = new_points.length
const new_normal = GetSmoothNormals(new_points)
const frames = GetMiniFrame(new_points, new_normal)
const limit = npoints
const transforms: Mat4[] = []
const pti = Vec3.copy(rpTmpVec1, new_points[0]);
// console.log(new_points.length)
// console.log(points.length/3)
// console.log(limit)
// console.log(segmentLength)
for (let i = 0; i<npoints-2; ++i) {
const pti1: Vec3 = new_points[i+1] // Vec3.create(points[(i+1)*3],points[(i+1)*3+1],points[(i+1)*3+2]);
const d = Vec3.distance(pti, pti1)
if (d >= segmentLength) {
// use twist or random?
const quat = Quat.rotationTo(Quat.zero(), Vec3.create(0, 0, 1), frames[i].t) // Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),new_normal[i]);//Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),direction);new_normal
const rq = Quat.setAxisAngle(Quat.zero(), frames[i].t, Math.random()*3.60 ) // Quat.setAxisAngle(Quat.zero(),direction, Math.random()*3.60 );//Quat.identity();//
const m = Mat4.fromQuat(Mat4.zero(), Quat.multiply(Quat.zero(), rq, quat)) // Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),quat1,quat2));//Mat4.fromQuat(Mat4.zero(),quat);//Mat4.identity();//Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),rq,quat));
// let pos:Vec3 = Vec3.add(Vec3.zero(),pti1,pti)
// pos = Vec3.scale(pos,pos,1.0/2.0);
// Vec3.makeRotation(Mat4.zero(),Vec3.create(0,0,1),frames[i].t);//
Mat4.setTranslation(m, pti1)
// let m2:Mat4 = GetTubePropertiesMatrix(pti,pti1);
// let q:Quat = Quat.rotationTo(Quat.zero(), Vec3.create(0,1,0),Vec3.create(0,0,1))
// m2=Mat4.mul(Mat4.identity(),Mat4.fromQuat(Mat4.zero(),q),m2);
transforms.push(m)
Vec3.copy(pti, pti1)
}
if (transforms.length >= limit) break
}
return transforms
}

View File

@@ -1,62 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3, Quat } from '../../../../mol-math/linear-algebra';
export interface CellPack {
cell: Cell
packings: CellPacking[]
}
export interface CellPacking {
name: string,
location: 'surface' | 'interior' | 'cytoplasme',
ingredients: Packing['ingredients']
}
//
export interface Cell {
recipe: Recipe
cytoplasme?: Packing
compartments?: { [key: string]: Compartment }
}
export interface Recipe {
setupfile: string
/** First entry is name, secound is path: [name: string, path: string][] */
paths: [string, string][]
version: string
name: string
}
export interface Compartment {
surface?: Packing
interior?: Packing
}
export interface Packing {
ingredients: { [key: string]: Ingredient }
}
export interface Ingredient {
source: IngredientSource
results: [Vec3, Quat][]
name: string
positions?: [Vec3[]] // why wrapped in an extra array?
radii?: [number[]] // why wrapped in an extra array?
/** Number of `curveX` properties in the object where `X` is a 0-indexed number */
nbCurve?: number
/** Curve properties are Vec3[] but that is not expressable in TypeScript */
[curveX: string]: unknown
}
export interface IngredientSource {
pdb: string
transform: { center: boolean, translate?: Vec3 }
biomt?: boolean
}

View File

@@ -1,402 +0,0 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { StateAction, StateBuilder, StateTransformer, State } from '../../../../mol-state';
import { PluginContext } from '../../../../mol-plugin/context';
import { PluginStateObject as PSO } from '../../../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { Ingredient, CellPacking } from './data';
import { getFromPdb, getFromCellPackDB } from './util';
import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit } from '../../../../mol-model/structure';
import { trajectoryFromMmCIF, MmcifFormat } from '../../../../mol-model-formats/structure/mmcif';
import { trajectoryFromPDB } from '../../../../mol-model-formats/structure/pdb';
import { Mat4, Vec3, Quat } from '../../../../mol-math/linear-algebra';
import { SymmetryOperator } from '../../../../mol-math/geometry';
import { Task, RuntimeContext } from '../../../../mol-task';
import { StateTransforms } from '../../../../mol-plugin-state/transforms';
import { ParseCellPack, StructureFromCellpack, DefaultCellPackBaseUrl } from './state';
import { MolScriptBuilder as MS } from '../../../../mol-script/language/builder';
import { getMatFromResamplePoints } from './curve';
import { compile } from '../../../../mol-script/runtime/query/compiler';
import { CifCategory, CifField } from '../../../../mol-io/reader/cif';
import { mmCIF_Schema } from '../../../../mol-io/reader/cif/schema/mmcif';
import { Column } from '../../../../mol-data/db';
import { createModels } from '../../../../mol-model-formats/structure/basic/parser';
import { CellpackPackingPreset, CellpackMembranePreset } from './preset';
import { AjaxTask } from '../../../../mol-util/data-source';
import { CellPackInfoProvider } from './property';
import { CellPackColorThemeProvider } from './color';
function getCellPackModelUrl(fileName: string, baseUrl: string) {
return `${baseUrl}/results/${fileName}`
}
async function getModel(id: string, baseUrl: string) {
let model: Model;
if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
// return
const cif = await getFromPdb(id)
model = (await trajectoryFromMmCIF(cif).run())[0]
} else {
const pdb = await getFromCellPackDB(id, baseUrl)
model = (await trajectoryFromPDB(pdb).run())[0]
}
return model
}
async function getStructure(model: Model, props: { assembly?: string } = {}) {
let structure = Structure.ofModel(model)
const { assembly } = props
if (assembly) {
structure = await StructureSymmetry.buildAssembly(structure, assembly).run()
}
const query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
})
])
const compiled = compile<StructureSelection>(query)
const result = compiled(new QueryContext(structure))
structure = StructureSelection.unionStructure(result)
return structure
}
function getTransform(trans: Vec3, rot: Quat) {
const q: Quat = Quat.create(-rot[3], rot[0], rot[1], rot[2])
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q)
Mat4.transpose(m, m)
Mat4.scale(m, m, Vec3.create(-1.0, 1.0, -1.0))
Mat4.setTranslation(m, trans)
return m
}
function getResultTransforms(results: Ingredient['results']) {
return results.map((r: Ingredient['results'][0]) => getTransform(r[0], r[1]))
}
function getCurveTransforms(ingredient: Ingredient) {
const n = ingredient.nbCurve || 0
const instances: Mat4[] = []
for (let i = 0; i < n; ++i) {
const cname = `curve${i}`
if (!(cname in ingredient)) {
// console.warn(`Expected '${cname}' in ingredient`)
continue
}
const _points = ingredient[cname] as Vec3[]
if (_points.length <= 2) {
// TODO handle curve with 2 or less points
continue
}
const points = new Float32Array(_points.length * 3)
for (let i = 0, il = _points.length; i < il; ++i) Vec3.toArray(_points[i], points, i * 3)
const newInstances = getMatFromResamplePoints(points)
instances.push(...newInstances)
}
return instances
}
function getAssembly(transforms: Mat4[], structure: Structure) {
const builder = Structure.Builder()
const { units } = structure;
for (let i = 0, il = transforms.length; i < il; ++i) {
const id = `${i + 1}`
const op = SymmetryOperator.create(id, transforms[i], { assembly: { id, operId: i, operList: [ id ] } })
for (const unit of units) {
builder.addWithOperator(unit, op)
}
}
return builder.getStructure();
}
function getCifCurve(name: string, transforms: Mat4[], model: Model) {
if (!MmcifFormat.is(model.sourceData)) throw new Error('mmcif source data needed')
const { db } = model.sourceData.data
const d = db.atom_site
const n = d._rowCount
const rowCount = n * transforms.length
const { offsets, count } = model.atomicHierarchy.chainAtomSegments
const x = d.Cartn_x.toArray()
const y = d.Cartn_y.toArray()
const z = d.Cartn_z.toArray()
const Cartn_x = new Float32Array(rowCount)
const Cartn_y = new Float32Array(rowCount)
const Cartn_z = new Float32Array(rowCount)
const map = new Uint32Array(rowCount)
const seq = new Int32Array(rowCount)
let offset = 0
for (let c = 0; c < count; ++c) {
const cStart = offsets[c]
const cEnd = offsets[c + 1]
const cLength = cEnd - cStart
for (let t = 0, tl = transforms.length; t < tl; ++t) {
const m = transforms[t]
for (let j = cStart; j < cEnd; ++j) {
const i = offset + j - cStart
const xj = x[j], yj = y[j], zj = z[j]
Cartn_x[i] = m[0] * xj + m[4] * yj + m[8] * zj + m[12]
Cartn_y[i] = m[1] * xj + m[5] * yj + m[9] * zj + m[13]
Cartn_z[i] = m[2] * xj + m[6] * yj + m[10] * zj + m[14]
map[i] = j
seq[i] = t + 1
}
offset += cLength
}
}
function multColumn<T>(column: Column<T>) {
const array = column.toArray()
return Column.ofLambda({
value: row => array[map[row]],
areValuesEqual: (rowA, rowB) => map[rowA] === map[rowB] || array[map[rowA]] === array[map[rowB]],
rowCount, schema: column.schema
})
}
const _atom_site: CifCategory.SomeFields<mmCIF_Schema['atom_site']> = {
auth_asym_id: CifField.ofColumn(multColumn(d.auth_asym_id)),
auth_atom_id: CifField.ofColumn(multColumn(d.auth_atom_id)),
auth_comp_id: CifField.ofColumn(multColumn(d.auth_comp_id)),
auth_seq_id: CifField.ofNumbers(seq),
B_iso_or_equiv: CifField.ofColumn(Column.ofConst(0, rowCount, Column.Schema.float)),
Cartn_x: CifField.ofNumbers(Cartn_x),
Cartn_y: CifField.ofNumbers(Cartn_y),
Cartn_z: CifField.ofNumbers(Cartn_z),
group_PDB: CifField.ofColumn(Column.ofConst('ATOM', rowCount, Column.Schema.str)),
id: CifField.ofColumn(Column.ofLambda({
value: row => row,
areValuesEqual: (rowA, rowB) => rowA === rowB,
rowCount, schema: d.id.schema,
})),
label_alt_id: CifField.ofColumn(multColumn(d.label_alt_id)),
label_asym_id: CifField.ofColumn(multColumn(d.label_asym_id)),
label_atom_id: CifField.ofColumn(multColumn(d.label_atom_id)),
label_comp_id: CifField.ofColumn(multColumn(d.label_comp_id)),
label_seq_id: CifField.ofNumbers(seq),
label_entity_id: CifField.ofColumn(Column.ofConst('1', rowCount, Column.Schema.str)),
occupancy: CifField.ofColumn(Column.ofConst(1, rowCount, Column.Schema.float)),
type_symbol: CifField.ofColumn(multColumn(d.type_symbol)),
pdbx_PDB_ins_code: CifField.ofColumn(Column.ofConst('', rowCount, Column.Schema.str)),
pdbx_PDB_model_num: CifField.ofColumn(Column.ofConst(1, rowCount, Column.Schema.int)),
}
const categories = {
entity: CifCategory.ofTable('entity', db.entity),
chem_comp: CifCategory.ofTable('chem_comp', db.chem_comp),
atom_site: CifCategory.ofFields('atom_site', _atom_site)
}
return {
header: name,
categoryNames: Object.keys(categories),
categories
};
}
async function getCurve(name: string, transforms: Mat4[], model: Model) {
const cif = getCifCurve(name, transforms, model)
const curveModelTask = Task.create('Curve Model', async ctx => {
const format = MmcifFormat.fromFrame(cif)
const models = await createModels(format.data.db, format, ctx)
return models[0]
})
const curveModel = await curveModelTask.run()
return getStructure(curveModel)
}
async function getIngredientStructure(ingredient: Ingredient, baseUrl: string) {
const { name, source, results, nbCurve } = ingredient
// TODO can these be added to the library?
if (name === 'HIV1_CAhex_0_1_0') return
if (name === 'HIV1_CAhexCyclophilA_0_1_0') return
if (name === 'iLDL') return
if (name === 'peptides') return
if (name === 'lypoglycane') return
if (source.pdb === 'None') return
const model = await getModel(source.pdb || name, baseUrl)
if (!model) return
if (nbCurve) {
return getCurve(name, getCurveTransforms(ingredient), model)
} else {
const structure = await getStructure(model, { assembly: source.biomt ? '1' : undefined })
return getAssembly(getResultTransforms(results), structure)
}
}
export function createStructureFromCellPack(packing: CellPacking, baseUrl: string) {
return Task.create('Create Packing Structure', async ctx => {
const { ingredients, name } = packing
const structures: Structure[] = []
for (const iName in ingredients) {
if (ctx.shouldUpdate) await ctx.update(iName)
const s = await getIngredientStructure(ingredients[iName], baseUrl)
if (s) structures.push(s)
}
if (ctx.shouldUpdate) await ctx.update(`${name} - units`)
const builder = Structure.Builder({ label: name })
let offsetInvariantId = 0
for (const s of structures) {
if (ctx.shouldUpdate) await ctx.update(`${s.label}`)
let maxInvariantId = 0
for (const u of s.units) {
const invariantId = u.invariantId + offsetInvariantId
if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId
builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, Unit.Trait.None, invariantId)
}
offsetInvariantId += maxInvariantId + 1
}
if (ctx.shouldUpdate) await ctx.update(`${name} - structure`)
const s = builder.getStructure()
for( let i = 0, il = s.models.length; i < il; ++i) {
const { trajectoryInfo } = s.models[i]
trajectoryInfo.size = il
trajectoryInfo.index = i
}
return s
})
}
async function handleHivRna(ctx: { runtime: RuntimeContext, fetch: AjaxTask }, packings: CellPacking[], baseUrl: string) {
for (let i = 0, il = packings.length; i < il; ++i) {
if (packings[i].name === 'HIV1_capsid_3j3q_PackInner_0_1_0') {
const url = `${baseUrl}/extras/rna_allpoints.json`
const data = await ctx.fetch({ url, type: 'string' }).runInContext(ctx.runtime);
const { points } = await (new Response(data)).json() as { points: number[] }
const curve0: Vec3[] = []
for (let j = 0, jl = points.length; j < jl; j += 3) {
curve0.push(Vec3.fromArray(Vec3(), points, j))
}
packings[i].ingredients['RNA'] = {
source: { pdb: 'RNA_U_Base.pdb', transform: { center: false } },
results: [],
name: 'RNA',
nbCurve: 1,
curve0
}
}
}
}
async function loadHivMembrane(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) {
const url = `${params.baseUrl}/membranes/hiv_lipids.bcif`
const membraneBuilder = state.build().toRoot()
.apply(StateTransforms.Data.Download, { label: 'hiv_lipids', url, isBinary: true }, { state: { isGhost: true } })
.apply(StateTransforms.Data.ParseCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.TrajectoryFromMmCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.ModelFromTrajectory, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.StructureFromModel)
await state.updateTree(membraneBuilder).runInContext(runtime)
const membraneParams = {
representation: params.preset.representation,
}
const membrane = state.build().to(membraneBuilder.ref)
await plugin.updateDataState(membrane, { revertOnError: true });
await CellpackMembranePreset.apply(membrane.selector, membraneParams, plugin)
}
async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) {
let cellPackJson: StateBuilder.To<PSO.Format.Json, StateTransformer<PSO.Data.String, PSO.Format.Json>>
if (params.source.name === 'id') {
const url = getCellPackModelUrl(params.source.params, params.baseUrl)
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.source.params }, { state: { isGhost: true } })
} else {
const file = params.source.params
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.ReadFile, { file, isBinary: false, label: file.name }, { state: { isGhost: true } })
}
const cellPackBuilder = cellPackJson
.apply(StateTransforms.Data.ParseJson, undefined, { state: { isGhost: true } })
.apply(ParseCellPack)
const cellPackObject = await state.updateTree(cellPackBuilder).runInContext(runtime)
const { packings } = cellPackObject.data
await handleHivRna({ runtime, fetch: plugin.fetch }, packings, params.baseUrl)
for (let i = 0, il = packings.length; i < il; ++i) {
const p = { packing: i, baseUrl: params.baseUrl }
const packing = state.build().to(cellPackBuilder.ref).apply(StructureFromCellpack, p)
await plugin.updateDataState(packing, { revertOnError: true });
const structure = packing.selector.obj?.data
if (structure) {
await CellPackInfoProvider.attach({ fetch: plugin.fetch, runtime }, structure, {
info: { packingsCount: packings.length, packingIndex: i }
})
}
const packingParams = {
traceOnly: params.preset.traceOnly,
representation: params.preset.representation,
}
await CellpackPackingPreset.apply(packing.selector, packingParams, plugin)
}
}
const LoadCellPackModelParams = {
source: PD.MappedStatic('id', {
'id': PD.Select('influenza_model1.json', [
['blood_hiv_immature_inside.json', 'blood_hiv_immature_inside'],
['BloodHIV1.0_mixed_fixed_nc1.cpr', 'BloodHIV1.0_mixed_fixed_nc1'],
['HIV-1_0.1.6-8_mixed_radii_pdb.cpr', 'HIV-1_0.1.6-8_mixed_radii_pdb'],
['hiv_lipids.bcif', 'hiv_lipids'],
['influenza_model1.json', 'influenza_model1'],
['Mycoplasma1.5_mixed_pdb_fixed.cpr', 'Mycoplasma1.5_mixed_pdb_fixed'],
] as const),
'file': PD.File({ accept: 'id' }),
}, { options: [['id', 'Id'], ['file', 'File']] }),
baseUrl: PD.Text(DefaultCellPackBaseUrl),
preset: PD.Group({
traceOnly: PD.Boolean(false),
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'ellipsoid']))
}, { isExpanded: true })
}
type LoadCellPackModelParams = PD.Values<typeof LoadCellPackModelParams>
export const LoadCellPackModel = StateAction.build({
display: { name: 'Load CellPack', description: 'Open or download a model' },
params: LoadCellPackModelParams,
from: PSO.Root
})(({ state, params }, ctx: PluginContext) => Task.create('CellPack Loader', async taskCtx => {
if (!ctx.representation.structure.themes.colorThemeRegistry.has(CellPackColorThemeProvider)) {
ctx.representation.structure.themes.colorThemeRegistry.add(CellPackColorThemeProvider)
}
if (params.source.name === 'id' && params.source.params === 'hiv_lipids.bcif') {
await loadHivMembrane(ctx, taskCtx, state, params)
} else {
await loadPackings(ctx, taskCtx, state, params)
}
}));

View File

@@ -1,73 +0,0 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { PluginStateObject as PSO, PluginStateTransform } from '../../../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { Task } from '../../../../mol-task';
import { CellPack as _CellPack, Cell, CellPacking } from './data';
import { createStructureFromCellPack } from './model';
export const DefaultCellPackBaseUrl = 'https://mesoscope.scripps.edu/data/cellPACK_data/cellPACK_database_1.1.0/'
export class CellPack extends PSO.Create<_CellPack>({ name: 'CellPack', typeClass: 'Object' }) { }
export { ParseCellPack }
type ParseCellPack = typeof ParseCellPack
const ParseCellPack = PluginStateTransform.BuiltIn({
name: 'parse-cellpack',
display: { name: 'Parse CellPack', description: 'Parse CellPack from JSON data' },
from: PSO.Format.Json,
to: CellPack
})({
apply({ a }) {
return Task.create('Parse CellPack', async ctx => {
const cell = a.data as Cell
const packings: CellPacking[] = []
const { compartments, cytoplasme } = cell
if (compartments) {
for (const name in compartments) {
const { surface, interior } = compartments[name]
if (surface) packings.push({ name, location: 'surface', ingredients: surface.ingredients })
if (interior) packings.push({ name, location: 'interior', ingredients: interior.ingredients })
}
}
if (cytoplasme) packings.push({ name: 'Cytoplasme', location: 'cytoplasme', ingredients: cytoplasme.ingredients })
return new CellPack({ cell, packings });
});
}
});
export { StructureFromCellpack }
type StructureFromCellpack = typeof ParseCellPack
const StructureFromCellpack = PluginStateTransform.BuiltIn({
name: 'structure-from-cellpack',
display: { name: 'Structure from CellPack', description: 'Create Structure from CellPack Packing' },
from: CellPack,
to: PSO.Molecule.Structure,
params: a => {
if (!a) {
return {
packing: PD.Numeric(0, {}, { description: 'Packing Index' }),
baseUrl: PD.Text(DefaultCellPackBaseUrl)
};
}
const options = a.data.packings.map((d, i) => [i, d.name] as [number, string])
return {
packing: PD.Select(0, options),
baseUrl: PD.Text(DefaultCellPackBaseUrl)
}
}
})({
apply({ a, params }) {
return Task.create('Structure from CellPack', async ctx => {
const packing = a.data.packings[params.packing]
const structure = await createStructureFromCellPack(packing, params.baseUrl).runInContext(ctx)
return new PSO.Molecule.Structure(structure, { label: packing.name })
});
}
});

View File

@@ -1,48 +0,0 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { CIF } from '../../../../mol-io/reader/cif'
import { parsePDB } from '../../../../mol-io/reader/pdb/parser';
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 parsePDBfile(data: string, id: string) {
const comp = parsePDB(data, id);
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 downloadPDB(url: string, id: string) {
const data = await fetch(url);
return parsePDBfile(await data.text(), id);
}
export async function getFromPdb(id: string) {
const parsed = await downloadCif(`https://files.rcsb.org/download/${id}.cif`, false);
return parsed.blocks[0];
}
function getCellPackDataUrl(id: string, baseUrl: string) {
const url = `${baseUrl}/other/${id}`
return url.endsWith('.pdb') ? url : `${url}.pdb`
}
export async function getFromCellPackDB(id: string, baseUrl: string) {
const name = id.endsWith('.pdb') ? id.substring(0, id.length - 4) : id
const parsed = await downloadPDB(getCellPackDataUrl(id, baseUrl), name);
return parsed;
}

View File

@@ -1,168 +0,0 @@
// /**
// * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
// *
// * @author David Sehnal <david.sehnal@gmail.com>
// */
// import { StateTree, StateBuilder, StateAction, State } from '../../../mol-state';
// import { StateTransforms } from '../../../mol-plugin/state/transforms';
// import { createModelTree } from '../../../mol-plugin/state/actions/structure';
// import { PluginContext } from '../../../mol-plugin/context';
// import { PluginStateObject } from '../../../mol-plugin/state/objects';
// import { ParamDefinition } from '../../../mol-util/param-definition';
// import { PluginCommands } from '../../../mol-plugin/command';
// import { Vec3 } from '../../../mol-math/linear-algebra';
// import { PluginStateSnapshotManager } from '../../../mol-plugin/state/snapshots';
// import { MolScriptBuilder as MS } from '../../../mol-script/language/builder';
// import { Text } from '../../../mol-geo/geometry/text/text';
// import { UUID } from '../../../mol-util';
// import { ColorNames } from '../../../mol-util/color/names';
// import { Camera } from '../../../mol-canvas3d/camera';
// import { createStructureRepresentation3dParamss } from '../../../mol-plugin/state/transforms/representation';
// import { createDefaultStructureComplex } from '../../../mol-plugin/util/structure-complex-helper';
// export const CreateJoleculeState = StateAction.build({
// display: { name: 'Jolecule State Import' },
// params: { id: ParamDefinition.Text('1mbo') },
// from: PluginStateObject.Root
// })(async ({ ref, state, params }, plugin: PluginContext) => {
// try {
// const id = params.id.trim().toLowerCase();
// const data = await plugin.runTask(plugin.fetch({ url: `https://jolecule.appspot.com/pdb/${id}.views.json`, type: 'json' })) as JoleculeSnapshot[];
// data.sort((a, b) => a.order - b.order);
// await PluginCommands.State.RemoveObject.dispatch(plugin, { state, ref });
// plugin.state.snapshots.clear();
// const template = createTemplate(plugin, state, id);
// const snapshots = data.map((e, idx) => buildSnapshot(plugin, template, { e, idx, len: data.length }));
// for (const s of snapshots) {
// plugin.state.snapshots.add(s);
// }
// PluginCommands.State.Snapshots.Apply.dispatch(plugin, { id: snapshots[0].snapshot.id });
// } catch (e) {
// plugin.log.error(`Jolecule Failed: ${e}`);
// }
// });
// interface JoleculeSnapshot {
// order: number,
// distances: { i_atom1: number, i_atom2: number }[],
// labels: { i_atom: number, text: string }[],
// camera: { up: Vec3, pos: Vec3, in: Vec3, slab: { z_front: number, z_back: number, zoom: number } },
// selected: number[],
// text: string
// }
// function createTemplate(plugin: PluginContext, state: State, id: string) {
// const b = new StateBuilder.Root(state.tree);
// const data = b.toRoot().apply(StateTransforms.Data.Download, { url: `https://www.ebi.ac.uk/pdbe/static/entry/${id}_updated.cif` }, { state: { isGhost: true }});
// const model = createModelTree(data, 'cif');
// const structure = model.apply(StateTransforms.Model.StructureFromModel);
// createDefaultStructureComplex(plugin, structure);
// return { tree: b.getTree(), structure: structure.ref };
// }
// const labelOptions: ParamDefinition.Values<Text.Params> = {
// ...ParamDefinition.getDefaultValues(Text.Params),
// tether: true,
// sizeFactor: 1.3,
// attachment: 'bottom-right',
// offsetZ: 10,
// background: true,
// backgroundMargin: 0.2,
// backgroundColor: ColorNames.skyblue,
// backgroundOpacity: 0.9
// }
// // const distanceLabelOptions = {
// // ...ParamDefinition.getDefaultValues(Text.Params),
// // sizeFactor: 1,
// // offsetX: 0,
// // offsetY: 0,
// // offsetZ: 10,
// // background: true,
// // backgroundMargin: 0.2,
// // backgroundColor: ColorNames.snow,
// // backgroundOpacity: 0.9
// // }
// function buildSnapshot(plugin: PluginContext, template: { tree: StateTree, structure: string }, params: { e: JoleculeSnapshot, idx: number, len: number }): PluginStateSnapshotManager.Entry {
// const b = new StateBuilder.Root(template.tree);
// let i = 0;
// for (const l of params.e.labels) {
// const expression = createExpression([l.i_atom]);
// const group = b.to(template.structure)
// .group(StateTransforms.Misc.CreateGroup, { label: `Label ${++i}` });
// group
// .apply(StateTransforms.Model.StructureSelectionFromExpression, { expression, label: 'Atom' })
// .apply(StateTransforms.Representation.StructureLabels3D, {
// target: { name: 'static-text', params: { value: l.text || '' } },
// options: labelOptions
// });
// group
// .apply(StateTransforms.Model.StructureSelectionFromExpression, { expression: MS.struct.modifier.wholeResidues([ expression ]), label: 'Residue' })
// .apply(StateTransforms.Representation.StructureRepresentation3D,
// createStructureRepresentation3dParamss.getDefaultParamsStatic(plugin, 'ball-and-stick', { }));
// }
// if (params.e.selected && params.e.selected.length > 0) {
// b.to(template.structure)
// .apply(StateTransforms.Model.StructureSelectionFromExpression, { expression: createExpression(params.e.selected), label: `Selected` })
// .apply(StateTransforms.Representation.StructureRepresentation3D,
// createStructureRepresentation3dParamss.getDefaultParamsStatic(plugin, 'ball-and-stick'));
// }
// // TODO
// // for (const l of params.e.distances) {
// // b.to('structure')
// // .apply(StateTransforms.Model.StructureSelectionFromExpression, { query: createQuery([l.i_atom1, l.i_atom2]), label: `Distance ${++i}` })
// // .apply(StateTransforms.Representation.StructureLabels3D, {
// // target: { name: 'static-text', params: { value: l. || '' } },
// // options: labelOptions
// // });
// // }
// return PluginStateSnapshotManager.Entry({
// id: UUID.create22(),
// data: { tree: StateTree.toJSON(b.getTree()) },
// camera: {
// current: getCameraSnapshot(params.e.camera),
// transitionStyle: 'animate',
// transitionDurationInMs: 350
// }
// }, {
// name: params.e.text
// });
// }
// function getCameraSnapshot(e: JoleculeSnapshot['camera']): Camera.Snapshot {
// const direction = Vec3.sub(Vec3(), e.pos, e.in);
// Vec3.normalize(direction, direction);
// const up = Vec3.sub(Vec3(), e.pos, e.up);
// Vec3.normalize(up, up);
// const s: Camera.Snapshot = {
// mode: 'perspective',
// fov: Math.PI / 4,
// position: Vec3.scaleAndAdd(Vec3(), e.pos, direction, e.slab.zoom),
// target: e.pos,
// radius: (e.slab.z_back - e.slab.z_front) / 2,
// fog: 50,
// up,
// };
// return s;
// }
// function createExpression(atomIndices: number[]) {
// if (atomIndices.length === 0) return MS.struct.generator.empty();
// return MS.struct.generator.atomGroups({
// 'atom-test': atomIndices.length === 1
// ? MS.core.rel.eq([MS.struct.atomProperty.core.sourceIndex(), atomIndices[0]])
// : MS.core.set.has([MS.set.apply(null, atomIndices), MS.struct.atomProperty.core.sourceIndex()]),
// 'group-by': 0
// });
// }

View File

@@ -34,10 +34,56 @@
height: 600px;
}
</style>
<link rel="stylesheet" type="text/css" href="app.css" />
<link rel="stylesheet" type="text/css" href="molstar.css" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./index.js"></script>
<script type="text/javascript" src="./molstar.js"></script>
<script type="text/javascript">
function getParam(name, regex) {
var r = new RegExp(name + '=' + '(' + regex + ')[&]?', 'i');
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
}
var debugMode = getParam('debug-mode', '[^&]+').trim() === '1';
if (debugMode) molstar.setDebugMode(debugMode, debugMode);
var disableAntialiasing = getParam('disable-antialiasing', '[^&]+').trim() === '1';
var pixelScale = parseFloat(getParam('pixel-scale', '[^&]+').trim() || '1');
var disableWboit = getParam('disable-wboit', '[^&]+').trim() === '1';
var hideControls = getParam('hide-controls', '[^&]+').trim() === '1';
var pdbProvider = getParam('pdb-provider', '[^&]+').trim().toLowerCase();
var emdbProvider = getParam('emdb-provider', '[^&]+').trim().toLowerCase();
var viewer = new molstar.Viewer('app', {
disableAntialiasing: disableAntialiasing,
pixelScale: pixelScale,
enableWboit: !disableWboit,
layoutShowControls: !hideControls,
viewportShowExpand: false,
pdbProvider: pdbProvider || 'pdbe',
emdbProvider: emdbProvider || 'pdbe',
});
var snapshotId = getParam('snapshot-id', '[^&]+').trim();
if (snapshotId) viewer.setRemoteSnapshot(snapshotId);
var snapshotUrl = getParam('snapshot-url', '[^&]+').trim();
var snapshotUrlType = getParam('snapshot-url-type', '[^&]+').toLowerCase().trim() || 'molj';
if (snapshotUrl && snapshotUrlType) viewer.loadSnapshotFromUrl(snapshotUrl, snapshotUrlType);
var structureUrl = getParam('structure-url', '[^&]+').trim();
var structureUrlFormat = getParam('structure-url-format', '[a-z]+').toLowerCase().trim();
var structureUrlIsBinary = getParam('structure-url-is-binary', '[^&]+').trim() === '1';
if (structureUrl) viewer.loadStructureFromUrl(structureUrl, structureUrlFormat, structureUrlIsBinary);
var pdb = getParam('pdb', '[^&]+').trim();
if (pdb) viewer.loadPdb(pdb);
var pdbDev = getParam('pdb-dev', '[^&]+').trim();
if (pdbDev) viewer.loadPdbDev(pdbDev);
var emdb = getParam('emdb', '[^&]+').trim();
if (emdb) viewer.loadEmdb(emdb);
</script>
</body>
</html>

View File

@@ -1,102 +1,279 @@
/**
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import '../../mol-util/polyfill';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import './index.html'
import './favicon.ico'
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import './index.html';
import './embedded.html';
import './favicon.ico';
import { PluginContext } from '../../mol-plugin/context';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginSpec } from '../../mol-plugin/spec';
import { LoadCellPackModel } from './extensions/cellpack/model';
import { StructureFromCellpack } from './extensions/cellpack/state';
import { DownloadStructure } from '../../mol-plugin-state/actions/structure';
import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
import { PluginConfig } from '../../mol-plugin/config';
require('mol-plugin-ui/skin/light.scss')
import { CellPack } from '../../extensions/cellpack';
import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb';
import { PDBeStructureQualityReport } from '../../extensions/pdbe';
import { Asset } from '../../mol-util/assets';
import { ObjectKeys } from '../../mol-util/type-helpers';
import { PluginState } from '../../mol-plugin/state';
import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior';
import { DnatcoConfalPyramids } from '../../extensions/dnatco';
import { G3DFormat, G3dProvider } from '../../extensions/g3d/format';
import { DataFormatProvider } from '../../mol-plugin-state/formats/provider';
import { BuildInVolumeFormat } from '../../mol-plugin-state/formats/volume';
import { Color } from '../../mol-util/color';
import { StateObjectSelector } from '../../mol-state';
import { PluginStateObject } from '../../mol-plugin-state/objects';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params';
import { Mp4Export } from '../../extensions/mp4-export';
import { StructureRepresentationPresetProvider } from '../../mol-plugin-state/builder/structure/representation-preset';
function getParam(name: string, regex: string): string {
let r = new RegExp(`${name}=(${regex})[&]?`, 'i');
return decodeURIComponent(((window.location.search || '').match(r) || [])[1] || '');
}
require('mol-plugin-ui/skin/light.scss');
const hideControls = getParam('hide-controls', `[^&]+`) === '1';
export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
export { setProductionMode, setDebugMode } from '../../mol-util/debug';
function init() {
const spec: PluginSpec = {
actions: [
...DefaultPluginSpec.actions,
// PluginSpec.Action(CreateJoleculeState),
PluginSpec.Action(LoadCellPackModel),
PluginSpec.Action(StructureFromCellpack),
],
behaviors: [...DefaultPluginSpec.behaviors],
animations: [...DefaultPluginSpec.animations || []],
customParamEditors: DefaultPluginSpec.customParamEditors,
layout: {
initial: {
isExpanded: true,
showControls: !hideControls
const CustomFormats = [
['g3d', G3dProvider] as const
];
const Extensions = {
'cellpack': PluginSpec.Behavior(CellPack),
'dnatco-confal-pyramids': PluginSpec.Behavior(DnatcoConfalPyramids),
'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport),
'rcsb-assembly-symmetry': PluginSpec.Behavior(RCSBAssemblySymmetry),
'rcsb-validation-report': PluginSpec.Behavior(RCSBValidationReport),
'anvil-membrane-orientation': PluginSpec.Behavior(ANVILMembraneOrientation),
'g3d': PluginSpec.Behavior(G3DFormat),
'mp4-export': PluginSpec.Behavior(Mp4Export)
};
const DefaultViewerOptions = {
customFormats: CustomFormats as [string, DataFormatProvider][],
extensions: ObjectKeys(Extensions),
layoutIsExpanded: true,
layoutShowControls: true,
layoutShowRemoteState: true,
layoutControlsDisplay: 'reactive' as PluginLayoutControlsDisplay,
layoutShowSequence: true,
layoutShowLog: true,
layoutShowLeftPanel: true,
disableAntialiasing: false,
pixelScale: 1,
enableWboit: true,
viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue,
viewportShowControls: PluginConfig.Viewport.ShowControls.defaultValue,
viewportShowSettings: PluginConfig.Viewport.ShowSettings.defaultValue,
viewportShowSelectionMode: PluginConfig.Viewport.ShowSelectionMode.defaultValue,
viewportShowAnimation: PluginConfig.Viewport.ShowAnimation.defaultValue,
pluginStateServer: PluginConfig.State.DefaultServer.defaultValue,
volumeStreamingServer: PluginConfig.VolumeStreaming.DefaultServer.defaultValue,
volumeStreamingDisabled: !PluginConfig.VolumeStreaming.Enabled.defaultValue,
pdbProvider: PluginConfig.Download.DefaultPdbProvider.defaultValue,
emdbProvider: PluginConfig.Download.DefaultEmdbProvider.defaultValue,
};
type ViewerOptions = typeof DefaultViewerOptions;
export class Viewer {
plugin: PluginContext
constructor(elementOrId: string | HTMLElement, options: Partial<ViewerOptions> = {}) {
const o = { ...DefaultViewerOptions, ...options };
const defaultSpec = DefaultPluginSpec();
const spec: PluginSpec = {
actions: [...defaultSpec.actions],
behaviors: [
...defaultSpec.behaviors,
...o.extensions.map(e => Extensions[e]),
],
animations: [...defaultSpec.animations || []],
customParamEditors: defaultSpec.customParamEditors,
customFormats: o?.customFormats,
layout: {
initial: {
isExpanded: o.layoutIsExpanded,
showControls: o.layoutShowControls,
controlsDisplay: o.layoutControlsDisplay,
},
controls: {
...defaultSpec.layout && defaultSpec.layout.controls,
top: o.layoutShowSequence ? undefined : 'none',
bottom: o.layoutShowLog ? undefined : 'none',
left: o.layoutShowLeftPanel ? undefined : 'none',
}
},
controls: {
...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls
}
},
config: DefaultPluginSpec.config
};
spec.config?.set(PluginConfig.Viewport.ShowExpand, false);
const plugin = createPlugin(document.getElementById('app')!, spec);
trySetSnapshot(plugin);
tryLoadFromUrl(plugin);
}
components: {
...defaultSpec.components,
remoteState: o.layoutShowRemoteState ? 'default' : 'none',
},
config: [
[PluginConfig.General.DisableAntialiasing, o.disableAntialiasing],
[PluginConfig.General.PixelScale, o.pixelScale],
[PluginConfig.General.EnableWboit, o.enableWboit],
[PluginConfig.Viewport.ShowExpand, o.viewportShowExpand],
[PluginConfig.Viewport.ShowControls, o.viewportShowControls],
[PluginConfig.Viewport.ShowSettings, o.viewportShowSettings],
[PluginConfig.Viewport.ShowSelectionMode, o.viewportShowSelectionMode],
[PluginConfig.Viewport.ShowAnimation, o.viewportShowAnimation],
[PluginConfig.State.DefaultServer, o.pluginStateServer],
[PluginConfig.State.CurrentServer, o.pluginStateServer],
[PluginConfig.VolumeStreaming.DefaultServer, o.volumeStreamingServer],
[PluginConfig.VolumeStreaming.Enabled, !o.volumeStreamingDisabled],
[PluginConfig.Download.DefaultPdbProvider, o.pdbProvider],
[PluginConfig.Download.DefaultEmdbProvider, o.emdbProvider]
]
};
async function trySetSnapshot(ctx: PluginContext) {
try {
const snapshotUrl = getParam('snapshot-url', `[^&]+`);
const snapshotId = getParam('snapshot-id', `[^&]+`);
if (!snapshotUrl && !snapshotId) return;
// TODO parametrize the server
const url = snapshotId
? `https://webchem.ncbr.muni.cz/molstar-state/get/${snapshotId}`
: snapshotUrl;
await PluginCommands.State.Snapshots.Fetch(ctx, { url })
} catch (e) {
ctx.log.error('Failed to load snapshot.');
console.warn('Failed to load snapshot', e);
const element = typeof elementOrId === 'string'
? document.getElementById(elementOrId)
: elementOrId;
if (!element) throw new Error(`Could not get element with id '${elementOrId}'`);
this.plugin = createPlugin(element, spec);
}
}
async function tryLoadFromUrl(ctx: PluginContext) {
const url = getParam('loadFromURL', '[^&]+').trim();
try {
if (!url) return;
setRemoteSnapshot(id: string) {
const url = `${this.plugin.config.get(PluginConfig.State.CurrentServer)}/get/${id}`;
return PluginCommands.State.Snapshots.Fetch(this.plugin, { url });
}
let format = 'cif', isBinary = false;
switch (getParam('loadFromURLFormat', '[a-z]+').toLocaleLowerCase().trim()) {
case 'pdb': format = 'pdb'; break;
case 'mmbcif': isBinary = true; break;
}
loadSnapshotFromUrl(url: string, type: PluginState.SnapshotType) {
return PluginCommands.State.Snapshots.OpenUrl(this.plugin, { url, type });
}
const params = DownloadStructure.createDefaultParams(void 0 as any, ctx);
return ctx.runTask(ctx.state.data.applyAction(DownloadStructure, {
loadStructureFromUrl(url: string, format: BuiltInTrajectoryFormat = 'mmcif', isBinary = false, options?: LoadStructureOptions) {
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
source: {
name: 'url',
params: {
url,
url: Asset.Url(url),
format: format as any,
isBinary,
options: { ...params.source.params.options, representationParams: options?.representationParams as any },
}
}
}));
}
async loadAllModelsOrAssemblyFromUrl(url: string, format: BuiltInTrajectoryFormat = 'mmcif', isBinary = false, options?: LoadStructureOptions) {
const plugin = this.plugin;
const data = await plugin.builders.data.download({ url, isBinary }, { state: { isGhost: true } });
const trajectory = await plugin.builders.structure.parseTrajectory(data, format);
await this.plugin.builders.structure.hierarchy.applyPreset(trajectory, 'all-models', { useDefaultIfSingleModel: true, representationPresetParams: options?.representationParams });
}
async loadStructureFromData(data: string | number[], format: BuiltInTrajectoryFormat, options?: { dataLabel?: string }) {
const _data = await this.plugin.builders.data.rawData({ data, label: options?.dataLabel });
const trajectory = await this.plugin.builders.structure.parseTrajectory(_data, format);
await this.plugin.builders.structure.hierarchy.applyPreset(trajectory, 'default');
}
loadPdb(pdb: string, options?: LoadStructureOptions) {
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
const provider = this.plugin.config.get(PluginConfig.Download.DefaultPdbProvider)!;
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
source: {
name: 'pdb' as const,
params: {
provider: {
id: pdb,
server: {
name: provider,
params: PdbDownloadProvider[provider].defaultValue as any
}
},
options: { ...params.source.params.options, representationParams: options?.representationParams as any },
}
}
}));
}
loadPdbDev(pdbDev: string) {
const params = DownloadStructure.createDefaultParams(this.plugin.state.data.root.obj!, this.plugin);
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadStructure, {
source: {
name: 'pdb-dev' as const,
params: {
provider: {
id: pdbDev,
encoding: 'bcif',
},
options: params.source.params.options,
}
}
}));
} catch (e) {
ctx.log.error(`Failed to load from URL (${url})`);
console.warn(`Failed to load from URL (${url})`, e);
}
loadEmdb(emdb: string, options?: { detail?: number }) {
const provider = this.plugin.config.get(PluginConfig.Download.DefaultEmdbProvider)!;
return this.plugin.runTask(this.plugin.state.data.applyAction(DownloadDensity, {
source: {
name: 'pdb-emd-ds' as const,
params: {
provider: {
id: emdb,
server: provider,
},
detail: options?.detail ?? 3,
}
}
}));
}
async loadVolumeFromUrl(url: string, format: BuildInVolumeFormat, isBinary: boolean, isovalues: VolumeIsovalueInfo[], entryId?: string) {
const plugin = this.plugin;
if (!plugin.dataFormats.get(format)) {
throw new Error(`Unknown density format: ${format}`);
}
return plugin.dataTransaction(async () => {
const data = await plugin.builders.data.download({ url, isBinary, label: entryId }, { state: { isGhost: true } });
const parsed = await plugin.dataFormats.get(format)!.parse(plugin, data, { entryId });
const volume = (parsed.volume || parsed.volumes[0]) as StateObjectSelector<PluginStateObject.Volume.Data>;
if (!volume?.isOk) throw new Error('Failed to parse any volume.');
const repr = plugin.build().to(volume);
for (const iso of isovalues) {
repr.apply(StateTransforms.Representation.VolumeRepresentation3D, createVolumeRepresentationParams(this.plugin, volume.data!, {
type: 'isosurface',
typeParams: { alpha: iso.alpha ?? 1, isoValue: iso.type === 'absolute' ? { kind: 'absolute', absoluteValue: iso.value } : { kind: 'relative', relativeValue: iso.value } },
color: 'uniform',
colorParams: { value: iso.color }
}));
}
await repr.commit();
});
}
handleResize() {
this.plugin.layout.events.updated.next();
}
}
init();
export interface LoadStructureOptions {
representationParams?: StructureRepresentationPresetProvider.CommonParams
}
export interface VolumeIsovalueInfo {
type: 'absolute' | 'relative',
value: number,
color: Color,
alpha?: number
}

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env node
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Josh McMenemy <josh.mcmenemy@gmail.com>
*/
import * as argparse from 'argparse';
import * as path from 'path';
import util from 'util';
import fs from 'fs';
require('util.promisify').shim();
const writeFile = util.promisify(fs.writeFile);
import { DatabaseCollection } from '../../mol-data/db';
import { CCD_Schema } from '../../mol-io/reader/cif/schema/ccd';
import { ensureDataAvailable, readCCD } from './util';
function extractIonNames(ccd: DatabaseCollection<CCD_Schema>) {
const ionNames: string[] = [];
for (const k in ccd) {
const {chem_comp} = ccd[k];
if (chem_comp.name.value(0).toUpperCase().includes(' ION')) {
ionNames.push(chem_comp.id.value(0));
}
}
// these are extra ions that don't have ION in their name
ionNames.push('NCO', 'OHX');
return ionNames;
}
function writeIonNamesFile(filePath: string, ionNames: string[]) {
const output = `/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated ion names params file. Names extracted from CCD components.
*
* @author molstar/chem-comp-dict/create-table cli
*/
export const IonNames = new Set(${JSON.stringify(ionNames).replace(/"/g, "'").replace(/,/g, ', ')});
`;
writeFile(filePath, output);
}
async function run(out: string, forceDownload = false) {
await ensureDataAvailable(forceDownload);
const ccd = await readCCD();
const ionNames = extractIonNames(ccd);
if (!fs.existsSync(path.dirname(out))) {
fs.mkdirSync(path.dirname(out));
}
writeIonNamesFile(out, ionNames);
}
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Extract and save IonNames from CCD.'
});
parser.addArgument('out', {
help: 'Generated file output path.'
});
parser.addArgument([ '--forceDownload', '-f' ], {
action: 'storeTrue',
help: 'Force download of CCD and PVCD.'
});
interface Args {
out: string,
forceDownload?: boolean,
}
const args: Args = parser.parseArgs();
run(args.out, args.forceDownload);

View File

@@ -0,0 +1,294 @@
#!/usr/bin/env node
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse';
import * as util from 'util';
import * as path from 'path';
import * as fs from 'fs';
require('util.promisify').shim();
const writeFile = util.promisify(fs.writeFile);
import { Database, Table, DatabaseCollection } from '../../mol-data/db';
import { CCD_Schema } from '../../mol-io/reader/cif/schema/ccd';
import { SetUtils } from '../../mol-util/set';
import { DefaultMap } from '../../mol-util/map';
import { mmCIF_chemCompBond_schema } from '../../mol-io/reader/cif/schema/mmcif-extras';
import { ccd_chemCompAtom_schema } from '../../mol-io/reader/cif/schema/ccd-extras';
import { ensureDataAvailable, getEncodedCif, readCCD, readPVCD } from './util';
type CCB = Table<CCD_Schema['chem_comp_bond']>
type CCA = Table<CCD_Schema['chem_comp_atom']>
function ccbKey(compId: string, atomId1: string, atomId2: string) {
return atomId1 < atomId2 ? `${compId}:${atomId1}-${atomId2}` : `${compId}:${atomId2}-${atomId1}`;
}
function ccaKey(compId: string, atomId: string) {
return `${compId}:${atomId}`;
}
function addChemCompBondToSet(set: Set<string>, ccb: CCB) {
for (let i = 0, il = ccb._rowCount; i < il; ++i) {
set.add(ccbKey(ccb.comp_id.value(i), ccb.atom_id_1.value(i), ccb.atom_id_2.value(i)));
}
return set;
}
function addChemCompAtomToSet(set: Set<string>, cca: CCA) {
for (let i = 0, il = cca._rowCount; i < il; ++i) {
set.add(ccaKey(cca.comp_id.value(i), cca.atom_id.value(i)));
}
return set;
}
function checkAddingBondsFromPVCD(pvcd: DatabaseCollection<CCD_Schema>) {
const ccbSetByParent = DefaultMap<string, Set<string>>(() => new Set());
for (const k in pvcd) {
const { chem_comp, chem_comp_bond } = pvcd[k];
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0);
if (parentIds.length === 0) {
const set = ccbSetByParent.getDefault(chem_comp.id.value(0));
addChemCompBondToSet(set, chem_comp_bond);
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
const parentId = parentIds[i];
const set = ccbSetByParent.getDefault(parentId);
addChemCompBondToSet(set, chem_comp_bond);
}
}
}
}
for (const k in pvcd) {
const { chem_comp, chem_comp_atom, chem_comp_bond } = pvcd[k];
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0);
if (parentIds.length > 0) {
for (let i = 0, il = parentIds.length; i < il; ++i) {
const entryBonds = addChemCompBondToSet(new Set<string>(), chem_comp_bond);
const entryAtoms = addChemCompAtomToSet(new Set<string>(), chem_comp_atom);
const extraBonds = SetUtils.difference(ccbSetByParent.get(parentIds[i])!, entryBonds);
extraBonds.forEach(bk => {
const [a1, a2] = bk.split('|');
if (entryAtoms.has(a1) && entryAtoms.has(a2)) {
console.error(`Adding all PVCD bonds would wrongly add bond ${bk} for ${k}`);
}
});
}
}
}
}
}
function checkAddingAtomsFromPVCD(pvcd: DatabaseCollection<CCD_Schema>) {
const ccaSetByParent = DefaultMap<string, Set<string>>(() => new Set());
for (const k in pvcd) {
const { chem_comp, chem_comp_atom } = pvcd[k];
if (chem_comp_atom._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0);
if (parentIds.length === 0) {
const set = ccaSetByParent.getDefault(chem_comp.id.value(0));
addChemCompAtomToSet(set, chem_comp_atom);
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
const parentId = parentIds[i];
const set = ccaSetByParent.getDefault(parentId);
addChemCompAtomToSet(set, chem_comp_atom);
}
}
}
}
}
async function createBonds(
ccd: DatabaseCollection<CCD_Schema>,
pvcd: DatabaseCollection<CCD_Schema>,
atomsRequested: boolean
) {
const ccbSet = new Set<string>();
const comp_id: string[] = [];
const atom_id_1: string[] = [];
const atom_id_2: string[] = [];
const value_order: typeof mmCIF_chemCompBond_schema['value_order']['T'][] = [];
const pdbx_aromatic_flag: typeof mmCIF_chemCompBond_schema['pdbx_aromatic_flag']['T'][] = [];
const pdbx_stereo_config: typeof mmCIF_chemCompBond_schema['pdbx_stereo_config']['T'][] = [];
const molstar_protonation_variant: string[] = [];
function addBonds(compId: string, ccb: CCB, protonationVariant: boolean) {
for (let i = 0, il = ccb._rowCount; i < il; ++i) {
const atomId1 = ccb.atom_id_1.value(i);
const atomId2 = ccb.atom_id_2.value(i);
const k = ccbKey(compId, atomId1, atomId2);
if (!ccbSet.has(k)) {
atom_id_1.push(atomId1);
atom_id_2.push(atomId2);
comp_id.push(compId);
value_order.push(ccb.value_order.value(i));
pdbx_aromatic_flag.push(ccb.pdbx_aromatic_flag.value(i));
pdbx_stereo_config.push(ccb.pdbx_stereo_config.value(i));
molstar_protonation_variant.push(protonationVariant ? 'Y' : 'N');
ccbSet.add(k);
}
}
}
// check adding bonds from PVCD
checkAddingBondsFromPVCD(pvcd);
// add bonds from PVCD
for (const k in pvcd) {
const { chem_comp, chem_comp_bond } = pvcd[k];
if (chem_comp_bond._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0);
if (parentIds.length === 0) {
addBonds(chem_comp.id.value(0), chem_comp_bond, false);
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
addBonds(parentIds[i], chem_comp_bond, true);
}
}
}
}
// add bonds from CCD
for (const k in ccd) {
const { chem_comp, chem_comp_bond } = ccd[k];
if (chem_comp_bond._rowCount) {
addBonds(chem_comp.id.value(0), chem_comp_bond, false);
}
}
const bondTable = Table.ofArrays(mmCIF_chemCompBond_schema, {
comp_id, atom_id_1, atom_id_2, value_order,
pdbx_aromatic_flag, pdbx_stereo_config, molstar_protonation_variant
});
const bondDatabase = Database.ofTables(
CCB_TABLE_NAME,
{ chem_comp_bond: mmCIF_chemCompBond_schema },
{ chem_comp_bond: bondTable }
);
return { bonds: bondDatabase, atoms: atomsRequested ? createAtoms(ccd, pvcd) : void 0 };
}
function createAtoms(ccd: DatabaseCollection<CCD_Schema>, pvcd: DatabaseCollection<CCD_Schema>) {
const ccaSet = new Set<string>();
const comp_id: string[] = [];
const atom_id: string[] = [];
const charge: number[] = [];
const pdbx_stereo_config: typeof CCD_Schema.chem_comp_atom['pdbx_stereo_config']['T'][] = [];
function addAtoms(compId: string, cca: CCA) {
for (let i = 0, il = cca._rowCount; i < il; ++i) {
const atomId = cca.atom_id.value(i);
const k = ccaKey(compId, atomId);
if (!ccaSet.has(k)) {
atom_id.push(atomId);
comp_id.push(compId);
charge.push(cca.charge.value(i));
pdbx_stereo_config.push(cca.pdbx_stereo_config.value(i));
ccaSet.add(k);
}
}
}
// check adding atoms from PVCD
checkAddingAtomsFromPVCD(pvcd);
// add atoms from PVCD
for (const k in pvcd) {
const { chem_comp, chem_comp_atom } = pvcd[k];
if (chem_comp_atom._rowCount) {
const parentIds = chem_comp.mon_nstd_parent_comp_id.value(0);
if (parentIds.length === 0) {
addAtoms(chem_comp.id.value(0), chem_comp_atom);
} else {
for (let i = 0, il = parentIds.length; i < il; ++i) {
addAtoms(parentIds[i], chem_comp_atom);
}
}
}
}
// add atoms from CCD
for (const k in ccd) {
const { chem_comp, chem_comp_atom } = ccd[k];
if (chem_comp_atom._rowCount) {
addAtoms(chem_comp.id.value(0), chem_comp_atom);
}
}
const atomTable = Table.ofArrays(ccd_chemCompAtom_schema, {
comp_id, atom_id, charge, pdbx_stereo_config
});
return Database.ofTables(
CCA_TABLE_NAME,
{ chem_comp_atom: ccd_chemCompAtom_schema },
{ chem_comp_atom: atomTable }
);
}
async function run(out: string, binary = false, forceDownload = false, ccaOut?: string) {
await ensureDataAvailable(forceDownload);
const ccd = await readCCD();
const pvcd = await readPVCD();
const { bonds, atoms } = await createBonds(ccd, pvcd, !!ccaOut);
const ccbCif = getEncodedCif(CCB_TABLE_NAME, bonds, binary);
if (!fs.existsSync(path.dirname(out))) {
fs.mkdirSync(path.dirname(out));
}
writeFile(out, ccbCif);
if (!!ccaOut) {
const ccaCif = getEncodedCif(CCA_TABLE_NAME, atoms, binary);
if (!fs.existsSync(path.dirname(ccaOut))) {
fs.mkdirSync(path.dirname(ccaOut));
}
writeFile(ccaOut, ccaCif);
}
}
const CCB_TABLE_NAME = 'CHEM_COMP_BONDS';
const CCA_TABLE_NAME = 'CHEM_COMP_ATOMS';
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Create a cif file with one big table of all chem_comp_bond entries from the CCD and PVCD.'
});
parser.addArgument('out', {
help: 'Generated file output path.'
});
parser.addArgument([ '--forceDownload', '-f' ], {
action: 'storeTrue',
help: 'Force download of CCD and PVCD.'
});
parser.addArgument([ '--binary', '-b' ], {
action: 'storeTrue',
help: 'Output as BinaryCIF.'
});
parser.addArgument(['--ccaOut', '-a'], {
help: 'Optional generated file output path for chem_comp_atom data.',
required: false
});
interface Args {
out: string,
forceDownload?: boolean,
binary?: boolean,
ccaOut?: string
}
const args: Args = parser.parseArgs();
run(args.out, args.binary, args.forceDownload, args.ccaOut);

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as util from 'util';
import * as path from 'path';
import * as fs from 'fs';
import * as zlib from 'zlib';
import fetch from 'node-fetch';
require('util.promisify').shim();
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
import { Progress } from '../../mol-task';
import { Database } from '../../mol-data/db';
import { CIF } from '../../mol-io/reader/cif';
import { CifWriter } from '../../mol-io/writer/cif';
import { CCD_Schema } from '../../mol-io/reader/cif/schema/ccd';
export async function ensureAvailable(path: string, url: string, forceDownload = false) {
if (forceDownload || !fs.existsSync(path)) {
console.log(`downloading ${url}...`);
const data = await fetch(url);
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR);
}
if (url.endsWith('.gz')) {
await writeFile(path, zlib.gunzipSync(await data.buffer()));
} else {
await writeFile(path, await data.text());
}
console.log(`done downloading ${url}`);
}
}
export async function ensureDataAvailable(forceDownload = false) {
await ensureAvailable(CCD_PATH, CCD_URL, forceDownload);
await ensureAvailable(PVCD_PATH, PVCD_URL, forceDownload);
}
export async function readFileAsCollection<S extends Database.Schema>(path: string, schema: S) {
const parsed = await parseCif(await readFile(path, 'utf8'));
return CIF.toDatabaseCollection(schema, parsed.result);
}
export async function readCCD() {
return readFileAsCollection(CCD_PATH, CCD_Schema);
}
export async function readPVCD() {
return readFileAsCollection(PVCD_PATH, CCD_Schema);
}
async function parseCif(data: string | Uint8Array) {
const comp = CIF.parse(data);
console.time('parse cif');
const parsed = await comp.run(p => console.log(Progress.format(p)), 250);
console.timeEnd('parse cif');
if (parsed.isError) throw parsed;
return parsed;
}
export function getEncodedCif(name: string, database: Database<Database.Schema>, binary = false) {
const encoder = CifWriter.createEncoder({ binary, encoderName: 'mol*' });
CifWriter.Encoder.writeDatabase(encoder, name, database);
return encoder.getData();
}
const DATA_DIR = path.join(__dirname, '..', '..', '..', '..', 'build/data');
const CCD_PATH = path.join(DATA_DIR, 'components.cif');
const PVCD_PATH = path.join(DATA_DIR, 'aa-variants-v1.cif');
const CCD_URL = 'http://ftp.wwpdb.org/pub/pdb/data/monomers/components.cif';
const PVCD_URL = 'http://ftp.wwpdb.org/pub/pdb/data/monomers/aa-variants-v1.cif';

View File

@@ -0,0 +1,119 @@
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
*/
import { CIF, CifCategory, getCifFieldType, CifField, CifFile } from '../../mol-io/reader/cif';
import { CifWriter, EncodingStrategyHint } from '../../mol-io/writer/cif';
import * as util from 'util';
import * as fs from 'fs';
import * as zlib from 'zlib';
import { Progress, Task, RuntimeContext } from '../../mol-task';
import { classifyFloatArray, classifyIntArray } from '../../mol-io/common/binary-cif';
import { BinaryEncodingProvider } from '../../mol-io/writer/cif/encoder/binary';
import { Category } from '../../mol-io/writer/cif/encoder';
import { ReaderResult } from '../../mol-io/reader/result';
function showProgress(p: Progress) {
process.stdout.write(`\r${new Array(80).join(' ')}`);
process.stdout.write(`\r${Progress.format(p)}`);
}
const readFileAsync = util.promisify(fs.readFile);
const unzipAsync = util.promisify<zlib.InputType, Buffer>(zlib.unzip);
async function readFile(ctx: RuntimeContext, filename: string): Promise<ReaderResult<CifFile>> {
const isGz = /\.gz$/i.test(filename);
if (filename.match(/\.bcif/)) {
let input = await readFileAsync(filename);
if (isGz) input = await unzipAsync(input);
return await CIF.parseBinary(new Uint8Array(input)).runInContext(ctx);
} else {
let str: string;
if (isGz) {
const data = await unzipAsync(await readFileAsync(filename));
str = data.toString('utf8');
} else {
str = await readFileAsync(filename, 'utf8');
}
return await CIF.parseText(str).runInContext(ctx);
}
}
async function getCIF(ctx: RuntimeContext, filename: string) {
const parsed = await readFile(ctx, filename);
if (parsed.isError) {
throw new Error(parsed.toString());
}
return parsed.result;
}
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 });
}
}
export function convert(path: string, asText = false, hints?: EncodingStrategyHint[], filter?: string) {
return Task.create<Uint8Array>('BinaryCIF', async ctx => {
const encodingProvider: BinaryEncodingProvider = hints
? CifWriter.createEncodingProviderFromJsonConfig(hints)
: { get: (c, f) => void 0 };
const cif = await getCIF(ctx, path);
const encoder = CifWriter.createEncoder({
binary: !asText,
encoderName: 'mol*/ciftools cif2bcif',
binaryAutoClassifyEncoding: true,
binaryEncodingPovider: encodingProvider
});
if (filter) {
encoder.setFilter(Category.filterOf(filter));
}
let maxProgress = 0;
for (const b of cif.blocks) {
maxProgress += b.categoryNames.length;
for (const c of b.categoryNames) maxProgress += b.categories[c].fieldNames.length;
}
let current = 0;
for (const b of cif.blocks) {
encoder.startDataBlock(b.header);
for (const c of b.categoryNames) {
const cat = b.categories[c];
const fields: CifWriter.Field[] = [];
for (const f of cat.fieldNames) {
fields.push(classify(f, cat.getField(f)!));
current++;
if (ctx.shouldUpdate) await ctx.update({ message: 'Encoding...', current, max: maxProgress });
}
encoder.writeCategory(getCategoryInstanceProvider(b.categories[c], fields));
current++;
if (ctx.shouldUpdate) await ctx.update({ message: 'Encoding...', current, max: maxProgress });
}
}
await ctx.update('Exporting...');
const ret = encoder.getData() as Uint8Array;
await ctx.update('Done.\n');
return ret;
}).run(showProgress, 250);
}

68
src/cli/cif2bcif/index.ts Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env node
/**
* Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse';
import * as util from 'util';
import * as fs from 'fs';
import * as zlib from 'zlib';
import { convert } from './converter';
require('util.promisify').shim();
async function process(srcPath: string, outPath: string, configPath?: string, filterPath?: string) {
const config = configPath ? JSON.parse(fs.readFileSync(configPath, 'utf8')) : void 0;
const filter = filterPath ? fs.readFileSync(filterPath, 'utf8') : void 0;
const res = await convert(srcPath, false, config, filter);
await write(outPath, res);
}
const zipAsync = util.promisify<zlib.InputType, Buffer>(zlib.gzip);
async function write(outPath: string, res: Uint8Array) {
const isGz = /\.gz$/i.test(outPath);
if (isGz) {
res = await zipAsync(res);
}
fs.writeFileSync(outPath, res);
}
function run(args: Args) {
process(args.src, args.out, args.config, args.filter);
}
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Convert any CIF file to a BCIF file'
});
parser.addArgument([ 'src' ], {
help: 'Source CIF path'
});
parser.addArgument([ 'out' ], {
help: 'Output BCIF path'
});
parser.addArgument([ '-c', '--config' ], {
help: 'Optional encoding strategy/precision config path',
required: false
});
parser.addArgument([ '-f', '--filter' ], {
help: 'Optional filter whitelist/blacklist path',
required: false
});
interface Args {
src: string
out: string
config?: string
filter?: string
}
const args: Args = parser.parseArgs();
if (args) {
run(args);
}

275
src/cli/cifschema/index.ts Normal file
View File

@@ -0,0 +1,275 @@
#!/usr/bin/env node
/**
* Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse';
import * as fs from 'fs';
import * as path from 'path';
import fetch from 'node-fetch';
import { parseCsv } from '../../mol-io/reader/csv/parser';
import { CifFrame, CifBlock } from '../../mol-io/reader/cif';
import { parseCifText } from '../../mol-io/reader/cif/text/parser';
import { generateSchema } from './util/cif-dic';
import { generate } from './util/generate';
import { Filter, Database } from './util/schema';
import { parseImportGet } from './util/helper';
function getDicVersion(block: CifBlock) {
return block.categories.dictionary.getField('version')!.str(0);
}
function getDicNamespace(block: CifBlock) {
return block.categories.dictionary.getField('namespace')!.str(0);
}
async function runGenerateSchemaMmcif(name: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
await ensureMmcifDicAvailable();
const mmcifDic = await parseCifText(fs.readFileSync(MMCIF_DIC_PATH, 'utf8')).run();
if (mmcifDic.isError) throw mmcifDic;
await ensureIhmDicAvailable();
const ihmDic = await parseCifText(fs.readFileSync(IHM_DIC_PATH, 'utf8')).run();
if (ihmDic.isError) throw ihmDic;
await ensureCarbBranchDicAvailable();
const carbBranchDic = await parseCifText(fs.readFileSync(CARB_BRANCH_DIC_PATH, 'utf8')).run();
if (carbBranchDic.isError) throw carbBranchDic;
await ensureCarbCompDicAvailable();
const carbCompDic = await parseCifText(fs.readFileSync(CARB_COMP_DIC_PATH, 'utf8')).run();
if (carbCompDic.isError) throw carbCompDic;
const mmcifDicVersion = getDicVersion(mmcifDic.result.blocks[0]);
const ihmDicVersion = getDicVersion(ihmDic.result.blocks[0]);
const carbDicVersion = 'draft';
const version = `Dictionary versions: mmCIF ${mmcifDicVersion}, IHM ${ihmDicVersion}, CARB ${carbDicVersion}.`;
const frames: CifFrame[] = [...mmcifDic.result.blocks[0].saveFrames, ...ihmDic.result.blocks[0].saveFrames, ...carbBranchDic.result.blocks[0].saveFrames, ...carbCompDic.result.blocks[0].saveFrames];
const schema = generateSchema(frames);
await runGenerateSchema(name, version, schema, fieldNamesPath, typescript, out, moldbImportPath, addAliases);
}
async function runGenerateSchemaCifCore(name: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
await ensureCifCoreDicAvailable();
const cifCoreDic = await parseCifText(fs.readFileSync(CIF_CORE_DIC_PATH, 'utf8')).run();
if (cifCoreDic.isError) throw cifCoreDic;
const cifCoreDicVersion = getDicVersion(cifCoreDic.result.blocks[0]);
const version = `Dictionary versions: CifCore ${cifCoreDicVersion}.`;
const frames: CifFrame[] = [...cifCoreDic.result.blocks[0].saveFrames];
const imports = await resolveImports(frames, DIC_DIR);
const schema = generateSchema(frames, imports);
await runGenerateSchema(name, version, schema, fieldNamesPath, typescript, out, moldbImportPath, addAliases);
}
async function resolveImports(frames: CifFrame[], baseDir: string): Promise<Map<string, CifFrame[]>> {
const imports = new Map<string, CifFrame[]>();
for (const d of frames) {
if ('import' in d.categories) {
const importGet = parseImportGet(d.categories['import'].getField('get')!.str(0));
for (const g of importGet) {
const { file } = g;
if (!file) continue;
if (imports.has(file)) continue;
const dic = await parseCifText(fs.readFileSync(path.join(baseDir, file), 'utf8')).run();
if (dic.isError) throw dic;
imports.set(file, [...dic.result.blocks[0].saveFrames]);
}
}
}
return imports;
}
async function runGenerateSchemaDic(name: string, dicPath: string, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
const dic = await parseCifText(fs.readFileSync(dicPath, 'utf8')).run();
if (dic.isError) throw dic;
const dicVersion = getDicVersion(dic.result.blocks[0]);
const dicName = getDicNamespace(dic.result.blocks[0]);
const version = `Dictionary versions: ${dicName} ${dicVersion}.`;
const frames: CifFrame[] = [...dic.result.blocks[0].saveFrames];
const imports = await resolveImports(frames, path.dirname(dicPath));
const schema = generateSchema(frames, imports);
await runGenerateSchema(name, version, schema, fieldNamesPath, typescript, out, moldbImportPath, addAliases);
}
async function runGenerateSchema(name: string, version: string, schema: Database, fieldNamesPath: string, typescript = false, out: string, moldbImportPath: string, addAliases: boolean) {
const filter = fieldNamesPath ? await getFieldNamesFilter(fieldNamesPath) : undefined;
const output = typescript ? generate(name, version, schema, filter, moldbImportPath, addAliases) : JSON.stringify(schema, undefined, 4);
if (out) {
fs.writeFileSync(out, output);
} else {
console.log(output);
}
}
async function getFieldNamesFilter(fieldNamesPath: string): Promise<Filter> {
const fieldNamesStr = fs.readFileSync(fieldNamesPath, 'utf8');
const parsed = await parseCsv(fieldNamesStr, { noColumnNames: true }).run();
if (parsed.isError) throw parser.error;
const csvFile = parsed.result;
const fieldNamesCol = csvFile.table.getColumn('0');
if (!fieldNamesCol) throw 'error getting fields columns';
const fieldNames = fieldNamesCol.toStringArray();
const filter: Filter = {};
fieldNames.forEach((name, i) => {
const [ category, field ] = name.split('.');
// console.log(category, field)
if (!filter[ category ]) filter[ category ] = {};
filter[ category ][ field ] = true;
});
return filter;
}
async function ensureMmcifDicAvailable() { await ensureDicAvailable(MMCIF_DIC_PATH, MMCIF_DIC_URL); }
async function ensureIhmDicAvailable() { await ensureDicAvailable(IHM_DIC_PATH, IHM_DIC_URL); }
async function ensureCarbBranchDicAvailable() { await ensureDicAvailable(CARB_BRANCH_DIC_PATH, CARB_BRANCH_DIC_URL); }
async function ensureCarbCompDicAvailable() { await ensureDicAvailable(CARB_COMP_DIC_PATH, CARB_COMP_DIC_URL); }
async function ensureCifCoreDicAvailable() {
await ensureDicAvailable(CIF_CORE_DIC_PATH, CIF_CORE_DIC_URL);
await ensureDicAvailable(CIF_CORE_ENUM_PATH, CIF_CORE_ENUM_URL);
await ensureDicAvailable(CIF_CORE_ATTR_PATH, CIF_CORE_ATTR_URL);
}
async function ensureDicAvailable(dicPath: string, dicUrl: string) {
if (FORCE_DIC_DOWNLOAD || !fs.existsSync(dicPath)) {
const name = dicUrl.substr(dicUrl.lastIndexOf('/') + 1);
console.log(`downloading ${name}...`);
const data = await fetch(dicUrl);
if (!fs.existsSync(DIC_DIR)) {
fs.mkdirSync(DIC_DIR);
}
fs.writeFileSync(dicPath, await data.text());
console.log(`done downloading ${name}`);
}
}
const DIC_DIR = path.resolve(__dirname, '../../../../build/dics/');
const MMCIF_DIC_PATH = `${DIC_DIR}/mmcif_pdbx_v50.dic`;
const MMCIF_DIC_URL = 'http://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic';
const IHM_DIC_PATH = `${DIC_DIR}/ihm-extension.dic`;
const IHM_DIC_URL = 'https://raw.githubusercontent.com/ihmwg/IHM-dictionary/master/ihm-extension.dic';
const CARB_BRANCH_DIC_PATH = `${DIC_DIR}/entity_branch-extension.dic`;
const CARB_BRANCH_DIC_URL = 'https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/dict/entity_branch-extension.dic';
const CARB_COMP_DIC_PATH = `${DIC_DIR}/chem_comp-extension.dic`;
const CARB_COMP_DIC_URL = 'https://raw.githubusercontent.com/pdbxmmcifwg/carbohydrate-extension/master/dict/chem_comp-extension.dic';
const CIF_CORE_DIC_PATH = `${DIC_DIR}/cif_core.dic`;
const CIF_CORE_DIC_URL = 'https://raw.githubusercontent.com/COMCIFS/cif_core/master/cif_core.dic';
const CIF_CORE_ENUM_PATH = `${DIC_DIR}/templ_enum.cif`;
const CIF_CORE_ENUM_URL = 'https://raw.githubusercontent.com/COMCIFS/cif_core/master/templ_enum.cif';
const CIF_CORE_ATTR_PATH = `${DIC_DIR}/templ_attr.cif`;
const CIF_CORE_ATTR_URL = 'https://raw.githubusercontent.com/COMCIFS/cif_core/master/templ_attr.cif';
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Create schema from mmcif dictionary (v50 plus IHM and entity_branch extensions, downloaded from wwPDB)'
});
parser.addArgument([ '--preset', '-p' ], {
defaultValue: '',
choices: ['', 'mmCIF', 'CCD', 'BIRD', 'CifCore'],
help: 'Preset name'
});
parser.addArgument([ '--name', '-n' ], {
defaultValue: '',
help: 'Schema name'
});
parser.addArgument([ '--out', '-o' ], {
help: 'Generated schema output path, if not given printed to stdout'
});
parser.addArgument([ '--targetFormat', '-tf' ], {
defaultValue: 'typescript-molstar',
choices: ['typescript-molstar', 'json-internal'],
help: 'Target format'
});
parser.addArgument([ '--dicPath', '-d' ], {
defaultValue: '',
help: 'Path to dictionary'
});
parser.addArgument([ '--fieldNamesPath', '-fn' ], {
defaultValue: '',
help: 'Field names to include'
});
parser.addArgument([ '--forceDicDownload', '-f' ], {
action: 'storeTrue',
help: 'Force download of dictionaries'
});
parser.addArgument([ '--moldataImportPath', '-mip' ], {
defaultValue: 'molstar/lib/mol-data',
help: 'mol-data import path (for typescript target only)'
});
parser.addArgument([ '--addAliases', '-aa' ], {
action: 'storeTrue',
help: 'Add field name/path aliases'
});
interface Args {
name: string
preset: '' | 'mmCIF' | 'CCD' | 'BIRD' | 'CifCore'
forceDicDownload: boolean
dic: '' | 'mmCIF' | 'CifCore'
dicPath: string,
fieldNamesPath: string
targetFormat: 'typescript-molstar' | 'json-internal'
out: string,
moldataImportPath: string
addAliases: boolean
}
const args: Args = parser.parseArgs();
const FORCE_DIC_DOWNLOAD = args.forceDicDownload;
switch (args.preset) {
case 'mmCIF':
args.name = 'mmCIF';
args.dic = 'mmCIF';
args.fieldNamesPath = path.resolve(__dirname, '../../../../data/cif-field-names/mmcif-field-names.csv');
break;
case 'CCD':
args.name = 'CCD';
args.dic = 'mmCIF';
args.fieldNamesPath = path.resolve(__dirname, '../../../../data/cif-field-names/ccd-field-names.csv');
break;
case 'BIRD':
args.name = 'BIRD';
args.dic = 'mmCIF';
args.fieldNamesPath = path.resolve(__dirname, '../../../../data/cif-field-names/bird-field-names.csv');
break;
case 'CifCore':
args.name = 'CifCore';
args.dic = 'CifCore';
args.fieldNamesPath = path.resolve(__dirname, '../../../../data/cif-field-names/cif-core-field-names.csv');
break;
}
if (args.name) {
const typescript = args.targetFormat === 'typescript-molstar';
if (args.dicPath) {
runGenerateSchemaDic(args.name, args.dicPath, args.fieldNamesPath, typescript, args.out, args.moldataImportPath, args.addAliases).catch(e => {
console.error(e);
});
} else if (args.dic === 'mmCIF') {
runGenerateSchemaMmcif(args.name, args.fieldNamesPath, typescript, args.out, args.moldataImportPath, args.addAliases).catch(e => {
console.error(e);
});
} else if (args.dic === 'CifCore') {
runGenerateSchemaCifCore(args.name, args.fieldNamesPath, typescript, args.out, args.moldataImportPath, args.addAliases).catch(e => {
console.error(e);
});
}
}

View File

@@ -0,0 +1,475 @@
/**
* Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Database, Column, EnumCol, StrCol, IntCol, ListCol, FloatCol, CoordCol, MatrixCol, VectorCol } from './schema';
import { parseImportGet } from './helper';
import * as Data from '../../../mol-io/reader/cif/data-model';
import { CifFrame } from '../../../mol-io/reader/cif/data-model';
export function getFieldType(type: string, description: string, values?: string[], container?: string): Column {
switch (type) {
// mmCIF
case 'code':
case 'ucode':
case 'line':
case 'uline':
case 'text':
case 'char':
case 'uchar3':
case 'uchar1':
case 'boolean':
return values && values.length ? EnumCol(values, 'str', description) : StrCol(description);
case 'aliasname':
case 'name':
case 'idname':
case 'any':
case 'atcode':
case 'fax':
case 'phone':
case 'email':
case 'code30':
case 'seq-one-letter-code':
case 'author':
case 'orcid_id':
case 'sequence_dep':
case 'pdb_id':
case 'emd_id':
// todo, consider adding specialised fields
case 'yyyy-mm-dd':
case 'yyyy-mm-dd:hh:mm':
case 'yyyy-mm-dd:hh:mm-flex':
case 'int-range':
case 'float-range':
case 'binary':
case 'operation_expression':
case 'point_symmetry':
case '4x3_matrix':
case '3x4_matrices':
case 'point_group':
case 'point_group_helical':
case 'symmetry_operation':
case 'date_dep':
case 'url':
case 'symop':
case 'exp_data_doi':
case 'asym_id':
return StrCol(description);
case 'int':
case 'non_negative_int':
case 'positive_int':
return values && values.length ? EnumCol(values, 'int', description) : IntCol(description);
case 'float':
return FloatCol(description);
case 'ec-type':
case 'ucode-alphanum-csv':
case 'id_list':
return ListCol('str', ',', description);
case 'id_list_spc':
return ListCol('str', ' ', description);
// cif
case 'Text':
case 'Code':
case 'Complex':
case 'Symop':
case 'List':
case 'List(Real,Real)':
case 'List(Real,Real,Real,Real)':
case 'Date':
case 'Datetime':
case 'Tag':
case 'Implied':
return wrapContainer('str', ',', description, container);
case 'Real':
return wrapContainer('float', ',', description, container);
case 'Integer':
return wrapContainer('int', ',', description, container);
}
console.log(`unknown type '${type}'`);
return StrCol(description);
}
function ColFromType(type: 'int' | 'str' | 'float' | 'coord', description: string): Column {
switch (type) {
case 'int': return IntCol(description);
case 'str': return StrCol(description);
case 'float': return FloatCol(description);
case 'coord': return CoordCol(description);
}
}
function wrapContainer(type: 'int' | 'str' | 'float' | 'coord', separator: string, description: string, container?: string) {
return container && container === 'List' ? ListCol(type, separator, description) : ColFromType(type, description);
}
type FrameCategories = { [category: string]: Data.CifFrame }
type FrameLinks = { [k: string]: string }
interface FrameData {
categories: FrameCategories
links: FrameLinks
}
type Imports = Map<string, CifFrame[]>
function getImportFrames(d: Data.CifFrame, imports: Imports) {
const frames: Data.CifFrame[] = [];
if (!('import' in d.categories)) return frames;
const importGet = parseImportGet(d.categories['import'].getField('get')!.str(0));
for (const g of importGet) {
const { file, save } = g;
if (!file || !save) {
console.warn(`missing 'save' or 'file' for import in '${d.header}'`);
continue;
}
const importFrames = imports.get(file);
if (!importFrames) {
console.warn(`missing '${file}' entry in imports`);
continue;
}
const importSave = importFrames.find(id => id.header.toLowerCase() === save.toLowerCase());
if (!importSave) {
console.warn(`missing '${save}' save frame in '${file}'`);
continue;
}
frames.push(importSave);
}
return frames;
}
/** get field from given or linked category */
function getField(category: string, field: string, d: Data.CifFrame, imports: Imports, ctx: FrameData): Data.CifField|undefined {
const { categories, links } = ctx;
const cat = d.categories[category];
if (cat) {
return cat.getField(field);
} else if (d.header in links) {
const linkName = links[d.header];
if (linkName in categories) {
return getField(category, field, categories[linkName], imports, ctx);
} else {
// console.log(`link '${linkName}' not found`)
}
} else {
const importFrames = getImportFrames(d, imports);
for (const idf of importFrames) {
return getField(category, field, idf, imports, ctx);
}
}
}
function getEnums(d: Data.CifFrame, imports: Imports, ctx: FrameData) {
const value = getField('item_enumeration', 'value', d, imports, ctx);
const enums: string[] = [];
if (value) {
for (let i = 0; i < value.rowCount; ++i) {
enums.push(value.str(i));
// console.log(value.str(i))
}
return enums;
} else {
// console.log(`item_enumeration.value not found for '${d.header}'`)
}
}
function getContainer(d: Data.CifFrame, imports: Imports, ctx: FrameData) {
const value = getField('type', 'container', d, imports, ctx);
return value ? value.str(0) : undefined;
}
function getCode(d: Data.CifFrame, imports: Imports, ctx: FrameData): [string, string[] | undefined, string | undefined ] | undefined {
const code = getField('item_type', 'code', d, imports, ctx) || getField('type', 'contents', d, imports, ctx);
if (code) {
return [ code.str(0), getEnums(d, imports, ctx), getContainer(d, imports, ctx) ];
} else {
console.log(`item_type.code or type.contents not found for '${d.header}'`);
}
}
function getSubCategory(d: Data.CifFrame, imports: Imports, ctx: FrameData): string | undefined {
const value = getField('item_sub_category', 'id', d, imports, ctx);
if (value) {
return value.str(0);
}
}
function getDescription(d: Data.CifFrame, imports: Imports, ctx: FrameData): string | undefined {
const value = getField('item_description', 'description', d, imports, ctx) || getField('description', 'text', d, imports, ctx);
if (value) {
// trim (after newlines) and remove references to square brackets
return value.str(0).trim()
.replace(/(\r\n|\r|\n)([ \t]+)/g, '\n')
.replace(/(\[[1-3]\])+ element/, 'elements')
.replace(/(\[[1-3]\])+/, '');
}
}
function getAliases(d: Data.CifFrame, imports: Imports, ctx: FrameData): string[] | undefined {
const value = getField('item_aliases', 'alias_name', d, imports, ctx) || getField('alias', 'definition_id', d, imports, ctx);
return value ? value.toStringArray().map(v => v.substr(1)) : undefined;
}
const reMatrixField = /\[[1-3]\]\[[1-3]\]/;
const reVectorField = /\[[1-3]\]/;
const FORCE_INT_FIELDS = [
'_atom_site.id',
'_atom_site.auth_seq_id',
'_atom_site_anisotrop.id',
'_pdbx_struct_mod_residue.auth_seq_id',
'_struct_conf.beg_auth_seq_id',
'_struct_conf.end_auth_seq_id',
'_struct_conn.ptnr1_auth_seq_id',
'_struct_conn.ptnr2_auth_seq_id',
'_struct_sheet_range.beg_auth_seq_id',
'_struct_sheet_range.end_auth_seq_id',
];
const FORCE_MATRIX_FIELDS_MAP: { [k: string]: string } = {
'atom_site_aniso.U_11': 'U',
'atom_site_aniso.U_22': 'U',
'atom_site_aniso.U_33': 'U',
'atom_site_aniso.U_23': 'U',
'atom_site_aniso.U_13': 'U',
'atom_site_aniso.U_12': 'U',
'atom_site_aniso.U_11_su': 'U_su',
'atom_site_aniso.U_22_su': 'U_su',
'atom_site_aniso.U_33_su': 'U_su',
'atom_site_aniso.U_23_su': 'U_su',
'atom_site_aniso.U_13_su': 'U_su',
'atom_site_aniso.U_12_su': 'U_su',
};
const FORCE_MATRIX_FIELDS = Object.keys(FORCE_MATRIX_FIELDS_MAP);
const EXTRA_ALIASES: Database['aliases'] = {
'atom_site_aniso.U': [
'atom_site_anisotrop_U'
],
'atom_site_aniso.U_su': [
'atom_site_aniso_U_esd',
'atom_site_anisotrop_U_esd',
],
};
const COMMA_SEPARATED_LIST_FIELDS = [
'_atom_site.pdbx_struct_group_id',
'_chem_comp.mon_nstd_parent_comp_id',
'_diffrn_radiation.pdbx_wavelength_list',
'_diffrn_source.pdbx_wavelength_list',
'_em_diffraction.tilt_angle_list', // 20,40,50,55
'_em_entity_assembly.entity_id_list',
'_entity.pdbx_description', // Endolysin,Beta-2 adrenergic receptor
'_entity.pdbx_ec',
'_entity_poly.pdbx_strand_id', // A,B
'_entity_src_gen.pdbx_gene_src_gene', // ADRB2, ADRB2R, B2AR
'_pdbx_depui_entry_details.experimental_methods',
'_pdbx_depui_entry_details.requested_accession_types',
'_pdbx_soln_scatter_model.software_list', // INSIGHT II, HOMOLOGY, DISCOVERY, BIOPOLYMER, DELPHI
'_pdbx_soln_scatter_model.software_author_list', // MSI
'_pdbx_soln_scatter_model.entry_fitting_list', // Odd example: 'PDB CODE 1HFI, 1HCC, 1HFH, 1VCC'
'_pdbx_struct_assembly_gen.entity_inst_id',
'_pdbx_struct_assembly_gen.asym_id_list',
'_pdbx_struct_assembly_gen.auth_asym_id_list',
'_pdbx_struct_assembly_gen_depositor_info.asym_id_list',
'_pdbx_struct_assembly_gen_depositor_info.chain_id_list',
'_pdbx_struct_group_list.group_enumeration_type',
'_reflns.pdbx_diffrn_id',
'_refine.pdbx_diffrn_id',
'_reflns_shell.pdbx_diffrn_id',
'_struct_keywords.text',
];
const SPACE_SEPARATED_LIST_FIELDS = [
'_chem_comp.pdbx_subcomponent_list', // TSM DPH HIS CHF EMR
'_pdbx_soln_scatter.data_reduction_software_list', // OTOKO
'_pdbx_soln_scatter.data_analysis_software_list', // SCTPL5 GNOM
];
const SEMICOLON_SEPARATED_LIST_FIELDS = [
'_chem_comp.pdbx_synonyms' // GLYCERIN; PROPANE-1,2,3-TRIOL
];
/**
* Useful when a dictionary extension will add enum values to an existing dictionary.
* By adding them here, the dictionary extension can be tested before the added enum
* values are available in the existing dictionary.
*/
const EXTRA_ENUM_VALUES: { [k: string]: string[] } = {
};
export function generateSchema(frames: CifFrame[], imports: Imports = new Map()): Database {
const tables: Database['tables'] = {};
const aliases: Database['aliases'] = { ...EXTRA_ALIASES };
const categories: FrameCategories = {};
const links: FrameLinks = {};
const ctx = { categories, links };
// get category metadata
frames.forEach(d => {
// category definitions in mmCIF start with '_' and don't include a '.'
// category definitions in cifCore don't include a '.'
if (d.header[0] === '_' || d.header.includes('.')) return;
const categoryName = d.header.toLowerCase();
// console.log(d.header, d.categoryNames, d.categories)
let descriptionField: Data.CifField | undefined;
const categoryKeyNames = new Set<string>();
if ('category' in d.categories && 'category_key' in d.categories) {
const category = d.categories['category'];
const categoryKey = d.categories['category_key'];
if (categoryKey) {
const categoryKey_names = categoryKey.getField('name');
if (categoryKey_names) {
for (let i = 0, il = categoryKey_names.rowCount; i < il; ++i) {
categoryKeyNames.add(categoryKey_names.str(i));
}
}
}
descriptionField = category.getField('description');
if (categoryKeyNames.size === 0) {
console.log(`no key given for category '${categoryName}'`);
}
}
if ('description' in d.categories) {
descriptionField = d.categories['description'].getField('text');
}
let description = '';
if (descriptionField) {
description = descriptionField.str(0).trim()
.replace(/(\r\n|\r|\n)([ \t]+)/g, '\n'); // remove padding after newlines
} else {
console.log(`no description given for category '${categoryName}'`);
}
tables[categoryName] = { description, key: categoryKeyNames, columns: {} };
// console.log('++++++++++++++++++++++++++++++++++++++++++')
// console.log('name', categoryName)
// console.log('desc', description)
// console.log('key', categoryKeyNames)
});
// build list of links between categories
frames.forEach(d => {
if (d.header[0] !== '_' && !d.header.includes('.')) return;
categories[d.header] = d;
const item_linked = d.categories['item_linked'];
if (item_linked) {
const child_name = item_linked.getField('child_name');
const parent_name = item_linked.getField('parent_name');
if (child_name && parent_name) {
for (let i = 0; i < item_linked.rowCount; ++i) {
const childName = child_name.str(i);
const parentName = parent_name.str(i);
if (childName in links && links[childName] !== parentName) {
console.log(`${childName} linked to ${links[childName]}, ignoring link to ${parentName}`);
}
links[childName] = parentName;
}
}
}
});
// get field data
Object.keys(categories).forEach(fullName => {
const d = categories[fullName];
if (!d) {
console.log(`'${fullName}' not found, moving on`);
return;
}
const categoryName = d.header.substring(d.header[0] === '_' ? 1 : 0, d.header.indexOf('.'));
const itemName = d.header.substring(d.header.indexOf('.') + 1);
let fields: { [k: string]: Column };
if (categoryName in tables) {
fields = tables[categoryName].columns;
tables[categoryName].key.add(itemName);
} else if (categoryName.toLowerCase() in tables) {
// take case from category name in 'field' data as it is better if data is from cif dictionaries
tables[categoryName] = tables[categoryName.toLowerCase()];
fields = tables[categoryName].columns;
} else {
console.log(`category '${categoryName}' has no metadata`);
fields = {};
tables[categoryName] = {
description: '',
key: new Set(),
columns: fields
};
}
const itemAliases = getAliases(d, imports, ctx);
if (itemAliases) aliases[`${categoryName}.${itemName}`] = itemAliases;
const description = getDescription(d, imports, ctx) || '';
// need to use regex to check for matrix or vector items
// as sub_category assignment is missing for some entries
const subCategory = getSubCategory(d, imports, ctx);
if (subCategory === 'cartesian_coordinate' || subCategory === 'fractional_coordinate') {
fields[itemName] = CoordCol(description);
} else if (FORCE_INT_FIELDS.includes(d.header)) {
fields[itemName] = IntCol(description);
console.log(`forcing int: ${d.header}`);
} else if (FORCE_MATRIX_FIELDS.includes(d.header)) {
fields[itemName] = FloatCol(description);
fields[FORCE_MATRIX_FIELDS_MAP[d.header]] = MatrixCol(3, 3, description);
console.log(`forcing matrix: ${d.header}`);
} else if (subCategory === 'matrix') {
fields[itemName.replace(reMatrixField, '')] = MatrixCol(3, 3, description);
} else if (subCategory === 'vector') {
fields[itemName.replace(reVectorField, '')] = VectorCol(3, description);
} else {
if (itemName.match(reMatrixField)) {
fields[itemName.replace(reMatrixField, '')] = MatrixCol(3, 3, description);
console.log(`${d.header} should have 'matrix' _item_sub_category.id`);
} else if (itemName.match(reVectorField)) {
fields[itemName.replace(reVectorField, '')] = VectorCol(3, description);
console.log(`${d.header} should have 'vector' _item_sub_category.id`);
} else {
const code = getCode(d, imports, ctx);
if (code) {
let fieldType = getFieldType(code[0], description, code[1], code[2]);
if (fieldType.type === 'str') {
if (COMMA_SEPARATED_LIST_FIELDS.includes(d.header)) {
fieldType = ListCol('str', ',', description);
console.log(`forcing comma separated: ${d.header}`);
} else if (SPACE_SEPARATED_LIST_FIELDS.includes(d.header)) {
fieldType = ListCol('str', ' ', description);
console.log(`forcing space separated: ${d.header}`);
} else if (SEMICOLON_SEPARATED_LIST_FIELDS.includes(d.header)) {
fieldType = ListCol('str', ';', description);
console.log(`forcing space separated: ${d.header}`);
}
}
if (d.header in EXTRA_ENUM_VALUES) {
if (fieldType.type === 'enum') {
fieldType.values.push(...EXTRA_ENUM_VALUES[d.header]);
} else {
console.warn(`expected enum: ${d.header}`);
}
}
fields[itemName] = fieldType;
} else {
fields[itemName] = StrCol(description);
// console.log(`could not determine code for '${d.header}'`)
}
}
}
});
return { tables, aliases };
}

View File

@@ -0,0 +1,151 @@
/**
* Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Database, Filter, Column } from './schema';
import { indentString } from '../../../mol-util/string';
import { FieldPath } from '../../../mol-io/reader/cif/schema';
function header (name: string, info: string, moldataImportPath: string) {
return `/**
* Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated '${name}' schema file. ${info}
*
* @author molstar/ciftools package
*/
import { Database, Column } from '${moldataImportPath}/db';
import Schema = Column.Schema;`;
}
function footer (name: string) {
return `
export type ${name}_Schema = typeof ${name}_Schema;
export interface ${name}_Database extends Database<${name}_Schema> {};`;
}
function getTypeShorthands(schema: Database, fields?: Filter) {
const types = new Set<string>();
Object.keys(schema.tables).forEach(table => {
if (fields && !fields[table]) return;
const { columns } = schema.tables[table];
Object.keys(columns).forEach(columnName => {
if (fields && !fields[table][columnName]) return;
types.add(schema.tables[table].columns[columnName].type);
});
});
const shorthands: string[] = [];
types.forEach(type => {
switch (type) {
case 'str': shorthands.push('const str = Schema.str;'); break;
case 'int': shorthands.push('const int = Schema.int;'); break;
case 'float': shorthands.push('const float = Schema.float;'); break;
case 'coord': shorthands.push('const coord = Schema.coord;'); break;
case 'enum': shorthands.push('const Aliased = Schema.Aliased;'); break;
case 'matrix': shorthands.push('const Matrix = Schema.Matrix;'); break;
case 'vector': shorthands.push('const Vector = Schema.Vector;'); break;
case 'list': shorthands.push('const List = Schema.List;'); break;
}
});
return shorthands.join('\n');
}
function getTypeDef(c: Column): string {
switch (c.type) {
case 'str': return 'str';
case 'int': return 'int';
case 'float': return 'float';
case 'coord': return 'coord';
case 'enum':
return `Aliased<'${c.values.map(v => v.replace(/'/g, '\\\'')).join(`' | '`)}'>(${c.subType})`;
case 'matrix':
return `Matrix(${c.rows}, ${c.columns})`;
case 'vector':
return `Vector(${c.length})`;
case 'list':
if (c.subType === 'int') {
return `List('${c.separator}', x => parseInt(x, 10))`;
} else if (c.subType === 'float' || c.subType === 'coord') {
return `List('${c.separator}', x => parseFloat(x))`;
} else {
return `List('${c.separator}', x => x)`;
}
}
}
const reSafePropertyName = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
function safePropertyString(name: string) { return name.match(reSafePropertyName) ? name : `'${name}'`; }
function doc(description: string, spacesCount: number) {
const spaces = ' '.repeat(spacesCount);
return [
`${spaces}/**`,
`${indentString(description, 1, `${spaces} * `)}`.replace(/ +\n/g, '\n'),
`${spaces} */`
].join('\n');
}
export function generate (name: string, info: string, schema: Database, fields: Filter | undefined, moldataImportPath: string, addAliases: boolean) {
const codeLines: string[] = [];
if (fields) {
Object.keys(fields).forEach(table => {
if (table in schema.tables) {
const schemaTable = schema.tables[table];
Object.keys(fields[table]).forEach(column => {
if (!(column in schemaTable.columns)) {
console.log(`filter field '${table}.${column}' not found in schema`);
}
});
} else {
console.log(`filter category '${table}' not found in schema`);
}
});
}
codeLines.push(`export const ${name}_Schema = {`);
Object.keys(schema.tables).forEach(table => {
if (fields && !fields[table]) return;
const { description, columns } = schema.tables[table];
if (description) codeLines.push(doc(description, 4));
codeLines.push(` ${safePropertyString(table)}: {`);
Object.keys(columns).forEach(columnName => {
if (fields && !fields[table][columnName]) return;
const c = columns[columnName];
const typeDef = getTypeDef(c);
if (c.description) codeLines.push(doc(c.description, 8));
codeLines.push(` ${safePropertyString(columnName)}: ${typeDef},`);
});
codeLines.push(' },');
});
codeLines.push('};');
if (addAliases) {
codeLines.push('');
codeLines.push(`export const ${name}_Aliases = {`);
Object.keys(schema.aliases).forEach(path => {
const [ table, columnName ] = path.split('.');
if (fields && !fields[table]) return;
if (fields && !fields[table][columnName]) return;
const filteredAliases = new Set<string>();
schema.aliases[path].forEach(p => {
if (!FieldPath.equal(p, path)) filteredAliases.add(FieldPath.canonical(p));
});
if (filteredAliases.size === 0) return;
codeLines.push(` ${safePropertyString(path)}: [`);
filteredAliases.forEach(alias => {
codeLines.push(` '${alias}',`);
});
codeLines.push(' ],');
});
codeLines.push('};');
}
return `${header(name, info, moldataImportPath)}\n\n${getTypeShorthands(schema, fields)}\n\n${codeLines.join('\n')}\n${footer(name)}`;
}

View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
export type Import = { save?: string, file?: string }
export function parseImportGet(s: string): Import[] {
// [{'save':hi_ang_Fox_coeffs 'file':templ_attr.cif} {'save':hi_ang_Fox_c0 'file':templ_enum.cif}]
// [{"file":'templ_enum.cif' "save":'H_M_ref'}]
return s.trim().substring(2, s.length - 2).split(/}[ \n\t]*{/g).map(s => {
const save = s.match(/('save'|"save"):([^ \t\n]+)/);
const file = s.match(/('file'|"file"):([^ \t\n]+)/);
return {
save: save ? save[0].substr(7).replace(/['"]/g, '') : undefined,
file: file ? file[0].substr(7).replace(/['"]/g, '') : undefined
};
});
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
export interface Database {
tables: { [ tableName: string ]: Table }
aliases: { [ path: string ]: string[] }
}
export interface Table {
description: string
key: Set<string>
columns: { [ columnName: string ]: Column }
}
export type Column = IntCol | StrCol | FloatCol | CoordCol | EnumCol | VectorCol | MatrixCol | ListCol
type BaseCol = { description: string }
export type IntCol = { type: 'int' } & BaseCol
export function IntCol(description: string): IntCol { return { type: 'int', description }; }
export type StrCol = { type: 'str' } & BaseCol
export function StrCol(description: string): StrCol { return { type: 'str', description }; }
export type FloatCol = { type: 'float' } & BaseCol
export function FloatCol(description: string): FloatCol { return { type: 'float', description }; }
export type CoordCol = { type: 'coord' } & BaseCol
export function CoordCol(description: string): CoordCol { return { type: 'coord', description }; }
export type EnumCol = { type: 'enum', subType: 'int' | 'str', values: string[] } & BaseCol
export function EnumCol(values: string[], subType: 'int' | 'str', description: string): EnumCol {
return { type: 'enum', description, values, subType };
}
export type VectorCol = { type: 'vector', length: number } & BaseCol
export function VectorCol(length: number, description: string): VectorCol {
return { type: 'vector', description, length };
}
export type MatrixCol = { type: 'matrix', rows: number, columns: number } & BaseCol
export function MatrixCol(columns: number, rows: number, description: string): MatrixCol {
return { type: 'matrix', description, columns, rows };
}
export type ListCol = { type: 'list', subType: 'int' | 'str' | 'float' | 'coord', separator: string } & BaseCol
export function ListCol(subType: 'int' | 'str' | 'float' | 'coord', separator: string, description: string): ListCol {
return { type: 'list', description, separator, subType };
}
export type Filter = { [ table: string ]: { [ column: string ]: true } }
export function mergeFilters (...filters: Filter[]) {
const n = filters.length;
const mergedFilter: Filter = {};
const fields: Map<string, number> = new Map();
filters.forEach(filter => {
Object.keys(filter).forEach(category => {
Object.keys(filter[ category ]).forEach(field => {
const key = `${category}.${field}`;
const value = fields.get(key) || 0;
fields.set(key, value + 1);
});
});
});
fields.forEach((v, k) => {
if (v !== n) return;
const [categoryName, fieldName] = k.split('.');
if (categoryName in mergedFilter) {
mergedFilter[categoryName][fieldName] = true;
} else {
mergedFilter[categoryName] = { fieldName: true };
}
});
return mergedFilter;
}

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env node
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import * as argparse from 'argparse';
import * as fs from 'fs';
import * as path from 'path';
import fetch from 'node-fetch';
import { UniqueArray } from '../../mol-data/generic';
const LIPIDS_DIR = path.resolve(__dirname, '../../../../build/lipids/');
const MARTINI_LIPIDS_PATH = path.resolve(LIPIDS_DIR, 'martini_lipids.itp');
const MARTINI_LIPIDS_URL = 'http://www.cgmartini.nl/images/parameters/lipids/Collections/martini_v2.0_lipids_all_201506.itp';
async function ensureAvailable(path: string, url: string) {
if (FORCE_DOWNLOAD || !fs.existsSync(path)) {
const name = url.substr(url.lastIndexOf('/') + 1);
console.log(`downloading ${name}...`);
const data = await fetch(url);
if (!fs.existsSync(LIPIDS_DIR)) {
fs.mkdirSync(LIPIDS_DIR);
}
fs.writeFileSync(path, await data.text());
console.log(`done downloading ${name}`);
}
}
async function ensureLipidsAvailable() { await ensureAvailable(MARTINI_LIPIDS_PATH, MARTINI_LIPIDS_URL); }
const extraLipids = ['DMPC'];
async function run(out: string) {
await ensureLipidsAvailable();
const lipidsItpStr = fs.readFileSync(MARTINI_LIPIDS_PATH, 'utf8');
const lipids = UniqueArray.create<string>();
const reLipid = /\[moleculetype\]\n; molname nrexcl\n +([a-zA-Z]{3,5})/g;
let m: RegExpExecArray | null;
while ((m = reLipid.exec(lipidsItpStr)) !== null) {
const v = m[0].substr(m[0].lastIndexOf(' ') + 1);
UniqueArray.add(lipids, v, v);
}
for (const v of extraLipids) {
UniqueArray.add(lipids, v, v);
}
const lipidNames = JSON.stringify(lipids.array);
if (out) {
const output = `/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated lipid params file. Names extracted from Martini FF lipids itp.
*
* @author molstar/lipid-params cli
*/
export const LipidNames = new Set(${lipidNames.replace(/"/g, "'").replace(/,/g, ', ')});
`;
fs.writeFileSync(out, output);
} else {
console.log(lipidNames);
}
}
const parser = new argparse.ArgumentParser({
addHelp: true,
description: 'Create lipid params (from martini lipids itp)'
});
parser.addArgument([ '--out', '-o' ], {
help: 'Generated lipid params output path, if not given printed to stdout'
});
parser.addArgument([ '--forceDownload', '-f' ], {
action: 'storeTrue',
help: 'Force download of martini lipids itp'
});
interface Args {
out: string
forceDownload: boolean
}
const args: Args = parser.parseArgs();
const FORCE_DOWNLOAD = args.forceDownload;
run(args.out || '').catch(e => {
console.error(e);
});

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env node
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as _ from '../../mol-plugin-state/transforms'
import * as _ from '../../mol-plugin-state/transforms';
import { StateTransformer, StateObject } from '../../mol-state';
import { StringBuilder } from '../../mol-util';
import * as fs from 'fs';
@@ -13,7 +14,7 @@ import { PluginContext } from '../../mol-plugin/context';
import { ParamDefinition } from '../../mol-util/param-definition';
// force the transform to be evaluated
_.StateTransforms.Data.Download.id
_.StateTransforms.Data.Download.id;
// Empty plugin context
const ctx = new PluginContext({
@@ -32,7 +33,7 @@ function writeTransformer(t: StateTransformer) {
StringBuilder.write(builder, `## <a name="${t.id.replace('.', '-')}"></a>${t.id} :: ${typeToString(t.definition.from)} -> ${typeToString(t.definition.to)}`);
StringBuilder.newline(builder);
if (t.definition.display.description) {
StringBuilder.write(builder, `*${t.definition.display.description}*`)
StringBuilder.write(builder, `*${t.definition.display.description}*`);
StringBuilder.newline(builder);
}
StringBuilder.newline(builder);
@@ -48,7 +49,7 @@ function writeTransformer(t: StateTransformer) {
StringBuilder.write(builder, `\`\`\`js\n${JSON.stringify(ParamDefinition.getDefaultValues(params), null, 2)}\n\`\`\``);
StringBuilder.newline(builder);
}
StringBuilder.write(builder, '----------------------------')
StringBuilder.write(builder, '----------------------------');
StringBuilder.newline(builder);
}
@@ -62,7 +63,7 @@ transformers.forEach(t => {
StringBuilder.newline(builder);
});
StringBuilder.newline(builder);
StringBuilder.write(builder, '----------------------------')
StringBuilder.write(builder, '----------------------------');
StringBuilder.newline(builder);
transformers.forEach(t => writeTransformer(t));

View File

@@ -22,9 +22,12 @@ function paramInfo(param: PD.Any, offset: number): string {
case 'color-list': return `A list of colors as 0xrrggbb`;
case 'vec3': return `3D vector [x, y, z]`;
case 'mat4': return `4x4 transformation matrix`;
case 'url': return `URL couple with unique identifier`;
case 'file': return `JavaScript File Handle`;
case 'file-list': return `JavaScript FileList Handle`;
case 'select': return `One of ${oToS(param.options)}`;
case 'value-ref': return `Reference to a runtime defined value.`;
case 'data-ref': return `Reference to a computed data value.`;
case 'text': return 'String';
case 'interval': return `Interval [min, max]`;
case 'group': return `Object with:\n${getParams(param.params, offset + 2)}`;

View File

@@ -4,19 +4,19 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as util from 'util'
import * as fs from 'fs'
import fetch from 'node-fetch'
import * as util from 'util';
import * as fs from 'fs';
import fetch from 'node-fetch';
require('util.promisify').shim();
import { CIF } from '../../mol-io/reader/cif'
import { Progress } from '../../mol-task'
import { CIF } from '../../mol-io/reader/cif';
import { Progress } from '../../mol-task';
const readFileAsync = util.promisify(fs.readFile);
async function readFile(path: string) {
if (path.match(/\.bcif$/)) {
const input = await readFileAsync(path)
const input = await readFileAsync(path);
const data = new Uint8Array(input.byteLength);
for (let i = 0; i < input.byteLength; i++) data[i] = input[i];
return data;

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env node
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
@@ -5,11 +6,11 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as argparse from 'argparse'
import * as argparse from 'argparse';
require('util.promisify').shim();
import { CifFrame } from '../../mol-io/reader/cif'
import { Model, Structure, StructureElement, Unit, StructureProperties, UnitRing } from '../../mol-model/structure'
import { CifFrame } from '../../mol-io/reader/cif';
import { Model, Structure, StructureElement, Unit, StructureProperties, UnitRing, Trajectory } from '../../mol-model/structure';
// import { Run, Progress } from '../../mol-task'
import { OrderedSet } from '../../mol-data/int';
import { openCif, downloadCif } from './helpers';
@@ -18,6 +19,7 @@ import { trajectoryFromMmCIF } from '../../mol-model-formats/structure/mmcif';
import { Sequence } from '../../mol-model/sequence';
import { ModelSecondaryStructure } from '../../mol-model-formats/structure/property/secondary-structure';
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
import { Task } from '../../mol-task';
async function downloadFromPdb(pdb: string) {
@@ -32,30 +34,32 @@ export async function readCifFile(path: string) {
}
export function atomLabel(model: Model, aI: number) {
const { atoms, residues, chains, residueAtomSegments, chainAtomSegments } = model.atomicHierarchy
const { label_atom_id } = atoms
const { label_comp_id, label_seq_id } = residues
const { label_asym_id } = chains
const rI = residueAtomSegments.index[aI]
const cI = chainAtomSegments.index[aI]
return `${label_asym_id.value(cI)} ${label_comp_id.value(rI)} ${label_seq_id.value(rI)} ${label_atom_id.value(aI)}`
const { atoms, residues, chains, residueAtomSegments, chainAtomSegments } = model.atomicHierarchy;
const { label_atom_id, label_comp_id } = atoms;
const { label_seq_id } = residues;
const { label_asym_id } = chains;
const rI = residueAtomSegments.index[aI];
const cI = chainAtomSegments.index[aI];
return `${label_asym_id.value(cI)} ${label_comp_id.value(aI)} ${label_seq_id.value(rI)} ${label_atom_id.value(aI)}`;
}
export function residueLabel(model: Model, rI: number) {
const { residues, chains, residueAtomSegments, chainAtomSegments } = model.atomicHierarchy
const { label_comp_id, label_seq_id } = residues
const { label_asym_id } = chains
const cI = chainAtomSegments.index[residueAtomSegments.offsets[rI]]
return `${label_asym_id.value(cI)} ${label_comp_id.value(rI)} ${label_seq_id.value(rI)}`
const { atoms, residues, chains, residueAtomSegments, chainAtomSegments } = model.atomicHierarchy;
const { label_comp_id } = atoms;
const { label_seq_id } = residues;
const { label_asym_id } = chains;
const aI = residueAtomSegments.offsets[rI];
const cI = chainAtomSegments.index[aI];
return `${label_asym_id.value(cI)} ${label_comp_id.value(aI)} ${label_seq_id.value(rI)}`;
}
export function printSecStructure(model: Model) {
console.log('\nSecondary Structure\n=============');
const { residues } = model.atomicHierarchy;
const secondaryStructure = ModelSecondaryStructure.Provider.get(model);
if (!secondaryStructure) return
if (!secondaryStructure) return;
const { key, elements } = secondaryStructure
const { key, elements } = secondaryStructure;
const count = residues._rowCount;
let rI = 0;
while (rI < count) {
@@ -95,15 +99,17 @@ export function printBonds(structure: Structure, showIntra: boolean, showInter:
for (const unit of structure.units) {
if (!Unit.isAtomic(unit)) continue;
for (const pairBonds of bonds.getConnectedUnits(unit)) {
for (const pairBonds of bonds.getConnectedUnits(unit.id)) {
if (!pairBonds.areUnitsOrdered || pairBonds.edgeCount === 0) continue;
const { unitA, unitB } = pairBonds;
console.log(`${pairBonds.unitA.id} - ${pairBonds.unitB.id}: ${pairBonds.edgeCount} bond(s)`);
const { unitA, unitB, edgeCount } = pairBonds;
const uA = structure.unitMap.get(unitA);
const uB = structure.unitMap.get(unitB);
console.log(`${unitA} - ${unitB}: ${edgeCount} bond(s)`);
for (const aI of pairBonds.connectedIndices) {
for (const bond of pairBonds.getEdges(aI)) {
console.log(`${atomLabel(unitA.model, unitA.elements[aI])} -- ${atomLabel(unitB.model, unitB.elements[bond.indexB])}`);
console.log(`${atomLabel(uA.model, uA.elements[aI])} -- ${atomLabel(uB.model, uB.elements[bond.indexB])}`);
}
}
}
@@ -116,8 +122,8 @@ export function printSequence(model: Model) {
const { byEntityKey } = model.sequence;
for (const key of Object.keys(byEntityKey)) {
const { sequence, entityId } = byEntityKey[+key];
const { seqId, compId } = sequence
console.log(`${entityId} (${sequence.kind} ${seqId.value(0)} (offset ${sequence.offset}), ${seqId.value(seqId.rowCount - 1)}) (${compId.value(0)}, ${compId.value(compId.rowCount - 1)})`);
const { seqId, compId } = sequence;
console.log(`${entityId} (${sequence.kind} ${seqId.value(0)}, ${seqId.value(seqId.rowCount - 1)}) (${compId.value(0)}, ${compId.value(compId.rowCount - 1)})`);
console.log(`${Sequence.getSequenceString(sequence)}`);
}
console.log();
@@ -132,7 +138,7 @@ export function printRings(structure: Structure) {
for (let i = 0, _i = Math.min(5, all.length); i < _i; i++) {
fps[fps.length] = UnitRing.fingerprint(unit, all[i]);
}
if (all.length > 5) fps.push('...')
if (all.length > 5) fps.push('...');
console.log(`Unit ${unit.id}, ${all.length} ring(s), ${byFingerprint.size} different fingerprint(s).\n ${fps.join(', ')}`);
}
console.log();
@@ -171,8 +177,8 @@ export function printUnits(structure: Structure) {
export function printSymmetryInfo(model: Model) {
console.log('\nSymmetry Info\n=============');
const symmetry = ModelSymmetry.Provider.get(model)
if (!symmetry) return
const symmetry = ModelSymmetry.Provider.get(model);
if (!symmetry) return;
const { size, anglesInRadians } = symmetry.spacegroup.cell;
console.log(`Spacegroup: ${symmetry.spacegroup.name} size: ${Vec3.toString(size)} angles: ${Vec3.toString(anglesInRadians)}`);
console.log(`Assembly names: ${symmetry.assemblies.map(a => a.id).join(', ')}`);
@@ -180,10 +186,11 @@ export function printSymmetryInfo(model: Model) {
console.log(`NCS operators: ${symmetry.ncsOperators && symmetry.ncsOperators.map(a => a.name).join(', ')}`);
}
export function printModelStats(models: ReadonlyArray<Model>) {
export async function printModelStats(models: Trajectory) {
console.log('\nModels\n=============');
for (const m of models) {
for (let i = 0; i < models.frameCount; i++) {
const m = await Task.resolveInContext(models.getFrameAtIndex(i));
if (m.coarseHierarchy.isDefined) {
console.log(`${m.label} ${m.modelNum}: ${m.atomicHierarchy.atoms._rowCount} atom(s), ${m.coarseHierarchy.spheres.count} sphere(s), ${m.coarseHierarchy.gaussians.count} gaussian(s)`);
} else {
@@ -195,7 +202,7 @@ export function printModelStats(models: ReadonlyArray<Model>) {
export async function getModelsAndStructure(frame: CifFrame) {
const models = await trajectoryFromMmCIF(frame).run();
const structure = Structure.ofModel(models[0]);
const structure = Structure.ofModel(models.representative);
return { models, structure };
}
@@ -203,17 +210,17 @@ async function run(frame: CifFrame, args: Args) {
const { models, structure } = await getModelsAndStructure(frame);
if (args.models) printModelStats(models);
if (args.seq) printSequence(models[0]);
if (args.seq) printSequence(models.representative);
if (args.units) printUnits(structure);
if (args.sym) printSymmetryInfo(models[0]);
if (args.sym) printSymmetryInfo(models.representative);
if (args.rings) printRings(structure);
if (args.intraBonds) printBonds(structure, true, false);
if (args.interBonds) printBonds(structure, false, true);
if (args.sec) printSecStructure(models[0]);
if (args.sec) printSecStructure(models.representative);
}
async function runDL(pdb: string, args: Args) {
const mmcif = await downloadFromPdb(pdb)
const mmcif = await downloadFromPdb(pdb);
run(mmcif, args);
}
@@ -255,5 +262,5 @@ interface Args {
}
const args: Args = parser.parseArgs();
if (args.download) runDL(args.download, args)
else if (args.file) runFile(args.file, args)
if (args.download) runDL(args.download, args);
else if (args.file) runFile(args.file, args);

View File

@@ -1,46 +1,44 @@
#!/usr/bin/env node
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as fs from 'fs'
import * as argparse from 'argparse'
import * as util from 'util'
import * as fs from 'fs';
import * as argparse from 'argparse';
import * as util from 'util';
import { VolumeData, VolumeIsoValue } from '../../mol-model/volume'
import { downloadCif } from './helpers'
import { CIF } from '../../mol-io/reader/cif'
import { DensityServer_Data_Database } from '../../mol-io/reader/cif/schema/density-server';
import { Volume } from '../../mol-model/volume';
import { downloadCif } from './helpers';
import { CIF } from '../../mol-io/reader/cif';
import { Table } from '../../mol-data/db';
import { StringBuilder } from '../../mol-util';
import { Task } from '../../mol-task';
import { createVolumeIsosurfaceMesh } from '../../mol-repr/volume/isosurface';
import { Theme } from '../../mol-theme/theme';
import { volumeFromDensityServerData } from '../../mol-model-formats/volume/density-server';
import { volumeFromDensityServerData, DscifFormat } from '../../mol-model-formats/volume/density-server';
require('util.promisify').shim();
const writeFileAsync = util.promisify(fs.writeFile);
type Volume = { source: DensityServer_Data_Database, volume: VolumeData }
async function getVolume(url: string): Promise<Volume> {
const cif = await downloadCif(url, true);
const data = CIF.schema.densityServer(cif.blocks[1]);
return { source: data, volume: await volumeFromDensityServerData(data).run() };
return await volumeFromDensityServerData(data).run();
}
function print(data: Volume) {
const { volume_data_3d_info } = data.source;
function print(volume: Volume) {
if (!DscifFormat.is(volume.sourceData)) return;
const { volume_data_3d_info } = volume.sourceData.data;
const row = Table.getRow(volume_data_3d_info, 0);
console.log(row);
console.log(data.volume.cell);
console.log(data.volume.dataStats);
console.log(data.volume.fractionalBox);
console.log(volume.grid.transform);
console.log(volume.grid.stats);
}
async function doMesh(data: Volume, filename: string) {
const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, Theme.createEmpty(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
async function doMesh(volume: Volume, filename: string) {
const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, volume, Theme.createEmpty(), { isoValue: Volume.IsoValue.absolute(1.5) } )).run();
console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
// Export the mesh in OBJ format.

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AlphaOrbitalsExample } from '.';
import { ParameterControls } from '../../mol-plugin-ui/controls/parameters';
import { useBehavior } from '../../mol-plugin-ui/hooks/use-behavior';
import { PluginContextContainer } from '../../mol-plugin-ui/plugin';
export function mountControls(orbitals: AlphaOrbitalsExample, parent: Element) {
ReactDOM.render(<PluginContextContainer plugin={orbitals.plugin}>
<Controls orbitals={orbitals} />
</PluginContextContainer>, parent);
}
function Controls({ orbitals }: { orbitals: AlphaOrbitalsExample }) {
const params = useBehavior(orbitals.params);
const values = useBehavior(orbitals.state);
return <ParameterControls params={params as any} values={values} onChangeValues={(vs: any) => orbitals.state.next(vs)} />;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Mol* Alpha Orbitals Example</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#app {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
#controls {
position: absolute;
left: 8px;
top: 8px;
width: 300px;
}
</style>
<link rel="stylesheet" type="text/css" href="molstar.css" />
<script type="text/javascript" src="./index.js"></script>
</head>
<body>
<div id="app"></div>
<div id='controls'></div>
<script>
AlphaOrbitalsExample.init('app')
</script>
</body>
</html>

View File

@@ -0,0 +1,213 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { SphericalBasisOrder } from '../../extensions/alpha-orbitals/spherical-functions';
import { BasisAndOrbitals, CreateOrbitalDensityVolume, CreateOrbitalRepresentation3D, CreateOrbitalVolume, StaticBasisAndOrbitals } from '../../extensions/alpha-orbitals/transforms';
import { createPluginAsync } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { PluginStateObject } from '../../mol-plugin-state/objects';
import { PluginConfig } from '../../mol-plugin/config';
import { PluginContext } from '../../mol-plugin/context';
import { StateObjectSelector, StateTransformer } from '../../mol-state';
import { Color } from '../../mol-util/color';
import { ColorNames } from '../../mol-util/color/names';
import { ParamDefinition } from '../../mol-util/param-definition';
import { mountControls } from './controls';
import { DemoMoleculeSDF, DemoOrbitals } from './example-data';
import { BehaviorSubject } from 'rxjs';
import { debounceTime, skip } from 'rxjs/operators';
import './index.html';
import { Basis, AlphaOrbital } from '../../extensions/alpha-orbitals/data-model';
import { PluginCommands } from '../../mol-plugin/commands';
import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
require('mol-plugin-ui/skin/light.scss');
interface DemoInput {
moleculeSdf: string,
basis: Basis,
order: SphericalBasisOrder,
orbitals: AlphaOrbital[]
}
interface Params {
show: { name: 'orbital', params: { index: number } } | { name: 'density', params: {} },
isoValue: number,
gpuSurface: boolean
}
type Selectors = {
type: 'orbital',
volume: StateObjectSelector<PluginStateObject.Volume.Data, typeof CreateOrbitalVolume>,
positive: StateObjectSelector<PluginStateObject.Volume.Representation3D, typeof CreateOrbitalRepresentation3D>
negative: StateObjectSelector<PluginStateObject.Volume.Representation3D, typeof CreateOrbitalRepresentation3D>
} | {
type: 'density',
volume: StateObjectSelector<PluginStateObject.Volume.Data, typeof CreateOrbitalDensityVolume>,
positive: StateObjectSelector<PluginStateObject.Volume.Representation3D, typeof CreateOrbitalRepresentation3D>
}
export class AlphaOrbitalsExample {
plugin: PluginContext;
async init(target: string | HTMLElement) {
this.plugin = await createPluginAsync(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,
showControls: false
},
controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' },
},
config: [
[PluginConfig.Viewport.ShowExpand, false],
[PluginConfig.Viewport.ShowControls, false],
[PluginConfig.Viewport.ShowSelectionMode, false],
[PluginConfig.Viewport.ShowAnimation, false],
]
});
this.plugin.managers.interactivity.setProps({ granularity: 'element' });
if (!canComputeGrid3dOnGPU(this.plugin.canvas3d?.webgl)) {
PluginCommands.Toast.Show(this.plugin, {
title: 'Error',
message: `Browser/device does not support required WebGL extension (OES_texture_float).`
});
return;
}
this.load({
moleculeSdf: DemoMoleculeSDF,
...DemoOrbitals
});
mountControls(this, document.getElementById('controls')!);
}
readonly params = new BehaviorSubject<ParamDefinition.For<Params>>({} as any);
readonly state = new BehaviorSubject<Params>({ show: { name: 'orbital', params: { index: 32 } }, isoValue: 1, gpuSurface: false });
private selectors?: Selectors = void 0;
private basis?: StateObjectSelector<BasisAndOrbitals> = void 0;
private currentParams: Params = { ...this.state.value };
private clearVolume() {
if (!this.selectors) return;
const v = this.selectors.volume;
this.selectors = void 0;
return this.plugin.build().delete(v).commit();
}
private async syncVolume() {
if (!this.basis?.isOk) return;
const state = this.state.value;
if (state.show.name !== this.selectors?.type) {
await this.clearVolume();
}
const update = this.plugin.build();
if (state.show.name === 'orbital') {
if (!this.selectors) {
const volume = update
.to(this.basis)
.apply(CreateOrbitalVolume, { index: state.show.params.index });
const positive = volume.apply(CreateOrbitalRepresentation3D, this.volumeParams('positive', ColorNames.blue)).selector;
const negative = volume.apply(CreateOrbitalRepresentation3D, this.volumeParams('negative', ColorNames.red)).selector;
this.selectors = { type: 'orbital', volume: volume.selector, positive, negative };
} else {
const index = state.show.params.index;
update.to(this.selectors.volume).update(CreateOrbitalVolume, () => ({ index }));
}
} else {
if (!this.selectors) {
const volume = update
.to(this.basis)
.apply(CreateOrbitalDensityVolume);
const positive = volume.apply(CreateOrbitalRepresentation3D, this.volumeParams('positive', ColorNames.blue)).selector;
this.selectors = { type: 'density', volume: volume.selector, positive };
}
}
await update.commit();
if (this.currentParams.gpuSurface !== this.state.value.gpuSurface) {
await this.setIsovalue();
}
this.currentParams = this.state.value;
}
private setIsovalue() {
if (!this.selectors) return;
this.currentParams = this.state.value;
const update = this.plugin.build();
update.to(this.selectors.positive).update(this.volumeParams('positive', ColorNames.blue));
if (this.selectors?.type === 'orbital') {
update.to(this.selectors.negative).update(this.volumeParams('negative', ColorNames.red));
}
return update.commit();
}
private volumeParams(kind: 'positive' | 'negative', color: Color): StateTransformer.Params<typeof CreateOrbitalRepresentation3D> {
return {
alpha: 0.85,
color,
directVolume: this.state.value.gpuSurface,
kind,
relativeIsovalue: this.state.value.isoValue,
pickable: false,
xrayShaded: true
};
}
async load(input: DemoInput) {
await this.plugin.clear();
const data = await this.plugin.builders.data.rawData({ data: input.moleculeSdf }, { state: { isGhost: true } });
const trajectory = await this.plugin.builders.structure.parseTrajectory(data, 'mol');
const model = await this.plugin.builders.structure.createModel(trajectory);
const structure = await this.plugin.builders.structure.createStructure(model);
const all = await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'all');
if (all) await this.plugin.builders.structure.representation.addRepresentation(all, { type: 'ball-and-stick', color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } });
this.basis = await this.plugin.build().toRoot()
.apply(StaticBasisAndOrbitals, { basis: input.basis, order: input.order, orbitals: input.orbitals })
.commit();
await this.syncVolume();
this.params.next({
show: ParamDefinition.MappedStatic('orbital', {
'orbital': ParamDefinition.Group({
index: ParamDefinition.Numeric(32, { min: 0, max: input.orbitals.length - 1 }, { immediateUpdate: true, isEssential: true }),
}),
'density': ParamDefinition.EmptyGroup()
}, { cycle: true }),
isoValue: ParamDefinition.Numeric(this.currentParams.isoValue, { min: 0.5, max: 3, step: 0.1 }, { immediateUpdate: true, isEssential: false }),
gpuSurface: ParamDefinition.Boolean(this.currentParams.gpuSurface, { isHidden: true })
});
this.state.pipe(skip(1), debounceTime(1000 / 24)).subscribe(async params => {
if (params.show.name !== this.currentParams.show.name
|| (params.show.name === 'orbital' && this.currentParams.show.name === 'orbital' && params.show.params.index !== this.currentParams.show.params.index)) {
this.syncVolume();
} else if (params.isoValue !== this.currentParams.isoValue || params.gpuSurface !== this.currentParams.gpuSurface) {
this.setIsovalue();
}
});
}
}
(window as any).AlphaOrbitalsExample = new AlphaOrbitalsExample();

View File

@@ -18,13 +18,13 @@ export const StripedResidues = CustomElementProperty.create<number>({
for (let i = 0, _i = model.atomicHierarchy.atoms._rowCount; i < _i; i++) {
map.set(i as ElementIndex, residueIndex[i] % 2);
}
return map;
return { value: map };
},
coloring: {
getColor(e) { return e === 0 ? Color(0xff0000) : Color(0x0000ff) },
getColor(e) { return e === 0 ? Color(0xff0000) : Color(0x0000ff); },
defaultColor: Color(0x777777)
},
getLabel(e) {
return e === 0 ? 'Odd stripe' : 'Even stripe'
return e === 0 ? 'Odd stripe' : 'Even stripe';
}
})
});

View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { PluginUIComponent } from '../../mol-plugin-ui/base';
import * as React from 'react';
export class CustomToastMessage extends PluginUIComponent {
render() {
return <>
Custom <i>Toast</i> content. No timeout.
</>;
}
}

View File

@@ -41,7 +41,7 @@
display: block;
}
</style>
<link rel="stylesheet" type="text/css" href="app.css" />
<link rel="stylesheet" type="text/css" href="molstar.css" />
<script type="text/javascript" src="./index.js"></script>
</head>
<body>
@@ -50,18 +50,18 @@
<input type='text' id='url' placeholder='url' />
<input type='text' id='assemblyId' placeholder='assembly id' />
<select id='format'>
<option value='cif' selected>CIF</option>
<option value='mmcif' selected>mmCIF</option>
<option value='pdb'>PDB</option>
</select>
</div>
<div id="app"></div>
<script>
<script>
function $(id) { return document.getElementById(id); }
var pdbId = '1grm', assemblyId= '1';
var url = 'https://www.ebi.ac.uk/pdbe/static/entry/' + pdbId + '_updated.cif';
var format = 'cif';
var format = 'mmcif';
$('url').value = url;
$('url').onchange = function (e) { url = e.target.value; }
$('assemblyId').value = assemblyId;
@@ -69,15 +69,8 @@
$('format').value = format;
$('format').onchange = function (e) { format = e.target.value; }
// var url = 'https://www.ebi.ac.uk/pdbe/entry-files/pdb' + pdbId + '.ent';
// var format = 'pdb';
// var assemblyId = 'deposited';
BasicMolStarWrapper.init('app' /** or document.getElementById('app') */);
BasicMolStarWrapper.setBackground(0xffffff);
// BasicMolStarWrapper.load({ url: url, format: format, assemblyId: assemblyId });
// BasicMolStarWrapper.toggleSpin();
addControl('Load Asym Unit', () => BasicMolStarWrapper.load({ url: url, format: format }));
addControl('Load Assembly', () => BasicMolStarWrapper.load({ url: url, format: format, assemblyId: assemblyId }));
@@ -86,14 +79,14 @@
addHeader('Camera');
addControl('Toggle Spin', () => BasicMolStarWrapper.toggleSpin());
addSeparator();
addHeader('Animation');
// adjust this number to make the animation faster or slower
// requires to "restart" the animation if changed
BasicMolStarWrapper.animate.modelIndex.maxFPS = 30;
BasicMolStarWrapper.animate.modelIndex.targetFps = 30;
addControl('Play To End', () => BasicMolStarWrapper.animate.modelIndex.onceForward());
addControl('Play To Start', () => BasicMolStarWrapper.animate.modelIndex.onceBackward());
@@ -104,6 +97,7 @@
addHeader('Misc');
addControl('Apply Stripes', () => BasicMolStarWrapper.coloring.applyStripes());
addControl('Default Coloring', () => BasicMolStarWrapper.coloring.applyDefault());
addHeader('Interactivity');
addControl('Highlight seq_id=7', () => BasicMolStarWrapper.interactivity.highlightOn());
@@ -114,7 +108,7 @@
addControl('Static Superposition', () => BasicMolStarWrapper.tests.staticSuperposition());
addControl('Dynamic Superposition', () => BasicMolStarWrapper.tests.dynamicSuperposition());
addControl('Validation Tooltip', () => BasicMolStarWrapper.tests.toggleValidationTooltip());
addControl('Show Toasts', () => BasicMolStarWrapper.tests.showToasts());
addControl('Hide Toasts', () => BasicMolStarWrapper.tests.hideToasts());

View File

@@ -0,0 +1,168 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { EmptyLoci } from '../../mol-model/loci';
import { StructureSelection } from '../../mol-model/structure';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginContext } from '../../mol-plugin/context';
import { Script } from '../../mol-script/script';
import { Color } from '../../mol-util/color';
import { StripedResidues } from './coloring';
import { CustomToastMessage } from './controls';
import './index.html';
import { buildStaticSuperposition, dynamicSuperpositionTest, StaticSuperpositionTestData } from './superposition';
import { PDBeStructureQualityReport } from '../../extensions/pdbe';
import { Asset } from '../../mol-util/assets';
require('mol-plugin-ui/skin/light.scss');
type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string }
class BasicWrapper {
plugin: PluginContext;
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,
showControls: false
},
controls: {
// left: 'none'
}
},
components: {
remoteState: 'none'
}
});
this.plugin.representation.structure.themes.colorThemeRegistry.add(StripedResidues.colorThemeProvider!);
this.plugin.managers.lociLabels.addProvider(StripedResidues.labelProvider!);
this.plugin.customModelProperties.register(StripedResidues.propertyProvider, true);
}
async load({ url, format = 'mmcif', isBinary = false, assemblyId = '' }: LoadParams) {
await this.plugin.clear();
const data = await this.plugin.builders.data.download({ url: Asset.Url(url), isBinary }, { state: { isGhost: true } });
const trajectory = await this.plugin.builders.structure.parseTrajectory(data, format);
await this.plugin.builders.structure.hierarchy.applyPreset(trajectory, 'default', {
structure: assemblyId ? {
name: 'assembly',
params: { id: assemblyId }
} : {
name: 'model',
params: { }
},
showUnitcell: false,
representationPreset: 'auto'
});
}
setBackground(color: number) {
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: props => { props.renderer.backgroundColor = Color(color); } });
}
toggleSpin() {
if (!this.plugin.canvas3d) return;
PluginCommands.Canvas3D.SetSettings(this.plugin, {
settings: props => {
props.trackball.spin = !props.trackball.spin;
}
});
if (!this.plugin.canvas3d.props.trackball.spin) PluginCommands.Camera.Reset(this.plugin, {});
}
private animateModelIndexTargetFps() {
return Math.max(1, this.animate.modelIndex.targetFps | 0);
}
animate = {
modelIndex: {
targetFps: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'loop', params: {} } }); },
stop: () => this.plugin.managers.animation.stop()
}
}
coloring = {
applyStripes: async () => {
this.plugin.dataTransaction(async () => {
for (const s of this.plugin.managers.structure.hierarchy.current.structures) {
await this.plugin.managers.structure.component.updateRepresentationsTheme(s.components, { color: StripedResidues.propertyProvider.descriptor.name as any });
}
});
},
applyDefault: async () => {
this.plugin.dataTransaction(async () => {
for (const s of this.plugin.managers.structure.hierarchy.current.structures) {
await this.plugin.managers.structure.component.updateRepresentationsTheme(s.components, { color: 'default' });
}
});
}
}
interactivity = {
highlightOn: () => {
const data = this.plugin.managers.structure.hierarchy.current.structures[0]?.cell.obj?.data;
if (!data) return;
const seq_id = 7;
const sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
'residue-test': Q.core.rel.eq([Q.struct.atomProperty.macromolecular.label_seq_id(), seq_id]),
'group-by': Q.struct.atomProperty.macromolecular.residueKey()
}), data);
const loci = StructureSelection.toLociWithSourceUnits(sel);
this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci });
},
clearHighlight: () => {
this.plugin.managers.interactivity.lociHighlights.highlightOnly({ loci: EmptyLoci });
}
}
tests = {
staticSuperposition: async () => {
await this.plugin.clear();
return buildStaticSuperposition(this.plugin, StaticSuperpositionTestData);
},
dynamicSuperposition: async () => {
await this.plugin.clear();
return dynamicSuperpositionTest(this.plugin, ['1tqn', '2hhb', '4hhb'], 'HEM');
},
toggleValidationTooltip: () => {
return this.plugin.state.updateBehavior(PDBeStructureQualityReport, params => { params.showTooltip = !params.showTooltip; });
},
showToasts: () => {
PluginCommands.Toast.Show(this.plugin, {
title: 'Toast 1',
message: 'This is an example text, timeout 3s',
key: 'toast-1',
timeoutMs: 3000
});
PluginCommands.Toast.Show(this.plugin, {
title: 'Toast 2',
message: CustomToastMessage,
key: 'toast-2'
});
},
hideToasts: () => {
PluginCommands.Toast.Hide(this.plugin, { key: 'toast-1' });
PluginCommands.Toast.Hide(this.plugin, { key: 'toast-2' });
}
}
}
(window as any).BasicMolStarWrapper = new BasicWrapper();

View File

@@ -0,0 +1,119 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Mat4 } from '../../mol-math/linear-algebra';
import { QueryContext, StructureSelection } from '../../mol-model/structure';
import { superpose } from '../../mol-model/structure/structure/util/superposition';
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { PluginContext } from '../../mol-plugin/context';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { Expression } from '../../mol-script/language/expression';
import { compile } from '../../mol-script/runtime/query/compiler';
import { StateObjectRef } from '../../mol-state';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { Asset } from '../../mol-util/assets';
export type SuperpositionTestInput = {
pdbId: string,
auth_asym_id: string,
matrix: Mat4
}[];
export function buildStaticSuperposition(plugin: PluginContext, src: SuperpositionTestInput) {
return plugin.dataTransaction(async () => {
for (const s of src) {
const { structure } = await loadStructure(plugin, `https://www.ebi.ac.uk/pdbe/static/entry/${s.pdbId}_updated.cif`, 'mmcif');
await transform(plugin, structure, s.matrix);
const chain = await plugin.builders.structure.tryCreateComponentFromExpression(structure, chainSelection(s.auth_asym_id), `Chain ${s.auth_asym_id}`);
if (chain) await plugin.builders.structure.representation.addRepresentation(chain, { type: 'cartoon' });
}
});
}
export const StaticSuperpositionTestData: SuperpositionTestInput = [
{
pdbId: '1aj5', auth_asym_id: 'A', matrix: Mat4.identity()
},
{
pdbId: '1df0', auth_asym_id: 'B', matrix: Mat4.ofRows([
[0.406, 0.879, 0.248, -200.633],
[0.693, -0.473, 0.544, 73.403],
[0.596, -0.049, -0.802, -14.209],
[0, 0, 0, 1]])
},
{
pdbId: '1dvi', auth_asym_id: 'A', matrix: Mat4.ofRows([
[-0.053, -0.077, 0.996, -45.633],
[-0.312, 0.949, 0.057, -12.255],
[-0.949, -0.307, -0.074, 53.562],
[0, 0, 0, 1]])
}
];
export function dynamicSuperpositionTest(plugin: PluginContext, src: string[], comp_id: string) {
return plugin.dataTransaction(async () => {
for (const s of src) {
await loadStructure(plugin, `https://www.ebi.ac.uk/pdbe/static/entry/${s}_updated.cif`, 'mmcif');
}
const pivot = MS.struct.filter.first([
MS.struct.generator.atomGroups({
'residue-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.label_comp_id(), comp_id]),
'group-by': MS.struct.atomProperty.macromolecular.residueKey()
})
]);
const rest = MS.struct.modifier.exceptBy({
0: MS.struct.modifier.includeSurroundings({
0: pivot,
radius: 5
}),
by: pivot
});
const query = compile<StructureSelection>(pivot);
const xs = plugin.managers.structure.hierarchy.current.structures;
const selections = xs.map(s => StructureSelection.toLociWithCurrentUnits(query(new QueryContext(s.cell.obj!.data))));
const transforms = superpose(selections);
await siteVisual(plugin, xs[0].cell, pivot, rest);
for (let i = 1; i < selections.length; i++) {
await transform(plugin, xs[i].cell, transforms[i - 1].bTransform);
await siteVisual(plugin, xs[i].cell, pivot, rest);
}
});
}
async function siteVisual(plugin: PluginContext, s: StateObjectRef<PSO.Molecule.Structure>, pivot: Expression, rest: Expression) {
const center = await plugin.builders.structure.tryCreateComponentFromExpression(s, pivot, 'pivot');
if (center) await plugin.builders.structure.representation.addRepresentation(center, { type: 'ball-and-stick', color: 'residue-name' });
const surr = await plugin.builders.structure.tryCreateComponentFromExpression(s, rest, 'rest');
if (surr) await plugin.builders.structure.representation.addRepresentation(surr, { type: 'ball-and-stick', color: 'uniform', size: 'uniform', sizeParams: { value: 0.33 } });
}
async function loadStructure(plugin: PluginContext, url: string, format: BuiltInTrajectoryFormat, assemblyId?: string) {
const data = await plugin.builders.data.download({ url: Asset.Url(url) });
const trajectory = await plugin.builders.structure.parseTrajectory(data, format);
const model = await plugin.builders.structure.createModel(trajectory);
const structure = await plugin.builders.structure.createStructure(model, assemblyId ? { name: 'assembly', params: { id: assemblyId } } : void 0);
return { data, trajectory, model, structure };
}
function chainSelection(auth_asym_id: string) {
return MS.struct.generator.atomGroups({
'chain-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.auth_asym_id(), auth_asym_id])
});
}
function transform(plugin: PluginContext, s: StateObjectRef<PSO.Molecule.Structure>, matrix: Mat4) {
const b = plugin.state.data.build().to(s)
.insert(StateTransforms.Model.TransformStructureConformation, { transform: { name: 'matrix', params: { data: matrix, transpose: false } } });
return plugin.runTask(plugin.state.data.updateTree(b));
}

View File

@@ -4,12 +4,12 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Table } from '../../mol-data/db'
import { CifWriter } from '../../mol-io/writer/cif'
import * as S from './schemas'
import { Table } from '../../mol-data/db';
import { CifWriter } from '../../mol-io/writer/cif';
import * as S from './schemas';
// import { getCategoryInstanceProvider } from './utils'
export default function create(allData: any) {
export function createMapping(allData: any) {
const mols = Object.keys(allData);
const enc = CifWriter.createEncoder();
enc.startDataBlock(mols[0]);

View File

@@ -4,21 +4,21 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Column } from '../../mol-data/db'
import { Column } from '../../mol-data/db';
import Type = Column.Schema
export const Sources = {
id: Type.str,
count: Type.int
}
};
export type Sources = typeof Sources
export const Base = {
id: Type.str,
identifier: Type.str,
mapping_group_id: Type.int
}
};
export type Base = typeof Base
export const mapping = {
@@ -36,17 +36,17 @@ export const mapping = {
end_label_seq_id: Type.int,
end_auth_seq_id: Type.int,
pdbx_end_PDB_ins_code: Type.str
}
};
export type mapping = typeof mapping
export const Pfam = {
description: Type.str
}
};
export type Pfam = typeof Pfam
export const InterPro = {
name: Type.str
}
};
export type InterPro = typeof InterPro
export const CATH = {
@@ -56,32 +56,32 @@ export const CATH = {
identifier: Type.str,
class: Type.str,
topology: Type.str,
}
};
export type CATH = typeof CATH
export const EC = {
accepted_name: Type.str,
reaction: Type.str,
systematic_name: Type.str
}
};
export type EC = typeof EC
export const UniProt = {
name: Type.str
}
};
export type UniProt = typeof UniProt
export const SCOP = {
sccs: Type.str,
description: Type.str
}
};
export type SCOP = typeof SCOP
export const GO = {
category: Type.str,
definition: Type.str,
name: Type.str
}
};
export type GO = typeof GO
export const categories = {
@@ -92,4 +92,4 @@ export const categories = {
UniProt,
SCOP,
GO
}
};

View File

@@ -4,9 +4,9 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import * as express from 'express'
import fetch from 'node-fetch'
import createMapping from './mapping'
import express from 'express';
import fetch from 'node-fetch';
import { createMapping } from './mapping';
async function getMappings(id: string) {
const data = await fetch(`https://www.ebi.ac.uk/pdbe/api/mappings/${id}`);
@@ -19,7 +19,7 @@ let PORT = process.env.port || 1338;
const app = express();
const PREFIX = '/'
const PREFIX = '/';
app.get(`${PREFIX}/:id`, async (req, res) => {
try {
@@ -41,7 +41,7 @@ app.get(`${PREFIX}/:id`, async (req, res) => {
app.get(`${PREFIX}`, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Usage: /pdb_id, e.g. /1tqn');
})
});
app.listen(PORT);

View File

@@ -4,8 +4,8 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import fetch from 'node-fetch'
import createMapping from './mapping'
import fetch from 'node-fetch';
import { createMapping } from './mapping';
(async function () {
const data = await fetch('https://www.ebi.ac.uk/pdbe/api/mappings/1tqn?pretty=true');

View File

@@ -12,18 +12,18 @@
}
#app {
position: absolute;
left: 160px;
top: 100px;
width: 600px;
height: 600px;
border: 1px solid #ccc;
width: 100%;
height: 100%;
}
#controls {
position: absolute;
width: 150px;
top: 100px;
left: 780px;
bottom: 100px;
right: 50px;
z-index: 10;
font-family: sans-serif;
font-size: smaller;
}
#controls > button {
@@ -38,21 +38,21 @@
display: block;
}
</style>
<link rel="stylesheet" type="text/css" href="app.css" />
<link rel="stylesheet" type="text/css" href="molstar.css" />
<script type="text/javascript" src="./index.js"></script>
</head>
<body>
<div id='controls'></div>
<div id="app"></div>
<script>
<script>
LightingDemo.init('app')
LightingDemo.load({ url: 'https://files.rcsb.org/download/1M07.cif', assemblyId: '1' })
LightingDemo.load({ url: 'https://models.rcsb.org/4KTC.bcif', assemblyId: '1' }, 5, 1.3)
addHeader('Example PDB IDs');
addControl('1M07', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/1M07.cif', assemblyId: '1' }));
addControl('6HY0', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/6HY0.cif', assemblyId: '1' }));
addControl('6QVK', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/6QVK.cif', assemblyId: '1' }));
addControl('1RB8', () => LightingDemo.load({ url: 'https://files.rcsb.org/download/1RB8.cif', assemblyId: '1' }));
addControl('4KTC', () => LightingDemo.load({ url: 'https://models.rcsb.org/4KTC.bcif', assemblyId: '1' }, 5, 1.3));
addControl('5FJ5', () => LightingDemo.load({ url: 'https://models.rcsb.org/5FJ5.bcif', assemblyId: '1' }, 8, 1.8));
addControl('1UPN', () => LightingDemo.load({ url: 'https://models.rcsb.org/1UPN.bcif', assemblyId: '1' }, 7, 1.6));
addControl('1RB8', () => LightingDemo.load({ url: 'https://models.rcsb.org/1RB8.bcif', assemblyId: '1' }, 6, 1.3));
addSeparator()

View File

@@ -0,0 +1,129 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Canvas3DProps } from '../../mol-canvas3d/canvas3d';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginContext } from '../../mol-plugin/context';
import './index.html';
import { Asset } from '../../mol-util/assets';
require('mol-plugin-ui/skin/light.scss');
type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string }
type _Preset = Pick<Canvas3DProps, 'multiSample' | 'postprocessing' | 'renderer'>
type Preset = { [K in keyof _Preset]: Partial<_Preset[K]> }
const Canvas3DPresets = {
illustrative: <Preset> {
multiSample: {
mode: 'temporal' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15 } },
outline: { name: 'on', params: { scale: 1, threshold: 0.1 } }
},
renderer: {
style: { name: 'flat', params: {} }
}
},
occlusion: <Preset> {
multiSample: {
mode: 'temporal' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15 } },
outline: { name: 'off', params: { } }
},
renderer: {
style: { name: 'matte', params: {} }
}
},
standard: <Preset> {
multiSample: {
mode: 'off' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusion: { name: 'off', params: { } },
outline: { name: 'off', params: { } }
},
renderer: {
style: { name: 'matte', params: {} }
}
}
};
type Canvas3DPreset = keyof typeof Canvas3DPresets
class LightingDemo {
plugin: PluginContext;
private radius = 5;
private bias = 1.1;
private preset: Canvas3DPreset = 'illustrative';
init(target: string | HTMLElement) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec(),
layout: {
initial: {
isExpanded: false,
showControls: false
},
controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }
}
});
this.setPreset('illustrative');
}
setPreset(preset: Canvas3DPreset) {
const props = Canvas3DPresets[preset];
if (props.postprocessing.occlusion?.name === 'on') {
props.postprocessing.occlusion.params.radius = this.radius;
props.postprocessing.occlusion.params.bias = this.bias;
}
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: {
...props,
multiSample: {
...this.plugin.canvas3d!.props.multiSample,
...props.multiSample
},
renderer: {
...this.plugin.canvas3d!.props.renderer,
...props.renderer
},
postprocessing: {
...this.plugin.canvas3d!.props.postprocessing,
...props.postprocessing
},
}});
}
async load({ url, format = 'mmcif', isBinary = true, assemblyId = '' }: LoadParams, radius: number, bias: number) {
await this.plugin.clear();
const data = await this.plugin.builders.data.download({ url: Asset.Url(url), isBinary }, { state: { isGhost: true } });
const trajectory = await this.plugin.builders.structure.parseTrajectory(data, format);
const model = await this.plugin.builders.structure.createModel(trajectory);
const structure = await this.plugin.builders.structure.createStructure(model, assemblyId ? { name: 'assembly', params: { id: assemblyId } } : { name: 'model', params: { } });
const polymer = await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer');
if (polymer) await this.plugin.builders.structure.representation.addRepresentation(polymer, { type: 'spacefill', color: 'illustrative' });
const ligand = await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'ligand');
if (ligand) await this.plugin.builders.structure.representation.addRepresentation(ligand, { type: 'ball-and-stick', color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } });
this.radius = radius;
this.bias = bias;
this.setPreset(this.preset);
}
}
(window as any).LightingDemo = new LightingDemo();

View File

@@ -9,6 +9,7 @@ import { CustomElementProperty } from '../../mol-model-props/common/custom-eleme
import { Model, ElementIndex, ResidueIndex } from '../../mol-model/structure';
import { Color } from '../../mol-util/color';
import { CustomProperty } from '../../mol-model-props/common/custom-property';
import { Asset } from '../../mol-util/assets';
const EvolutionaryConservationPalette: Color[] = [
[255, 255, 129], // insufficient
@@ -30,9 +31,9 @@ export const EvolutionaryConservation = CustomElementProperty.create<number>({
type: 'static',
async getData(model: Model, ctx: CustomProperty.Context) {
const id = model.entryId.toLowerCase();
const url = `https://proteopedia.org/cgi-bin/cnsrf?${id}`
const json = await ctx.fetch({ url, type: 'json' }).runInContext(ctx.runtime)
const annotations = (json && json.residueAnnotations) || [];
const url = Asset.getUrlAsset(ctx.assetManager, `https://proteopedia.org/cgi-bin/cnsrf?${id}`);
const json = await ctx.assetManager.resolve(url, 'json').runInContext(ctx.runtime);
const annotations = json.data?.residueAnnotations || [];
const conservationMap = new Map<string, number>();
@@ -58,7 +59,7 @@ export const EvolutionaryConservation = CustomElementProperty.create<number>({
}
}
return map;
return { value: map, assets: [json] };
},
coloring: {
getColor(e: number) {
@@ -68,7 +69,7 @@ export const EvolutionaryConservation = CustomElementProperty.create<number>({
defaultColor: EvolutionaryConservationDefaultColor
},
getLabel(e) {
if (e === 10) return `Evolutionary Conservation: InsufficientData`;
if (e === 10) return `Evolutionary Conservation: Insufficient Data`;
return e ? `Evolutionary Conservation: ${e}` : void 0;
}
});

View File

@@ -11,58 +11,58 @@ import { Unit, StructureProperties, StructureElement, Bond } from '../../mol-mod
import { Color } from '../../mol-util/color';
import { Location } from '../../mol-model/location';
import { ColorTheme, LocationColor } from '../../mol-theme/color';
import { ParamDefinition as PD } from '../../mol-util/param-definition'
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { ThemeDataContext } from '../../mol-theme/theme';
import { Column } from '../../mol-data/db';
const Description = 'Gives every chain a color from a list based on its `asym_id` value.'
const Description = 'Gives every chain a color from a list based on its `asym_id` value.';
export function createProteopediaCustomTheme(colors: number[]) {
const ProteopediaCustomColorThemeParams = {
colors: PD.ObjectList({ color: PD.Color(Color(0xffffff)) }, ({ color }) => Color.toHexString(color),
{ defaultValue: colors.map(c => ({ color: Color(c) })) })
}
};
type ProteopediaCustomColorThemeParams = typeof ProteopediaCustomColorThemeParams
function getChainIdColorThemeParams(ctx: ThemeDataContext) {
return ProteopediaCustomColorThemeParams // TODO return copy
return ProteopediaCustomColorThemeParams; // TODO return copy
}
function getAsymId(unit: Unit): StructureElement.Property<string> {
switch (unit.kind) {
case Unit.Kind.Atomic:
return StructureProperties.chain.label_asym_id
return StructureProperties.chain.label_asym_id;
case Unit.Kind.Spheres:
case Unit.Kind.Gaussians:
return StructureProperties.coarse.asym_id
return StructureProperties.coarse.asym_id;
}
}
function addAsymIds(map: Map<string, number>, data: Column<string>) {
let j = map.size
let j = map.size;
for (let o = 0, ol = data.rowCount; o < ol; ++o) {
const k = data.value(o)
const k = data.value(o);
if (!map.has(k)) {
map.set(k, j)
j += 1
map.set(k, j);
j += 1;
}
}
}
function ProteopediaCustomColorTheme(ctx: ThemeDataContext, props: PD.Values<ProteopediaCustomColorThemeParams>): ColorTheme<ProteopediaCustomColorThemeParams> {
let color: LocationColor
let color: LocationColor;
const colors = props.colors, colorCount = colors.length, defaultColor = colors[0].color;
if (ctx.structure) {
const l = StructureElement.Location.create(ctx.structure)
const { models } = ctx.structure
const asymIdSerialMap = new Map<string, number>()
const l = StructureElement.Location.create(ctx.structure);
const { models } = ctx.structure;
const asymIdSerialMap = new Map<string, number>();
for (let i = 0, il = models.length; i < il; ++i) {
const m = models[i]
addAsymIds(asymIdSerialMap, m.atomicHierarchy.chains.label_asym_id)
const m = models[i];
addAsymIds(asymIdSerialMap, m.atomicHierarchy.chains.label_asym_id);
if (m.coarseHierarchy.isDefined) {
addAsymIds(asymIdSerialMap, m.coarseHierarchy.spheres.asym_id)
addAsymIds(asymIdSerialMap, m.coarseHierarchy.gaussians.asym_id)
addAsymIds(asymIdSerialMap, m.coarseHierarchy.spheres.asym_id);
addAsymIds(asymIdSerialMap, m.coarseHierarchy.gaussians.asym_id);
}
}
@@ -72,16 +72,16 @@ export function createProteopediaCustomTheme(colors: number[]) {
const o = asymIdSerialMap.get(asym_id(location)) || 0;
return colors[o % colorCount].color;
} else if (Bond.isLocation(location)) {
const asym_id = getAsymId(location.aUnit)
l.unit = location.aUnit
l.element = location.aUnit.elements[location.aIndex]
const asym_id = getAsymId(location.aUnit);
l.unit = location.aUnit;
l.element = location.aUnit.elements[location.aIndex];
const o = asymIdSerialMap.get(asym_id(l)) || 0;
return colors[o % colorCount].color;
}
return defaultColor
}
return defaultColor;
};
} else {
color = () => defaultColor
color = () => defaultColor;
}
return {
@@ -91,7 +91,7 @@ export function createProteopediaCustomTheme(colors: number[]) {
props,
description: Description,
legend: undefined
}
};
}
return {
@@ -102,5 +102,5 @@ export function createProteopediaCustomTheme(colors: number[]) {
getParams: getChainIdColorThemeParams,
defaultValues: PD.getDefaultValues(ProteopediaCustomColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
}
};
}

View File

@@ -4,12 +4,11 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { ResidueIndex, Model } from '../../mol-model/structure';
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
import { Model, ResidueIndex } from '../../mol-model/structure';
import { PluginContext } from '../../mol-plugin/context';
import { StructureRepresentationRegistry } from '../../mol-repr/structure/registry';
import { ColorTheme } from '../../mol-theme/color';
import { PolymerType } from '../../mol-model/structure/model/types';
import { PluginContext } from '../../mol-plugin/context';
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
export interface ModelInfo {
hetResidues: { name: string, indices: ResidueIndex[] }[],
@@ -54,13 +53,12 @@ export namespace ModelInfo {
const hetMap = new Map<string, ModelInfo['hetResidues'][0]>();
for (let rI = 0 as ResidueIndex; rI < residueCount; rI++) {
if (model.atomicHierarchy.derived.residue.polymerType[rI] !== PolymerType.NA) continue;
const cI = chainIndex[residueOffsets[rI]];
const eI = model.atomicHierarchy.index.getEntityFromChain(cI);
if (model.entities.data.type.value(eI) === 'water') continue;
const entityType = model.entities.data.type.value(eI);
if (entityType !== 'non-polymer' && entityType !== 'branched') continue;
const comp_id = model.atomicHierarchy.residues.label_comp_id.value(rI);
const comp_id = model.atomicHierarchy.atoms.label_comp_id.value(residueOffsets[rI]);
let lig = hetMap.get(comp_id);
if (!lig) {
@@ -72,7 +70,7 @@ export namespace ModelInfo {
}
const preferredAssemblyId = await pref;
const symmetry = ModelSymmetry.Provider.get(model)
const symmetry = ModelSymmetry.Provider.get(model);
return {
hetResidues: hetResidues,
@@ -86,6 +84,7 @@ export type SupportedFormats = 'cif' | 'pdb'
export interface LoadParams {
url: string,
format?: SupportedFormats,
isBinary?: boolean,
assemblyId?: string,
representationStyle?: RepresentationStyle
}

View File

@@ -48,7 +48,7 @@
width: 300px;
}
</style>
<link rel="stylesheet" type="text/css" href="app.css" />
<link rel="stylesheet" type="text/css" href="molstar.css" />
<script type="text/javascript" src="./index.js"></script>
</head>
<body>
@@ -60,11 +60,12 @@
<option value='cif' selected>CIF</option>
<option value='pdb'>PDB</option>
</select>
<input type='checkbox' id='isBinary' style="display: inline-block; width: auto" /> <label for="isBinary"> Binary</label><br />
</div>
<div id="app"></div>
<div id="volume-streaming-wrapper"></div>
<script>
// it might be a good idea to define these colors in a separate script file
// it might be a good idea to define these colors in a separate script file
var CustomColors = [0x00ff00, 0x0000ff];
// create an instance of the plugin
@@ -73,24 +74,28 @@
console.log('Wrapper version', MolStarProteopediaWrapper.VERSION_MAJOR, MolStarProteopediaWrapper.VERSION_MINOR);
function $(id) { return document.getElementById(id); }
var pdbId = '1cbs', assemblyId= 'preferred';
var url = 'https://www.ebi.ac.uk/pdbe/static/entry/' + pdbId + '_updated.cif';
var pdbId = '1cbs', assemblyId= 'preferred', isBinary = true;
var url = 'https://www.ebi.ac.uk/pdbe/entry-files/download/' + pdbId + '.bcif'
var format = 'cif';
$('url').value = url;
$('url').onchange = function (e) { url = e.target.value; }
$('assemblyId').value = assemblyId;
$('assemblyId').onchange = function (e) { assemblyId = e.target.value; }
$('format').value = format;
$('format').onchange = function (e) { format = e.target.value; }
$('isBinary').checked = isBinary;
$('isBinary').onchange = function (e) { isBinary = !!e.target.checked; };
// var url = 'https://www.ebi.ac.uk/pdbe/entry-files/pdb' + pdbId + '.ent';
// var format = 'pdb';
// var assemblyId = 'deposited';
function loadAndSnapshot(params) {
PluginWrapper.load(params).then(() => {
setTimeout(() => snapshot = PluginWrapper.plugin.state.getSnapshot({ canvas3d: false /* do not save spinning state */ }), 500);
});
}
var representationStyle = {
sequence: { coloring: 'proteopedia-custom' }, // or just { }
// sequence: { coloring: 'proteopedia-custom' }, // or just { }
hetGroups: { kind: 'ball-and-stick' }, // or 'spacefill
water: { hide: true },
snfg3d: { hide: false }
@@ -100,7 +105,7 @@
customColorList: CustomColors
});
PluginWrapper.setBackground(0xffffff);
PluginWrapper.load({ url: url, format: format, assemblyId: assemblyId, representationStyle: representationStyle });
loadAndSnapshot({ url: url, format: format, isBinary: isBinary, assemblyId: assemblyId, representationStyle: representationStyle });
PluginWrapper.toggleSpin();
PluginWrapper.events.modelInfo.subscribe(function (info) {
@@ -108,8 +113,8 @@
listHetGroups(info);
});
addControl('Load Asym Unit', () => PluginWrapper.load({ url: url, format: format }));
addControl('Load Assembly', () => PluginWrapper.load({ url: url, format: format, assemblyId: assemblyId }));
addControl('Load Asym Unit', () => loadAndSnapshot({ url: url, format: format, isBinary }));
addControl('Load Assembly', () => loadAndSnapshot({ url: url, format: format, isBinary, assemblyId: assemblyId }));
addSeparator();
@@ -135,14 +140,14 @@
// Same as "wheel icon" and Viewport options
// addControl('Clip', () => PluginWrapper.viewport.setSettings({ clip: [33, 66] }));
// addControl('Reset Clip', () => PluginWrapper.viewport.setSettings({ clip: [1, 100] }));
addSeparator();
addHeader('Animation');
// adjust this number to make the animation faster or slower
// requires to "restart" the animation if changed
PluginWrapper.animate.modelIndex.maxFPS = 30;
PluginWrapper.animate.modelIndex.targetFps = 30;
addControl('Play To End', () => PluginWrapper.animate.modelIndex.onceForward());
addControl('Play To Start', () => PluginWrapper.animate.modelIndex.onceBackward());
@@ -168,21 +173,24 @@
addControl('Init', () => PluginWrapper.experimentalData.init($('volume-streaming-wrapper')));
addControl('Remove', () => PluginWrapper.experimentalData.remove());
addSeparator();
addSeparator();
addHeader('State');
var snapshot;
addControl('Set Snapshot', () => {
snapshot = PluginWrapper.snapshot.get();
// could use JSON.stringify(snapshot) and upload the data
// const options = { data: true, behavior: false, animation: false, interactivity: false, canvas3d: false, camera: false, cameraTransition: false };
snapshot = PluginWrapper.plugin.state.getSnapshot(/** options */);
// console.log(JSON.stringify(snapshot, null, 2));
});
addControl('Restore Snapshot', () => {
if (!snapshot) return;
PluginWrapper.snapshot.set(snapshot);
});
addControl('Download Snapshot', () => {
snapshot = PluginWrapper.snapshot.download();
addControl('Download State', () => {
PluginWrapper.snapshot.download('molj');
});
addControl('Download Session', () => {
PluginWrapper.snapshot.download('molx');
});
////////////////////////////////////////////////////////
@@ -218,7 +226,7 @@
var l = document.createElement('button');
l.innerText = r.name;
l.onclick = function () {
PluginWrapper.hetGroups.focusFirst(r.name);
PluginWrapper.hetGroups.focusFirst(r.name, { doNotLabelWaters: true });
};
div.appendChild(l);
});

View File

@@ -5,34 +5,35 @@
*/
import * as ReactDOM from 'react-dom';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import './index.html'
import { PluginContext } from '../../mol-plugin/context';
import { PluginCommands } from '../../mol-plugin/commands';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { Color } from '../../mol-util/color';
import { PluginStateObject as PSO, PluginStateObject } from '../../mol-plugin-state/objects';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in';
import { StateBuilder, StateObject, StateSelection } from '../../mol-state';
import { EvolutionaryConservation } from './annotation';
import { LoadParams, SupportedFormats, RepresentationStyle, ModelInfo, StateElements } from './helpers';
import { RxEventHelper } from '../../mol-util/rx-event-helper';
import { volumeStreamingControls } from './ui/controls';
import { PluginState } from '../../mol-plugin/state';
import { Scheduler } from '../../mol-task';
import { createProteopediaCustomTheme } from './coloring';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { ColorNames } from '../../mol-util/color/names';
import { InitVolumeStreaming, CreateVolumeStreamingInfo } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
import { DefaultCanvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d';
import { Canvas3DProps, DefaultCanvas3DParams } from '../../mol-canvas3d/canvas3d';
import { createPlugin } from '../../mol-plugin';
import { DefaultPluginSpec } from '../../mol-plugin/spec';
import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
import { download } from '../../mol-util/download';
import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { CreateVolumeStreamingInfo, InitVolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginContext } from '../../mol-plugin/context';
import { PluginState } from '../../mol-plugin/state';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { StateBuilder, StateObject, StateSelection } from '../../mol-state';
import { Asset } from '../../mol-util/assets';
import { Color } from '../../mol-util/color';
import { ColorNames } from '../../mol-util/color/names';
import { getFormattedTime } from '../../mol-util/date';
require('../../mol-plugin-ui/skin/light.scss')
import { download } from '../../mol-util/download';
import { RxEventHelper } from '../../mol-util/rx-event-helper';
import { EvolutionaryConservation } from './annotation';
import { createProteopediaCustomTheme } from './coloring';
import { LoadParams, ModelInfo, RepresentationStyle, StateElements, SupportedFormats } from './helpers';
import './index.html';
import { volumeStreamingControls } from './ui/controls';
require('../../mol-plugin-ui/skin/light.scss');
class MolStarProteopediaWrapper {
static VERSION_MAJOR = 5;
static VERSION_MINOR = 0;
static VERSION_MINOR = 5;
private _ev = RxEventHelper.create();
@@ -46,7 +47,7 @@ class MolStarProteopediaWrapper {
customColorList?: number[]
}) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
animations: [
AnimateModelIndex
],
@@ -73,8 +74,8 @@ class MolStarProteopediaWrapper {
return this.plugin.state.data;
}
private download(b: StateBuilder.To<PSO.Root>, url: string) {
return b.apply(StateTransforms.Data.Download, { url, isBinary: false })
private download(b: StateBuilder.To<PSO.Root>, url: string, isBinary: boolean) {
return b.apply(StateTransforms.Data.Download, { url: Asset.Url(url), isBinary });
}
private model(b: StateBuilder.To<PSO.Data.Binary | PSO.Data.String>, format: SupportedFormats) {
@@ -89,11 +90,14 @@ class MolStarProteopediaWrapper {
private structure(assemblyId: string) {
const model = this.state.build().to(StateElements.Model);
const props = {
type: {
type: assemblyId ? {
name: 'assembly' as const,
params: { id: assemblyId || 'deposited' }
params: { id: assemblyId }
} : {
name: 'model' as const,
params: { }
}
}
};
const s = model
.apply(StateTransforms.Model.StructureFromModel, props, { ref: StateElements.Assembly });
@@ -185,7 +189,7 @@ class MolStarProteopediaWrapper {
const model = this.getObj<PluginStateObject.Molecule.Model>('model');
if (!model) return;
const info = await ModelInfo.get(this.plugin, model, checkPreferredAssembly)
const info = await ModelInfo.get(this.plugin, model, checkPreferredAssembly);
this.events.modelInfo.next(info);
return info;
}
@@ -194,8 +198,9 @@ class MolStarProteopediaWrapper {
return PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree });
}
private loadedParams: LoadParams = { url: '', format: 'cif', assemblyId: '' };
async load({ url, format = 'cif', assemblyId = 'deposited', representationStyle }: LoadParams) {
private emptyLoadedParams: LoadParams = { url: '', format: 'cif', isBinary: false, assemblyId: '' };
private loadedParams: LoadParams = { url: '', format: 'cif', isBinary: false, assemblyId: '' };
async load({ url, format = 'cif', assemblyId = '', isBinary = false, representationStyle }: LoadParams) {
let loadType: 'full' | 'update' = 'full';
const state = this.plugin.state.data;
@@ -208,7 +213,7 @@ class MolStarProteopediaWrapper {
if (loadType === 'full') {
await PluginCommands.State.RemoveObject(this.plugin, { state, ref: state.tree.root.ref });
const modelTree = this.model(this.download(state.build().toRoot(), url), format);
const modelTree = this.model(this.download(state.build().toRoot(), url, isBinary), format);
await this.applyState(modelTree);
const info = await this.doInfo(true);
const asmId = (assemblyId === 'preferred' && info && info.preferredAssemblyId) || assemblyId;
@@ -219,11 +224,14 @@ class MolStarProteopediaWrapper {
const info = await this.doInfo(true);
const asmId = (assemblyId === 'preferred' && info && info.preferredAssemblyId) || assemblyId;
const props = {
type: {
type: assemblyId ? {
name: 'assembly' as const,
params: { id: asmId || 'deposited' }
params: { id: asmId }
} : {
name: 'model' as const,
params: { }
}
}
};
tree.to(StateElements.Assembly).update(StateTransforms.Model.StructureFromModel, p => ({ ...p, ...props }));
await this.applyState(tree);
}
@@ -231,7 +239,6 @@ class MolStarProteopediaWrapper {
await this.updateStyle(representationStyle);
this.loadedParams = { url, format, assemblyId };
Scheduler.setImmediate(() => PluginCommands.Camera.Reset(this.plugin, { }));
}
async updateStyle(style?: RepresentationStyle, partial?: boolean) {
@@ -249,9 +256,7 @@ class MolStarProteopediaWrapper {
toggleSpin() {
if (!this.plugin.canvas3d) return;
const trackball = this.plugin.canvas3d.props.trackball;
const spinning = trackball.spin;
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: { trackball: { ...trackball, spin: !trackball.spin } } });
if (!spinning) PluginCommands.Camera.Reset(this.plugin, { });
}
viewport = {
@@ -264,36 +269,21 @@ class MolStarProteopediaWrapper {
camera = {
toggleSpin: () => this.toggleSpin(),
resetPosition: () => PluginCommands.Camera.Reset(this.plugin, { }),
// setClip: (options?: { distance?: number, near?: number, far?: number }) => {
// if (!options) {
// PluginCommands.Canvas3D.SetSettings(this.plugin, {
// settings: {
// cameraClipDistance: DefaultCanvas3DParams.cameraClipDistance,
// clip: DefaultCanvas3DParams.clip
// }
// });
// return;
// }
resetPosition: () => PluginCommands.Camera.Reset(this.plugin, { })
}
// options = options || { };
// const props = this.plugin.canvas3d.props;
// const clipNear = typeof options.near === 'undefined' ? props.clip[0] : options.near;
// const clipFar = typeof options.far === 'undefined' ? props.clip[1] : options.far;
// PluginCommands.Canvas3D.SetSettings(this.plugin, {
// settings: { cameraClipDistance: options.distance, clip: [clipNear, clipFar] }
// });
// }
private animateModelIndexTargetFps() {
return Math.max(1, this.animate.modelIndex.targetFps | 0);
}
animate = {
modelIndex: {
maxFPS: 8,
onceForward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }) },
onceBackward: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }) },
palindrome: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }) },
loop: () => { this.plugin.state.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }) },
stop: () => this.plugin.state.animation.stop()
targetFps: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { duration: { name: 'computed', params: { targetFps: this.animateModelIndexTargetFps() } }, mode: { name: 'loop', params: {} } }); },
stop: () => this.plugin.managers.animation.stop()
}
}
@@ -304,11 +294,6 @@ class MolStarProteopediaWrapper {
}
const state = this.state;
// const visuals = state.selectQ(q => q.ofType(PluginStateObject.Molecule.Structure.Representation3D).filter(c => c.transform.transformer === StateTransforms.Representation.StructureRepresentation3D));
// for (const v of visuals) {
// }
const tree = state.build();
const colorTheme = { name: EvolutionaryConservation.propertyProvider.descriptor.name, params: this.plugin.representation.structure.themes.colorThemeRegistry.get(EvolutionaryConservation.propertyProvider.descriptor.name).defaultValues };
@@ -353,12 +338,10 @@ class MolStarProteopediaWrapper {
PluginCommands.State.Update(this.plugin, { state: this.state, tree: update });
PluginCommands.Camera.Reset(this.plugin, { });
},
focusFirst: async (compId: string) => {
focusFirst: async (compId: string, options?: { hideLabels: boolean, doNotLabelWaters: boolean }) => {
if (!this.state.transforms.has(StateElements.Assembly)) return;
await PluginCommands.Camera.Reset(this.plugin, { });
// const asm = (this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure).data;
const update = this.state.build();
update.delete(StateElements.HetGroupFocusGroup);
@@ -372,69 +355,66 @@ class MolStarProteopediaWrapper {
const surroundings = MS.struct.modifier.includeSurroundings({ 0: core, radius: 5, 'as-whole-residues': true });
const group = update.to(StateElements.Assembly).group(StateTransforms.Misc.CreateGroup, { label: compId }, { ref: StateElements.HetGroupFocusGroup });
const asm = this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure;
const coreSel = group.apply(StateTransforms.Model.StructureSelectionFromExpression, { label: 'Core', expression: core }, { ref: StateElements.HetGroupFocus });
coreSel.apply(StateTransforms.Representation.StructureRepresentation3D, createStructureRepresentationParams(this.plugin, asm.data, {
type: 'ball-and-stick'
}));
coreSel.apply(StateTransforms.Representation.StructureRepresentation3D, createStructureRepresentationParams(this.plugin, asm.data, {
type: 'label',
typeParams: { level: 'element' }
}), { tags: ['proteopedia-labels'] });
group.apply(StateTransforms.Model.StructureSelectionFromExpression, { label: 'Core', expression: core }, { ref: StateElements.HetGroupFocus })
.apply(StateTransforms.Representation.StructureRepresentation3D, this.createCoreVisualParams());
group.apply(StateTransforms.Model.StructureSelectionFromExpression, { label: 'Surroundings', expression: surroundings })
.apply(StateTransforms.Representation.StructureRepresentation3D, this.createSurVisualParams());
// sel.apply(StateTransforms.Representation.StructureLabels3D, {
// target: { name: 'residues', params: { } },
// options: {
// ...ParamDefinition.getDefaultValues(Text.Params),
// background: true,
// backgroundMargin: 0.2,
// backgroundColor: ColorNames.snow,
// backgroundOpacity: 0.9,
// }
// });
.apply(StateTransforms.Representation.StructureRepresentation3D, createStructureRepresentationParams(this.plugin, asm.data, {
type: 'ball-and-stick',
color: 'uniform', colorParams: { value: ColorNames.gray },
size: 'uniform', sizeParams: { value: 0.33 }
}));
if (!options?.hideLabels) {
// Labels
const waters = MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.struct.atomProperty.macromolecular.entityType(), 'water']),
});
const exclude = options?.doNotLabelWaters ? MS.struct.combinator.merge([core, waters]) : core;
const onlySurroundings = MS.struct.modifier.exceptBy({ 0: surroundings, by: exclude });
group.apply(StateTransforms.Model.StructureSelectionFromExpression, { label: 'Surroundings (only)', expression: onlySurroundings })
.apply(StateTransforms.Representation.StructureRepresentation3D, createStructureRepresentationParams(this.plugin, asm.data, {
type: 'label',
typeParams: { level: 'residue' }
}), { tags: ['proteopedia-labels'] }); // the tag can later be used to toggle the labels
}
await PluginCommands.State.Update(this.plugin, { state: this.state, tree: update });
const focus = (this.state.select(StateElements.HetGroupFocus)[0].obj as PluginStateObject.Molecule.Structure).data;
const sphere = focus.boundary.sphere;
// const asmCenter = asm.boundary.sphere.center;
// const position = Vec3.sub(Vec3.zero(), sphere.center, asmCenter);
// Vec3.normalize(position, position);
// Vec3.scaleAndAdd(position, sphere.center, position, sphere.radius);
const radius = Math.max(sphere.radius, 5)
const radius = Math.max(sphere.radius, 5);
const snapshot = this.plugin.canvas3d!.camera.getFocus(sphere.center, radius);
PluginCommands.Camera.SetSnapshot(this.plugin, { snapshot, durationMs: 250 });
}
}
private createSurVisualParams() {
const asm = this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure;
return createStructureRepresentationParams(this.plugin, asm.data, {
type: 'ball-and-stick',
color: 'uniform', colorParams: { value: ColorNames.gray },
size: 'uniform', sizeParams: { value: 0.33 }
});
}
private createCoreVisualParams() {
const asm = this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure;
return createStructureRepresentationParams(this.plugin, asm.data, {
type: 'ball-and-stick'
});
}
snapshot = {
get: () => {
return this.plugin.state.getSnapshot();
get: (params?: PluginState.SnapshotParams) => {
return this.plugin.state.getSnapshot(params);
},
set: (snapshot: PluginState.Snapshot) => {
return this.plugin.state.setSnapshot(snapshot);
},
download: () => {
const json = JSON.stringify(this.plugin.state.getSnapshot(), null, 2);
const blob = new Blob([json], {type : 'application/json;charset=utf-8'});
download(blob, `mol-star_state_${(name || getFormattedTime())}.json`)
download: async (type: 'molj' | 'molx' = 'molj', params?: PluginState.SnapshotParams) => {
const data = await this.plugin.managers.snapshot.serialize({ type, params });
download(data, `mol-star_state_${getFormattedTime()}.${type}`);
},
fetch: async (url: string) => {
fetch: async (url: string, type: 'molj' | 'molx' = 'molj') => {
try {
const snapshot = await this.plugin.runTask(this.plugin.fetch({ url, type: 'json' }));
// TODO: is this OK to test for snapshots from server?
await this.plugin.state.setSnapshot(snapshot?.data?.entries?.[0]?.snapshot || snapshot);
const data = await this.plugin.runTask(this.plugin.fetch({ url, type: 'binary' }));
this.loadedParams = { ...this.emptyLoadedParams };
return await this.plugin.managers.snapshot.open(new File([data], `state.${type}`));
} catch (e) {
console.log(e);
}

View File

@@ -13,7 +13,6 @@ import { StateElements } from '../helpers';
export function volumeStreamingControls(plugin: PluginContext, parent: Element) {
ReactDOM.render(<PluginContextContainer plugin={plugin}>
<TransformUpdaterControl nodeRef={StateElements.VolumeStreaming} />
</PluginContextContainer>,
parent);
<TransformUpdaterControl nodeRef={StateElements.VolumeStreaming} />
</PluginContextContainer>, parent);
}

View File

@@ -4,7 +4,7 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Task, Progress, Scheduler, MultistepTask, chunkedSubtask } from '../mol-task'
import { Task, Progress, Scheduler, MultistepTask, chunkedSubtask } from '../mol-task';
import { now } from '../mol-util/now';
export async function test1() {
@@ -85,19 +85,19 @@ export const ms = MultistepTask('ms-task', ['step 1', 'step 2', 'step 3'], async
await step(0);
const child = Task.create('chunked', async ctx => {
const s = await chunkedSubtask(ctx, 25, { i: 0, current: 0, total: 125 }, processChunk, (ctx, s, p) => ctx.update('chunk test ' + p))
const s = await chunkedSubtask(ctx, 25, { i: 0, current: 0, total: 125 }, processChunk, (ctx, s, p) => ctx.update('chunk test ' + p));
return s.i;
});
await child.runAsChild(ctx);
await Scheduler.delay(250);
await step(1);
await chunkedSubtask(ctx, 25, { i: 0, current: 0, total: 80 }, processChunk, (ctx, s, p) => ctx.update('chunk test ' + p))
await chunkedSubtask(ctx, 25, { i: 0, current: 0, total: 80 }, processChunk, (ctx, s, p) => ctx.update('chunk test ' + p));
await Scheduler.delay(250);
await step(2);
await Scheduler.delay(250);
return p.i + 3;
})
});
export function abortingObserver(p: Progress) {

View File

@@ -0,0 +1,214 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Box3D } from '../../../mol-math/geometry';
import { Vec3 } from '../../../mol-math/linear-algebra';
import { RuntimeContext } from '../../../mol-task';
import { sphericalCollocation } from '../collocation';
import { Basis, CubeGridInfo } from '../data-model';
describe('alpha-orbitals-cubes', () => {
it('water', async () => {
const grid: CubeGridInfo = {
params: {
basis: _testBasis,
cutoffThreshold: 0,
sphericalOrder: 'cca-reverse',
boxExpand: 0,
gridSpacing: []
},
box: Box3D.create(Vec3.create(-1, -1, -1), Vec3.create(1, 1, 1)),
delta: Vec3.create(2, 2, 2),
dimensions: Vec3.create(2, 2, 2),
npoints: 8,
size: Vec3.create(2, 2, 2)
};
const matrix = await sphericalCollocation(grid, {
energy: 0,
occupancy: 0,
alpha: [-2.2623991420609075e-16, 0.6360205395000592, 0.6672122399886391, -0.3876927909355508, -1.6780131293332933e-16, 2.844782862661151e-16, 4.977960694176068e-19, -2.3945919908996803e-16]
}, RuntimeContext.Synchronous);
const expected = [-0.1451730622877498, 0.06479453956039086, -0.2777738736440713, -0.057116584776260436, 0.05929916178822645, 0.2742903371231049, -0.07221698722165386, 0.15389180241391376];
expect(matrix.length).toBe(expected.length);
for (let i = 0; i < matrix.length; i++) {
expect(Math.abs(matrix[i] - expected[i]) < 1e-6).toBe(true);
}
});
});
const _testBasis: Basis = {
'atoms': [
{
'center': [
0.025886090588624934,
0.019164790004065606,
-0.013539970104105408
] as Vec3,
'shells': [
{
'angularMomentum': [0],
'coefficients': [
[
-0.004151277818987536,
-0.02067024147993795,
-0.05150303336984537,
0.33462711739899537,
0.5621061300983125,
0.17129946969948573
]
],
'exponents': [
152.28769660788095,
27.928015215973073,
7.848374792384515,
1.1223350202705642,
0.5093846587907856,
0.24292266532510307
]
},
{
'angularMomentum': [1],
'coefficients': [
[
0.007924233646294425,
0.051441048251911314,
0.18984000600705359,
0.4049863191150474,
0.40123628611490797,
0.1051855189039082
]
],
'exponents': [
27.203421487167727,
7.09409912597673,
2.5383362605345954,
1.0610730767843852,
0.4851948916410433,
0.22938302550642545
]
}
]
},
{
'center': [
0.5082729578468134,
1.6880351220025265,
0.4963443067810461
] as Vec3,
'shells': [
{
'angularMomentum': [0],
'coefficients': [
[
0.009163596280542963,
0.04936149294292479,
0.16853830490998634,
0.37056279972195677,
0.4164915298246781,
0.13033408410772263
]
],
'exponents': [
33.710073211949485,
6.180705022740464,
1.7291385346152253,
0.5940057549921978,
0.2306698170449518,
0.09500256906284119
]
},
{
'angularMomentum': [0],
'coefficients': [
[
-0.32279868167000036,
3.209629817295221,
2.4672629224617935,
-0.048487066612842224,
-0.2611850111200143,
-0.8917817597810863,
-1.9607480081275706,
-2.203769342520311,
-0.6896328935259993
]
],
'exponents': [
10.256286070314905,
0.6227965325875392,
0.2391007667853915,
33.710073211949485,
6.180705022740464,
1.7291385346152253,
0.5940057549921978,
0.2306698170449518,
0.09500256906284119
]
}
]
},
{
'center': [
1.1367367844436005,
-0.47018519422670163,
-1.356802622574504
] as Vec3,
'shells': [
{
'angularMomentum': [0],
'coefficients': [
[
0.009163596280542963,
0.04936149294292479,
0.16853830490998634,
0.37056279972195677,
0.4164915298246781,
0.13033408410772263
]
],
'exponents': [
33.710073211949485,
6.180705022740464,
1.7291385346152253,
0.5940057549921978,
0.2306698170449518,
0.09500256906284119
]
},
{
'angularMomentum': [0],
'coefficients': [
[
-0.32279868167000036,
3.209629817295221,
2.4672629224617935,
-0.048487066612842224,
-0.2611850111200143,
-0.8917817597810863,
-1.9607480081275706,
-2.203769342520311,
-0.6896328935259993
]
],
'exponents': [
10.256286070314905,
0.6227965325875392,
0.2391007667853915,
33.710073211949485,
6.180705022740464,
1.7291385346152253,
0.5940057549921978,
0.2306698170449518,
0.09500256906284119
]
}
]
}
]
};

View File

@@ -0,0 +1,162 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Inspired by https://github.com/dgasmith/gau2grid.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Vec3 } from '../../mol-math/linear-algebra';
import { RuntimeContext } from '../../mol-task';
import { arrayMin } from '../../mol-util/array';
import { AlphaOrbital, CubeGridInfo } from './data-model';
import { normalizeBasicOrder, SphericalFunctions } from './spherical-functions';
export async function sphericalCollocation(
grid: CubeGridInfo,
orbital: AlphaOrbital,
taskCtx: RuntimeContext
) {
const { basis, sphericalOrder, cutoffThreshold } = grid.params;
let baseCount = 0;
for (const atom of basis.atoms) {
for (const shell of atom.shells) {
for (const L of shell.angularMomentum) {
if (L > 4) {
// TODO: will L > 4 be required? Would need to precompute more functions in that case.
throw new Error('Angular momentum L > 4 not supported.');
}
baseCount += 2 * L + 1;
}
}
}
const matrix = new Float32Array(grid.npoints);
let baseIndex = 0;
for (const atom of basis.atoms) {
for (const shell of atom.shells) {
let amIndex = 0;
for (const L of shell.angularMomentum) {
const alpha = normalizeBasicOrder(
L,
orbital.alpha.slice(baseIndex, baseIndex + 2 * L + 1),
sphericalOrder
);
baseIndex += 2 * L + 1;
collocationBasis(
matrix,
grid,
L,
shell.coefficients[amIndex++],
shell.exponents,
atom.center,
cutoffThreshold,
alpha
);
if (taskCtx.shouldUpdate) {
await taskCtx.update({
message: 'Computing...',
current: baseIndex,
max: baseCount,
isIndeterminate: false,
});
}
}
}
}
return matrix;
}
function collocationBasis(
matrix: Float32Array,
grid: CubeGridInfo,
L: number,
coefficients: number[],
exponents: number[],
center: Vec3,
cutoffThreshold: number,
alpha: number[]
) {
const ncoeff = exponents.length;
const sphericalFunc = SphericalFunctions[L];
const cx = center[0],
cy = center[1],
cz = center[2];
const ny = grid.dimensions[1],
nz = grid.dimensions[2];
const gdx = grid.delta[0],
gdy = grid.delta[1],
gdz = grid.delta[2];
const sx = grid.box.min[0],
sy = grid.box.min[1],
sz = grid.box.min[2];
const cutoffRadius =
cutoffThreshold > 0
? Math.sqrt(-Math.log(cutoffThreshold) / arrayMin(exponents))
: 10000;
const cutoffSquared = cutoffRadius * cutoffRadius;
const radiusBox = getRadiusBox(grid, center, cutoffRadius);
const iMin = radiusBox[0][0],
jMin = radiusBox[0][1],
kMin = radiusBox[0][2];
const iMax = radiusBox[1][0],
jMax = radiusBox[1][1],
kMax = radiusBox[1][2];
for (let i = iMin; i <= iMax; i++) {
const x = sx + gdx * i - cx;
const oX = i * ny * nz;
for (let j = jMin; j <= jMax; j++) {
const y = sy + gdy * j - cy;
const oY = oX + j * nz;
for (let k = kMin; k <= kMax; k++) {
const z = sz + gdz * k - cz;
const R2 = x * x + y * y + z * z;
if (R2 > cutoffSquared) {
continue;
}
let gaussianSum = 0;
for (let c = 0; c < ncoeff; c++) {
gaussianSum +=
coefficients[c] * Math.exp(-exponents[c] * R2);
}
const sphericalSum = L === 0 ? alpha[0] : sphericalFunc(alpha, x, y, z);
matrix[k + oY] += gaussianSum * sphericalSum;
}
}
}
}
function getRadiusBox(grid: CubeGridInfo, center: Vec3, radius: number) {
const r = Vec3.create(radius, radius, radius);
const min = Vec3.scaleAndAdd(Vec3(), center, r, -1);
const max = Vec3.add(Vec3(), center, r);
Vec3.sub(min, min, grid.box.min);
Vec3.sub(max, max, grid.box.min);
Vec3.div(min, min, grid.delta);
Vec3.floor(min, min);
Vec3.max(min, min, Vec3());
Vec3.div(max, max, grid.delta);
Vec3.ceil(max, max);
Vec3.min(max, max, Vec3.subScalar(Vec3(), grid.dimensions, 1));
return [min, max];
}

View File

@@ -0,0 +1,131 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Mat4, Tensor, Vec3 } from '../../mol-math/linear-algebra';
import { Grid } from '../../mol-model/volume';
import { SphericalBasisOrder } from './spherical-functions';
import { Box3D, RegularGrid3d } from '../../mol-math/geometry';
import { arrayMin, arrayMax, arrayRms, arrayMean } from '../../mol-util/array';
// Note: generally contracted gaussians are currently not supported.
export interface SphericalElectronShell {
exponents: number[];
angularMomentum: number[];
// number[] for each angular momentum
coefficients: number[][];
}
export interface Basis {
atoms: {
// in Bohr units!
center: Vec3;
shells: SphericalElectronShell[];
}[];
}
export interface AlphaOrbital {
energy: number;
occupancy: number;
alpha: number[];
}
export interface CubeGridComputationParams {
basis: Basis;
/**
* for each electron shell compute a cutoff radius as
* const cutoffRadius = Math.sqrt(-Math.log(cutoffThreshold) / arrayMin(exponents));
*/
cutoffThreshold: number;
sphericalOrder: SphericalBasisOrder;
boxExpand: number;
gridSpacing: number | [atomCountThreshold: number, spacing: number][];
doNotComputeIsovalues?: boolean;
}
export interface CubeGridInfo {
params: CubeGridComputationParams;
dimensions: Vec3;
box: Box3D;
size: Vec3;
npoints: number;
delta: Vec3;
}
export interface CubeGrid {
grid: Grid;
isovalues?: { negative?: number; positive?: number };
}
export function initCubeGrid(params: CubeGridComputationParams): CubeGridInfo {
const geometry = params.basis.atoms.map(a => a.center);
const { gridSpacing: spacing, boxExpand: expand } = params;
const count = geometry.length;
const box = Box3D.expand(
Box3D(),
Box3D.fromVec3Array(Box3D(), geometry),
Vec3.create(expand, expand, expand)
);
const size = Box3D.size(Vec3(), box);
const spacingThresholds =
typeof spacing === 'number' ? [[0, spacing]] : [...spacing];
spacingThresholds.sort((a, b) => b[0] - a[0]);
let s = 0.4;
for (let i = 0; i <= spacingThresholds.length; i++) {
s = spacingThresholds[i][1];
if (spacingThresholds[i][0] <= count) break;
}
const dimensions = Vec3.ceil(Vec3(), Vec3.scale(Vec3(), size, 1 / s));
return {
params,
box,
dimensions,
size,
npoints: dimensions[0] * dimensions[1] * dimensions[2],
delta: Vec3.div(Vec3(), size, Vec3.subScalar(Vec3(), dimensions, 1)),
};
}
const BohrToAngstromFactor = 0.529177210859;
export function createGrid(gridInfo: RegularGrid3d, values: Float32Array, axisOrder: number[]) {
const boxSize = Box3D.size(Vec3(), gridInfo.box);
const boxOrigin = Vec3.clone(gridInfo.box.min);
Vec3.scale(boxSize, boxSize, BohrToAngstromFactor);
Vec3.scale(boxOrigin, boxOrigin, BohrToAngstromFactor);
const scale = Mat4.fromScaling(
Mat4(),
Vec3.div(
Vec3(),
boxSize,
Vec3.sub(Vec3(), gridInfo.dimensions, Vec3.create(1, 1, 1))
)
);
const translate = Mat4.fromTranslation(Mat4(), boxOrigin);
const matrix = Mat4.mul(Mat4(), translate, scale);
const grid: Grid = {
transform: { kind: 'matrix', matrix },
cells: Tensor.create(
Tensor.Space(gridInfo.dimensions, axisOrder, Float32Array),
(values as any) as Tensor.Data
),
stats: {
min: arrayMin(values),
max: arrayMax(values),
mean: arrayMean(values),
sigma: arrayRms(values),
},
};
return grid;
}

View File

@@ -0,0 +1,124 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { sortArray } from '../../mol-data/util';
import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
import { WebGLContext } from '../../mol-gl/webgl/context';
import { Task } from '../../mol-task';
import { AlphaOrbital, createGrid, CubeGrid, CubeGridComputationParams, initCubeGrid } from './data-model';
import { gpuComputeAlphaOrbitalsDensityGridValues } from './gpu/compute';
export function createSphericalCollocationDensityGrid(
params: CubeGridComputationParams, orbitals: AlphaOrbital[], webgl?: WebGLContext
): Task<CubeGrid> {
return Task.create('Spherical Collocation Grid', async (ctx) => {
const cubeGrid = initCubeGrid(params);
let matrix: Float32Array;
if (canComputeGrid3dOnGPU(webgl)) {
// console.time('gpu');
matrix = await gpuComputeAlphaOrbitalsDensityGridValues(ctx, webgl!, cubeGrid, orbitals);
// console.timeEnd('gpu');
} else {
throw new Error('Missing OES_texture_float WebGL extension.');
}
const grid = createGrid(cubeGrid, matrix, [0, 1, 2]);
let isovalues: { negative?: number, positive?: number } | undefined;
if (!params.doNotComputeIsovalues) {
isovalues = computeDensityIsocontourValues(matrix, 0.85);
}
return { grid, isovalues };
});
}
export function computeDensityIsocontourValues(input: Float32Array, cumulativeThreshold: number) {
let weightSum = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = Math.abs(v);
weightSum += w;
}
const avgWeight = weightSum / input.length;
let minWeight = 3 * avgWeight;
// do not try to identify isovalues for degenerate data
// e.g. all values are almost same
if (Math.abs(avgWeight - input[0] * input[0]) < 1e-5) {
return { negative: void 0, positive: void 0 };
}
let size = 0;
while (true) {
let csum = 0;
size = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = Math.abs(v);
if (w >= minWeight) {
csum += w;
size++;
}
}
if (csum / weightSum > cumulativeThreshold) {
break;
}
minWeight -= avgWeight;
}
const values = new Float32Array(size);
const weights = new Float32Array(size);
const indices = new Int32Array(size);
let o = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = Math.abs(v);
if (w >= minWeight) {
values[o] = v;
weights[o] = w;
indices[o] = o;
o++;
}
}
sortArray(
indices,
(indices, i, j) => weights[indices[j]] - weights[indices[i]]
);
let cweight = 0,
cutoffIndex = 0;
for (let i = 0; i < size; i++) {
cweight += weights[indices[i]];
if (cweight / weightSum >= cumulativeThreshold) {
cutoffIndex = i;
break;
}
}
let positive = Number.POSITIVE_INFINITY,
negative = Number.NEGATIVE_INFINITY;
for (let i = 0; i < cutoffIndex; i++) {
const v = values[indices[i]];
if (v > 0) {
if (v < positive) positive = v;
} else if (v < 0) {
if (v > negative) negative = v;
}
}
return {
negative: negative !== Number.NEGATIVE_INFINITY ? negative : void 0,
positive: positive !== Number.POSITIVE_INFINITY ? positive : void 0,
};
}

View File

@@ -0,0 +1,170 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { createGrid3dComputeRenderable } from '../../../mol-gl/compute/grid3d';
import { TextureSpec, UnboxedValues, UniformSpec } from '../../../mol-gl/renderable/schema';
import { WebGLContext } from '../../../mol-gl/webgl/context';
import { RuntimeContext } from '../../../mol-task';
import { ValueCell } from '../../../mol-util';
import { arrayMin } from '../../../mol-util/array';
import { AlphaOrbital, Basis, CubeGridInfo } from '../data-model';
import { normalizeBasicOrder, SphericalBasisOrder } from '../spherical-functions';
import { MAIN, UTILS } from './shader.frag';
const Schema = {
tCenters: TextureSpec('image-float32', 'rgba', 'float', 'nearest'),
tInfo: TextureSpec('image-float32', 'rgba', 'float', 'nearest'),
tCoeff: TextureSpec('image-float32', 'rgb', 'float', 'nearest'),
tAlpha: TextureSpec('image-float32', 'alpha', 'float', 'nearest'),
uNCenters: UniformSpec('i'),
uNAlpha: UniformSpec('i'),
uNCoeff: UniformSpec('i'),
uMaxCoeffs: UniformSpec('i'),
};
const Orbitals = createGrid3dComputeRenderable({
schema: Schema,
loopBounds: ['uNCenters', 'uMaxCoeffs'],
mainCode: MAIN,
utilCode: UTILS,
returnCode: 'v',
values(params: { grid: CubeGridInfo, orbital: AlphaOrbital }) {
return createTextureData(params.grid, params.orbital);
}
});
const Density = createGrid3dComputeRenderable({
schema: {
...Schema,
uOccupancy: UniformSpec('f'),
},
loopBounds: ['uNCenters', 'uMaxCoeffs'],
mainCode: MAIN,
utilCode: UTILS,
returnCode: 'current + uOccupancy * v * v',
values(params: { grid: CubeGridInfo, orbitals: AlphaOrbital[] }) {
return {
...createTextureData(params.grid, params.orbitals[0]),
uOccupancy: 0
};
},
cumulative: {
states(params: { grid: CubeGridInfo, orbitals: AlphaOrbital[] }) {
return params.orbitals.filter(o => o.occupancy !== 0);
},
update({ grid }, state: AlphaOrbital, values) {
const alpha = getNormalizedAlpha(grid.params.basis, state.alpha, grid.params.sphericalOrder);
ValueCell.updateIfChanged(values.uOccupancy, state.occupancy);
ValueCell.update(values.tAlpha, { width: alpha.length, height: 1, array: alpha });
}
}
});
export function gpuComputeAlphaOrbitalsGridValues(ctx: RuntimeContext, webgl: WebGLContext, grid: CubeGridInfo, orbital: AlphaOrbital) {
return Orbitals(ctx, webgl, grid, { grid, orbital });
}
export function gpuComputeAlphaOrbitalsDensityGridValues(ctx: RuntimeContext, webgl: WebGLContext, grid: CubeGridInfo, orbitals: AlphaOrbital[]) {
return Density(ctx, webgl, grid, { grid, orbitals });
}
function getNormalizedAlpha(basis: Basis, alphaOrbitals: number[], sphericalOrder: SphericalBasisOrder) {
const alpha = new Float32Array(alphaOrbitals.length);
let aO = 0;
for (const atom of basis.atoms) {
for (const shell of atom.shells) {
for (const L of shell.angularMomentum) {
const a0 = normalizeBasicOrder(L, alphaOrbitals.slice(aO, aO + 2 * L + 1), sphericalOrder);
for (let i = 0; i < a0.length; i++) alpha[aO + i] = a0[i];
aO += 2 * L + 1;
}
}
}
return alpha;
}
function createTextureData(grid: CubeGridInfo, orbital: AlphaOrbital): UnboxedValues<typeof Schema> {
const { basis, sphericalOrder, cutoffThreshold } = grid.params;
let centerCount = 0;
let baseCount = 0;
let coeffCount = 0;
for (const atom of basis.atoms) {
for (const shell of atom.shells) {
for (const L of shell.angularMomentum) {
if (L > 4) {
// TODO: will L > 4 be required? Would need to precompute more functions in that case.
throw new Error('Angular momentum L > 4 not supported.');
}
centerCount++;
baseCount += 2 * L + 1;
coeffCount += shell.exponents.length;
}
}
}
const centers = new Float32Array(4 * centerCount);
// L, alpha_offset, coeff_offset_start, coeff_offset_end
const info = new Float32Array(4 * centerCount);
const alpha = new Float32Array(baseCount);
const coeff = new Float32Array(3 * coeffCount);
let maxCoeffs = 0;
let cO = 0, aO = 0, coeffO = 0;
for (const atom of basis.atoms) {
for (const shell of atom.shells) {
let amIndex = 0;
for (const L of shell.angularMomentum) {
const a0 = normalizeBasicOrder(L, orbital.alpha.slice(aO, aO + 2 * L + 1), sphericalOrder);
const cutoffRadius = cutoffThreshold > 0
? Math.sqrt(-Math.log(cutoffThreshold) / arrayMin(shell.exponents))
: 10000;
centers[4 * cO + 0] = atom.center[0];
centers[4 * cO + 1] = atom.center[1];
centers[4 * cO + 2] = atom.center[2];
centers[4 * cO + 3] = cutoffRadius * cutoffRadius;
info[4 * cO + 0] = L;
info[4 * cO + 1] = aO;
info[4 * cO + 2] = coeffO;
info[4 * cO + 3] = coeffO + shell.exponents.length;
for (let i = 0; i < a0.length; i++) alpha[aO + i] = a0[i];
const c0 = shell.coefficients[amIndex++];
for (let i = 0; i < shell.exponents.length; i++) {
coeff[3 * (coeffO + i) + 0] = c0[i];
coeff[3 * (coeffO + i) + 1] = shell.exponents[i];
}
if (c0.length > maxCoeffs) {
maxCoeffs = c0.length;
}
cO++;
aO += 2 * L + 1;
coeffO += shell.exponents.length;
}
}
}
return {
uNCenters: centerCount,
uNAlpha: baseCount,
uNCoeff: coeffCount,
uMaxCoeffs: maxCoeffs,
tCenters: { width: centerCount, height: 1, array: centers },
tInfo: { width: centerCount, height: 1, array: info },
tCoeff: { width: coeffCount, height: 1, array: coeff },
tAlpha: { width: baseCount, height: 1, array: alpha },
};
}

View File

@@ -0,0 +1,145 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
export const UTILS = `
float L1(vec3 p, float a0, float a1, float a2) {
return a0 * p.z + a1 * p.x + a2 * p.y;
}
float L2(vec3 p, float a0, float a1, float a2, float a3, float a4) {
float x = p.x, y = p.y, z = p.z;
float xx = x * x, yy = y * y, zz = z * z;
return (
a0 * (-0.5 * xx - 0.5 * yy + zz) +
a1 * (1.7320508075688772 * x * z) +
a2 * (1.7320508075688772 * y * z) +
a3 * (0.8660254037844386 * xx - 0.8660254037844386 * yy) +
a4 * (1.7320508075688772 * x * y)
);
}
float L3(vec3 p, float a0, float a1, float a2, float a3, float a4, float a5, float a6) {
float x = p.x, y = p.y, z = p.z;
float xx = x * x, yy = y * y, zz = z * z;
float xxx = xx * x, yyy = yy * y, zzz = zz * z;
return (
a0 * (-1.5 * xx * z - 1.5 * yy * z + zzz) +
a1 * (-0.6123724356957945 * xxx - 0.6123724356957945 * x * yy + 2.449489742783178 * x * zz) +
a2 * (-0.6123724356957945 * xx * y - 0.6123724356957945 * yyy + 2.449489742783178 * y * zz) +
a3 * (1.9364916731037085 * xx * z - 1.9364916731037085 * yy * z) +
a4 * (3.872983346207417 * x * y * z) +
a5 * (0.7905694150420949 * xxx - 2.3717082451262845 * x * yy) +
a6 * (2.3717082451262845 * xx * y - 0.7905694150420949 * yyy)
);
}
float L4(vec3 p, float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8) {
float x = p.x, y = p.y, z = p.z;
float xx = x * x, yy = y * y, zz = z * z;
float xxx = xx * x, yyy = yy * y, zzz = zz * z;
float xxxx = xxx * x, yyyy = yyy * y, zzzz = zzz * z;
return (
a0 * (0.375 * xxxx + 0.75 * xx * yy + 0.375 * yyyy - 3.0 * xx * zz - 3.0 * yy * zz + zzzz) +
a1 * (-2.3717082451262845 * xxx * z - 2.3717082451262845 * x * yy * z + 3.1622776601683795 * x * zzz) +
a2 * (-2.3717082451262845 * xx * y * z - 2.3717082451262845 * yyy * z + 3.1622776601683795 * y * zzz) +
a3 * (-0.5590169943749475 * xxxx + 0.5590169943749475 * yyyy + 3.3541019662496847 * xx * zz - 3.3541019662496847 * yy * zz) +
a4 * (-1.118033988749895 * xxx * y - 1.118033988749895 * x * yyy + 6.708203932499369 * x * y * zz) +
a5 * (2.091650066335189 * xxx * z + -6.274950199005566 * x * yy * z) +
a6 * (6.274950199005566 * xx * y * z + -2.091650066335189 * yyy * z) +
a7 * (0.739509972887452 * xxxx - 4.437059837324712 * xx * yy + 0.739509972887452 * yyyy) +
a8 * (2.958039891549808 * xxx * y + -2.958039891549808 * x * yyy)
);
}
float alpha(float offset, float f) {
#ifdef WEBGL1
// in webgl1, the value is in the alpha channel!
return texture2D(tAlpha, vec2(offset * f, 0.5)).a;
#else
return texture2D(tAlpha, vec2(offset * f, 0.5)).x;
#endif
}
float Y(int L, vec3 X, float aO, float fA) {
if (L == 0) {
return alpha(aO, fA);
} else if (L == 1) {
return L1(X,
alpha(aO, fA), alpha(aO + 1.0, fA), alpha(aO + 2.0, fA)
);
} else if (L == 2) {
return L2(X,
alpha(aO, fA), alpha(aO + 1.0, fA), alpha(aO + 2.0, fA), alpha(aO + 3.0, fA), alpha(aO + 4.0, fA)
);
} else if (L == 3) {
return L3(X,
alpha(aO, fA), alpha(aO + 1.0, fA), alpha(aO + 2.0, fA), alpha(aO + 3.0, fA), alpha(aO + 4.0, fA),
alpha(aO + 5.0, fA), alpha(aO + 6.0, fA)
);
} else if (L == 4) {
return L4(X,
alpha(aO, fA), alpha(aO + 1.0, fA), alpha(aO + 2.0, fA), alpha(aO + 3.0, fA), alpha(aO + 4.0, fA),
alpha(aO + 5.0, fA), alpha(aO + 6.0, fA), alpha(aO + 7.0, fA), alpha(aO + 8.0, fA)
);
}
// TODO: do we need L > 4?
return 0.0;
}
#ifndef WEBGL1
float R(float R2, int start, int end, float fCoeff) {
float gauss = 0.0;
for (int i = start; i < end; i++) {
vec2 c = texture2D(tCoeff, vec2(float(i) * fCoeff, 0.5)).xy;
gauss += c.x * exp(-c.y * R2);
}
return gauss;
}
#else
float R(float R2, int start, int end, float fCoeff) {
float gauss = 0.0;
int o = start;
for (int i = 0; i < uMaxCoeffs; i++) {
if (o >= end) break;
vec2 c = texture2D(tCoeff, vec2(float(o) * fCoeff, 0.5)).xy;
gauss += c.x * exp(-c.y * R2);
o++;
}
return gauss;
}
#endif
`;
export const MAIN = `
float fCenter = 1.0 / float(uNCenters - 1);
float fCoeff = 1.0 / float(uNCoeff - 1);
float fA = 1.0 / float(uNAlpha - 1);
float v = 0.0;
for (int i = 0; i < uNCenters; i++) {
vec2 cCoord = vec2(float(i) * fCenter, 0.5);
vec4 center = texture2D(tCenters, cCoord);
vec3 X = xyz - center.xyz;
float R2 = dot(X, X);
// center.w is squared cutoff radius
if (R2 > center.w) {
continue;
}
vec4 info = texture2D(tInfo, cCoord);
int L = int(info.x);
float aO = info.y;
int coeffStart = int(info.z);
int coeffEnd = int(info.w);
v += R(R2, coeffStart, coeffEnd, fCoeff) * Y(L, X, aO, fA);
}
`;

View File

@@ -0,0 +1,131 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Inspired by https://github.com/dgasmith/gau2grid.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { sortArray } from '../../mol-data/util';
import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
import { WebGLContext } from '../../mol-gl/webgl/context';
import { Task } from '../../mol-task';
import { sphericalCollocation } from './collocation';
import { AlphaOrbital, createGrid, CubeGrid, CubeGridComputationParams, initCubeGrid } from './data-model';
import { gpuComputeAlphaOrbitalsGridValues } from './gpu/compute';
// setDebugMode(true);
export function createSphericalCollocationGrid(
params: CubeGridComputationParams, orbital: AlphaOrbital, webgl?: WebGLContext
): Task<CubeGrid> {
return Task.create('Spherical Collocation Grid', async (ctx) => {
const cubeGrid = initCubeGrid(params);
let matrix: Float32Array;
if (canComputeGrid3dOnGPU(webgl)) {
// console.time('gpu');
matrix = await gpuComputeAlphaOrbitalsGridValues(ctx, webgl!, cubeGrid, orbital);
// console.timeEnd('gpu');
} else {
// console.time('cpu');
matrix = await sphericalCollocation(cubeGrid, orbital, ctx);
// console.timeEnd('cpu');
}
const grid = createGrid(cubeGrid, matrix, [0, 1, 2]);
let isovalues: { negative?: number, positive?: number } | undefined;
if (!params.doNotComputeIsovalues) {
isovalues = computeOrbitalIsocontourValues(matrix, 0.85);
}
return { grid, isovalues };
});
}
export function computeOrbitalIsocontourValues(input: Float32Array, cumulativeThreshold: number) {
let weightSum = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = v * v;
weightSum += w;
}
const avgWeight = weightSum / input.length;
let minWeight = 3 * avgWeight;
// do not try to identify isovalues for degenerate data
// e.g. all values are almost same
if (Math.abs(avgWeight - input[0] * input[0]) < 1e-5) {
return { negative: void 0, positive: void 0 };
}
let size = 0;
while (true) {
let csum = 0;
size = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = v * v;
if (w >= minWeight) {
csum += w;
size++;
}
}
if (csum / weightSum > cumulativeThreshold) {
break;
}
minWeight -= avgWeight;
}
const values = new Float32Array(size);
const weights = new Float32Array(size);
const indices = new Int32Array(size);
let o = 0;
for (let i = 0, _i = input.length; i < _i; i++) {
const v = input[i];
const w = v * v;
if (w >= minWeight) {
values[o] = v;
weights[o] = w;
indices[o] = o;
o++;
}
}
sortArray(
indices,
(indices, i, j) => weights[indices[j]] - weights[indices[i]]
);
let cweight = 0,
cutoffIndex = 0;
for (let i = 0; i < size; i++) {
cweight += weights[indices[i]];
if (cweight / weightSum >= cumulativeThreshold) {
cutoffIndex = i;
break;
}
}
let positive = Number.POSITIVE_INFINITY,
negative = Number.NEGATIVE_INFINITY;
for (let i = 0; i < cutoffIndex; i++) {
const v = values[indices[i]];
if (v > 0) {
if (v < positive) positive = v;
} else if (v < 0) {
if (v > negative) negative = v;
}
}
return {
negative: negative !== Number.NEGATIVE_INFINITY ? negative : void 0,
positive: positive !== Number.POSITIVE_INFINITY ? positive : void 0,
};
}

View File

@@ -0,0 +1,93 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Inspired by https://github.com/dgasmith/gau2grid.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
// gaussian:
// R_0, R^+_1, R^-_1, ..., R^+_l, R^-_l
// cca:
// R^-_(l), R^-_(l-1), ..., R_0, ..., R^+_(l-1), R^+_l
// cca-reverse:
// R^+_(l), R^+_(l-1), ..., R_0, ..., R^-_(l-1), R^-_l
export type SphericalBasisOrder = 'gaussian' | 'cca' | 'cca-reverse';
export function normalizeBasicOrder(
L: number,
alpha: number[],
order: SphericalBasisOrder
) {
if (order === 'gaussian' || L === 0) return alpha;
const ret: number[] = [alpha[L]];
for (let l = 0; l < L; l++) {
const a = alpha[L - l - 1],
b = alpha[L + l + 1];
if (order === 'cca') ret.push(b, a);
else ret.push(a, b);
}
return ret;
}
export type SphericalFunc = (
alpha: number[],
x: number,
y: number,
z: number
) => number;
export const SphericalFunctions: SphericalFunc[] = [L0, L1, L2, L3, L4];
// L_i functions were auto-generated.
function L0(alpha: number[], x: number, y: number, z: number) {
return alpha[0];
}
function L1(alpha: number[], x: number, y: number, z: number) {
return alpha[0] * z + alpha[1] * x + alpha[2] * y;
}
function L2(alpha: number[], x: number, y: number, z: number) {
const xx = x * x, yy = y * y, zz = z * z;
return (
alpha[0] * (-0.5 * xx - 0.5 * yy + zz) +
alpha[1] * (1.7320508075688772 * x * z) +
alpha[2] * (1.7320508075688772 * y * z) +
alpha[3] * (0.8660254037844386 * xx - 0.8660254037844386 * yy) +
alpha[4] * (1.7320508075688772 * x * y)
);
}
function L3(alpha: number[], x: number, y: number, z: number) {
const xx = x * x, yy = y * y, zz = z * z;
const xxx = xx * x, yyy = yy * y, zzz = zz * z;
return (
alpha[0] * (-1.5 * xx * z - 1.5 * yy * z + zzz) +
alpha[1] * (-0.6123724356957945 * xxx - 0.6123724356957945 * x * yy + 2.449489742783178 * x * zz) +
alpha[2] * (-0.6123724356957945 * xx * y - 0.6123724356957945 * yyy + 2.449489742783178 * y * zz) +
alpha[3] * (1.9364916731037085 * xx * z - 1.9364916731037085 * yy * z) +
alpha[4] * (3.872983346207417 * x * y * z) +
alpha[5] * (0.7905694150420949 * xxx - 2.3717082451262845 * x * yy) +
alpha[6] * (2.3717082451262845 * xx * y - 0.7905694150420949 * yyy)
);
}
function L4(alpha: number[], x: number, y: number, z: number) {
const xx = x * x, yy = y * y, zz = z * z;
const xxx = xx * x, yyy = yy * y, zzz = zz * z;
const xxxx = xxx * x, yyyy = yyy * y, zzzz = zzz * z;
return (
alpha[0] * (0.375 * xxxx + 0.75 * xx * yy + 0.375 * yyyy - 3.0 * xx * zz - 3.0 * yy * zz + zzzz) +
alpha[1] * (-2.3717082451262845 * xxx * z - 2.3717082451262845 * x * yy * z + 3.1622776601683795 * x * zzz) +
alpha[2] * (-2.3717082451262845 * xx * y * z - 2.3717082451262845 * yyy * z + 3.1622776601683795 * y * zzz) +
alpha[3] * (-0.5590169943749475 * xxxx + 0.5590169943749475 * yyyy + 3.3541019662496847 * xx * zz - 3.3541019662496847 * yy * zz) +
alpha[4] * (-1.118033988749895 * xxx * y - 1.118033988749895 * x * yyy + 6.708203932499369 * x * y * zz) +
alpha[5] * (2.091650066335189 * xxx * z + -6.274950199005566 * x * yy * z) +
alpha[6] * (6.274950199005566 * xx * y * z + -2.091650066335189 * yyy * z) +
alpha[7] * (0.739509972887452 * xxxx - 4.437059837324712 * xx * yy + 0.739509972887452 * yyyy) +
alpha[8] * (2.958039891549808 * xxx * y + -2.958039891549808 * x * yyy)
);
}

View File

@@ -0,0 +1,236 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { PluginStateObject, PluginStateTransform } from '../../mol-plugin-state/objects';
import { createSphericalCollocationGrid } from './orbitals';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Task } from '../../mol-task';
import { CustomProperties } from '../../mol-model/custom-property';
import { SphericalBasisOrder } from './spherical-functions';
import { Volume } from '../../mol-model/volume';
import { PluginContext } from '../../mol-plugin/context';
import { ColorNames } from '../../mol-util/color/names';
import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params';
import { StateTransformer } from '../../mol-state';
import { Theme } from '../../mol-theme/theme';
import { VolumeRepresentation3DHelpers } from '../../mol-plugin-state/transforms/representation';
import { AlphaOrbital, Basis, CubeGrid } from './data-model';
import { createSphericalCollocationDensityGrid } from './density';
import { Tensor } from '../../mol-math/linear-algebra';
export class BasisAndOrbitals extends PluginStateObject.Create<{ basis: Basis, order: SphericalBasisOrder, orbitals: AlphaOrbital[] }>({ name: 'Basis', typeClass: 'Object' }) { }
export const StaticBasisAndOrbitals = PluginStateTransform.BuiltIn({
name: 'static-basis-and-orbitals',
display: 'Basis and Orbitals',
from: PluginStateObject.Root,
to: BasisAndOrbitals,
params: {
label: PD.Text('Orbital Data', { isHidden: true }),
basis: PD.Value<Basis>(void 0 as any, { isHidden: true }),
order: PD.Text<SphericalBasisOrder>('gaussian' as SphericalBasisOrder, { isHidden: true }),
orbitals: PD.Value<AlphaOrbital[]>([], { isHidden: true })
},
})({
apply({ params }) {
return new BasisAndOrbitals({ basis: params.basis, order: params.order, orbitals: params.orbitals }, { label: params.label });
}
});
const CreateOrbitalVolumeParamBase = {
cutoffThreshold: PD.Numeric(0.0015, { min: 0, max: 0.1, step: 0.0001 }),
boxExpand: PD.Numeric(4.5, { min: 0, max: 7, step: 0.1 }),
gridSpacing: PD.ObjectList({ atomCount: PD.Numeric(0), spacing: PD.Numeric(0.35, { min: 0.1, max: 2, step: 0.01 }) }, e => `Atoms ${e.atomCount}: ${e.spacing}`, {
defaultValue: [
{ atomCount: 55, spacing: 0.5 },
{ atomCount: 40, spacing: 0.45 },
{ atomCount: 25, spacing: 0.4 },
{ atomCount: 0, spacing: 0.35 },
]
}),
clampValues: PD.MappedStatic('off', {
off: PD.EmptyGroup(),
on: PD.Group({
sigma: PD.Numeric(8, { min: 1, max: 20 }, { description: 'Clamp values to range [sigma * negIsoValue, sigma * posIsoValue].' })
})
})
};
function clampData(matrix: Tensor.Data, min: number, max: number) {
for (let i = 0, _i = matrix.length; i < _i; i++) {
const v = matrix[i];
if (v < min) matrix[i] = min;
else if (v > max) matrix[i] = max;
}
}
function clampGrid(data: CubeGrid, v: number) {
const grid = data.grid;
const min = (data.isovalues?.negative ?? data.grid.stats.min) * v;
const max = (data.isovalues?.positive ?? data.grid.stats.max) * v;
// clamp values for better direct volume resolution
// current implementation uses Byte array for values
// if this is not enough, update mol* to use float
// textures instead
if (grid.stats.min < min || grid.stats.max > max) {
clampData(data.grid.cells.data, min, max);
if (grid.stats.min < min) {
(grid.stats.min as number) = min;
}
if (grid.stats.max > max) {
(grid.stats.max as number) = max;
}
}
}
export const CreateOrbitalVolume = PluginStateTransform.BuiltIn({
name: 'create-orbital-volume',
display: 'Orbital Volume',
from: BasisAndOrbitals,
to: PluginStateObject.Volume.Data,
params: (a) => {
if (!a) {
return { index: PD.Numeric(0), ...CreateOrbitalVolumeParamBase };
}
return {
index: PD.Select(0, a.data.orbitals.map((o, i) => [i, `[${i + 1}] ${o.energy.toFixed(4)}`])),
...CreateOrbitalVolumeParamBase
};
}
})({
apply({ a, params }, plugin: PluginContext) {
return Task.create('Orbital Volume', async ctx => {
const data = await createSphericalCollocationGrid({
basis: a.data.basis,
cutoffThreshold: params.cutoffThreshold,
sphericalOrder: a.data.order,
boxExpand: params.boxExpand,
gridSpacing: params.gridSpacing.map(e => [e.atomCount, e.spacing] as [number, number])
}, a.data.orbitals[params.index], plugin.canvas3d?.webgl).runInContext(ctx);
const volume: Volume = {
grid: data.grid,
sourceData: { name: 'custom grid', kind: 'alpha-orbitals', data },
customProperties: new CustomProperties(),
_propertyData: Object.create(null),
};
if (params.clampValues?.name === 'on') {
clampGrid(data, params.clampValues?.params?.sigma ?? 8);
}
return new PluginStateObject.Volume.Data(volume, { label: 'Orbital Volume' });
});
}
});
export const CreateOrbitalDensityVolume = PluginStateTransform.BuiltIn({
name: 'create-orbital-density-volume',
display: 'Orbital Density Volume',
from: BasisAndOrbitals,
to: PluginStateObject.Volume.Data,
params: CreateOrbitalVolumeParamBase
})({
apply({ a, params }, plugin: PluginContext) {
return Task.create('Orbital Volume', async ctx => {
const data = await createSphericalCollocationDensityGrid({
basis: a.data.basis,
cutoffThreshold: params.cutoffThreshold,
sphericalOrder: a.data.order,
boxExpand: params.boxExpand,
gridSpacing: params.gridSpacing.map(e => [e.atomCount, e.spacing] as [number, number])
}, a.data.orbitals, plugin.canvas3d?.webgl).runInContext(ctx);
const volume: Volume = {
grid: data.grid,
sourceData: { name: 'custom grid', kind: 'alpha-orbitals', data },
customProperties: new CustomProperties(),
_propertyData: Object.create(null),
};
if (params.clampValues?.name === 'on') {
clampGrid(data, params.clampValues?.params?.sigma ?? 8);
}
return new PluginStateObject.Volume.Data(volume, { label: 'Orbital Volume' });
});
}
});
export const CreateOrbitalRepresentation3D = PluginStateTransform.BuiltIn({
name: 'create-orbital-representation-3d',
display: 'Orbital Representation 3D',
from: PluginStateObject.Volume.Data,
to: PluginStateObject.Volume.Representation3D,
params: {
directVolume: PD.Boolean(false),
relativeIsovalue: PD.Numeric(1, { min: 0.01, max: 5, step: 0.01 }),
kind: PD.Select<'positive' | 'negative'>('positive', [['positive', 'Positive'], ['negative', 'Negative']]),
color: PD.Color(ColorNames.blue),
alpha: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
xrayShaded: PD.Boolean(false),
pickable: PD.Boolean(true)
}
})({
canAutoUpdate() {
return true;
},
apply({ a, params: srcParams }, plugin: PluginContext) {
return Task.create('Orbitals Representation 3D', async ctx => {
const params = volumeParams(plugin, a, srcParams);
const propertyCtx = { runtime: ctx, assetManager: plugin.managers.asset };
const provider = plugin.representation.volume.registry.get(params.type.name);
if (provider.ensureCustomProperties) await provider.ensureCustomProperties.attach(propertyCtx, a.data);
const props = params.type.params || {};
const repr = provider.factory({ webgl: plugin.canvas3d?.webgl, ...plugin.representation.volume.themes }, provider.getParams);
repr.setTheme(Theme.create(plugin.representation.volume.themes, { volume: a.data }, params));
await repr.createOrUpdate(props, a.data).runInContext(ctx);
repr.setState({ pickable: srcParams.pickable });
return new PluginStateObject.Volume.Representation3D({ repr, source: a }, { label: provider.label, description: VolumeRepresentation3DHelpers.getDescription(props) });
});
},
update({ a, b, newParams: srcParams }, plugin: PluginContext) {
return Task.create('Orbitals Representation 3D', async ctx => {
const newParams = volumeParams(plugin, a, srcParams);
const props = { ...b.data.repr.props, ...newParams.type.params };
b.data.repr.setTheme(Theme.create(plugin.representation.volume.themes, { volume: a.data }, newParams));
await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);
b.data.repr.setState({ pickable: srcParams.pickable });
b.description = VolumeRepresentation3DHelpers.getDescription(props);
return StateTransformer.UpdateResult.Updated;
});
}
});
function volumeParams(plugin: PluginContext, volume: PluginStateObject.Volume.Data, params: StateTransformer.Params<typeof CreateOrbitalRepresentation3D>) {
if (volume.data.sourceData.kind !== 'alpha-orbitals') throw new Error('Invalid data source kind.');
const { isovalues } = volume.data.sourceData.data as CubeGrid;
if (!isovalues) throw new Error('Isovalues are not computed.');
const value = isovalues[params.kind];
return createVolumeRepresentationParams(plugin, volume.data, params.directVolume ? {
type: 'direct-volume',
typeParams: {
alpha: params.alpha,
renderMode: {
name: 'isosurface',
params: { isoValue: { kind: 'absolute', absoluteValue: (value ?? 1000) * params.relativeIsovalue }, singleLayer: false }
},
xrayShaded: params.xrayShaded
},
color: 'uniform',
colorParams: { value: params.color }
} : {
type: 'isosurface',
typeParams: { isoValue: { kind: 'absolute', absoluteValue: (value ?? 1000) * params.relativeIsovalue }, alpha: params.alpha, xrayShaded: params.xrayShaded },
color: 'uniform',
colorParams: { value: params.color }
});
}

View File

@@ -0,0 +1,370 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Structure, StructureElement, StructureProperties } from '../../mol-model/structure';
import { Task, RuntimeContext } from '../../mol-task';
import { CentroidHelper } from '../../mol-math/geometry/centroid-helper';
import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area';
import { Vec3 } from '../../mol-math/linear-algebra';
import { getElementMoleculeType } from '../../mol-model/structure/util';
import { MoleculeType } from '../../mol-model/structure/model/types';
import { AccessibleSurfaceArea } from '../../mol-model-props/computed/accessible-surface-area/shrake-rupley';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { MembraneOrientation } from './prop';
interface ANVILContext {
structure: Structure,
numberOfSpherePoints: number,
stepSize: number,
minThickness: number,
maxThickness: number,
asaCutoff: number,
offsets: ArrayLike<number>,
exposed: ArrayLike<boolean>,
centroid: Vec3,
extent: number
};
export const ANVILParams = {
numberOfSpherePoints: PD.Numeric(120, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
stepSize: PD.Numeric(1, { min: 0.25, max: 4, step: 0.25 }, { description: 'Thickness of membrane slices that will be tested' }),
minThickness: PD.Numeric(20, { min: 10, max: 30, step: 1}, { description: 'Minimum membrane thickness used during refinement' }),
maxThickness: PD.Numeric(40, { min: 30, max: 50, step: 1}, { description: 'Maximum membrane thickness used during refinement' }),
asaCutoff: PD.Numeric(40, { min: 10, max: 100, step: 1 }, { description: 'Absolute ASA cutoff above which residues will be considered' })
};
export type ANVILParams = typeof ANVILParams
export type ANVILProps = PD.Values<ANVILParams>
/**
* Implements:
* Membrane positioning for high- and low-resolution protein structures through a binary classification approach
* Guillaume Postic, Yassine Ghouzam, Vincent Guiraud, and Jean-Christophe Gelly
* Protein Engineering, Design & Selection, 2015, 15
* doi: 10.1093/protein/gzv063
*/
export function computeANVIL(structure: Structure, props: ANVILProps) {
return Task.create('Compute Membrane Orientation', async runtime => {
return await calculate(runtime, structure, props);
});
}
const centroidHelper = new CentroidHelper();
function initialize(structure: Structure, props: ANVILProps): ANVILContext {
const l = StructureElement.Location.create(structure);
const { label_atom_id, x, y, z } = StructureProperties.atom;
const elementCount = structure.polymerResidueCount;
centroidHelper.reset();
let offsets = new Int32Array(elementCount);
let exposed = new Array<boolean>(elementCount);
const accessibleSurfaceArea = structure && AccessibleSurfaceAreaProvider.get(structure);
const asa = accessibleSurfaceArea.value!;
const vec = Vec3();
let m = 0;
for (let i = 0, il = structure.units.length; i < il; ++i) {
const unit = structure.units[i];
const { elements } = unit;
l.unit = unit;
for (let j = 0, jl = elements.length; j < jl; ++j) {
const eI = elements[j];
l.element = eI;
// consider only amino acids
if (getElementMoleculeType(unit, eI) !== MoleculeType.Protein) {
continue;
}
// only CA is considered for downstream operations
if (label_atom_id(l) !== 'CA') {
continue;
}
// while iterating use first pass to compute centroid
Vec3.set(vec, x(l), y(l), z(l));
centroidHelper.includeStep(vec);
// keep track of offsets and exposed state to reuse
offsets[m] = structure.serialMapping.getSerialIndex(l.unit, l.element);
exposed[m] = AccessibleSurfaceArea.getValue(l, asa) > props.asaCutoff;
m++;
}
}
// omit potentially empty tail1
offsets = offsets.slice(0, m);
exposed = exposed.slice(0, m);
// calculate centroid and extent
centroidHelper.finishedIncludeStep();
const centroid = centroidHelper.center;
for (let k = 0, kl = offsets.length; k < kl; k++) {
setLocation(l, structure, offsets[k]);
Vec3.set(vec, x(l), y(l), z(l));
centroidHelper.radiusStep(vec);
}
const extent = 1.2 * Math.sqrt(centroidHelper.radiusSq);
return {
...props,
structure: structure,
offsets: offsets,
exposed: exposed,
centroid: centroid,
extent: extent
};
}
export async function calculate(runtime: RuntimeContext, structure: Structure, params: ANVILProps): Promise<MembraneOrientation> {
const { label_comp_id } = StructureProperties.atom;
const ctx = initialize(structure, params);
const initialHphobHphil = HphobHphil.filtered(ctx, label_comp_id);
const initialMembrane = findMembrane(ctx, generateSpherePoints(ctx, ctx.numberOfSpherePoints), initialHphobHphil, label_comp_id);
const alternativeMembrane = findMembrane(ctx, findProximateAxes(ctx, initialMembrane), initialHphobHphil, label_comp_id);
const membrane = initialMembrane.qmax! > alternativeMembrane.qmax! ? initialMembrane : alternativeMembrane;
return {
planePoint1: membrane.planePoint1,
planePoint2: membrane.planePoint2,
normalVector: membrane.normalVector!,
radius: ctx.extent,
centroid: ctx.centroid
};
}
interface MembraneCandidate {
planePoint1: Vec3,
planePoint2: Vec3,
stats: HphobHphil,
normalVector?: Vec3,
spherePoint?: Vec3,
qmax?: number
}
namespace MembraneCandidate {
export function initial(c1: Vec3, c2: Vec3, stats: HphobHphil): MembraneCandidate {
return {
planePoint1: c1,
planePoint2: c2,
stats: stats
};
}
export function scored(spherePoint: Vec3, c1: Vec3, c2: Vec3, stats: HphobHphil, qmax: number, centroid: Vec3): MembraneCandidate {
const diam_vect = Vec3();
Vec3.sub(diam_vect, centroid, spherePoint);
return {
planePoint1: c1,
planePoint2: c2,
stats: stats,
normalVector: diam_vect,
spherePoint: spherePoint,
qmax: qmax
};
}
}
function findMembrane(ctx: ANVILContext, spherePoints: Vec3[], initialStats: HphobHphil, label_comp_id: StructureElement.Property<string>): MembraneCandidate {
const { centroid, stepSize, minThickness, maxThickness } = ctx;
// best performing membrane
let membrane: MembraneCandidate;
// score of the best performing membrane
let qmax = 0;
// construct slices of thickness 1.0 along the axis connecting the centroid and the spherePoint
const diam = Vec3();
for (let i = 0, il = spherePoints.length; i < il; i++) {
const spherePoint = spherePoints[i];
Vec3.sub(diam, centroid, spherePoint);
Vec3.scale(diam, diam, 2);
const diamNorm = Vec3.magnitude(diam);
const qvartemp = [];
for (let i = 0, il = diamNorm - stepSize; i < il; i += stepSize) {
const c1 = Vec3();
const c2 = Vec3();
Vec3.scaleAndAdd(c1, spherePoint, diam, i / diamNorm);
Vec3.scaleAndAdd(c2, spherePoint, diam, (i + stepSize) / diamNorm);
// evaluate how well this membrane slice embeddeds the peculiar residues
const stats = HphobHphil.filtered(ctx, label_comp_id, (testPoint: Vec3) => isInMembranePlane(testPoint, diam, c1, c2));
qvartemp.push(MembraneCandidate.initial(c1, c2, stats));
}
let jmax = (minThickness / stepSize) - 1;
for (let width = 0, widthl = maxThickness; width < widthl;) {
const imax = qvartemp.length - 1 - jmax;
for (let i = 0, il = imax; i < il; i++) {
const c1 = qvartemp[i].planePoint1;
const c2 = qvartemp[i + jmax].planePoint2;
let hphob = 0;
let hphil = 0;
let total = 0;
for (let j = 0; j < jmax; j++) {
const ij = qvartemp[i + j];
if (j === 0 || j === jmax - 1) {
hphob += 0.5 * ij.stats.hphob;
hphil += 0.5 * ij.stats.hphil;
} else {
hphob += ij.stats.hphob;
hphil += ij.stats.hphil;
}
total += ij.stats.total;
}
const stats = HphobHphil.of(hphob, hphil, total);
if (hphob !== 0) {
const qvaltest = qValue(stats, initialStats);
if (qvaltest > qmax) {
qmax = qvaltest;
membrane = MembraneCandidate.scored(spherePoint, c1, c2, HphobHphil.of(hphob, hphil, total), qmax, centroid);
}
}
}
jmax++;
width = (jmax + 1) * stepSize;
}
}
return membrane!;
}
function qValue(currentStats: HphobHphil, initialStats: HphobHphil): number {
if(initialStats.hphob < 1) {
initialStats.hphob = 0.1;
}
if(initialStats.hphil < 1) {
initialStats.hphil += 1;
}
const part_tot = currentStats.hphob + currentStats.hphil;
return (currentStats.hphob * (initialStats.hphil - currentStats.hphil) - currentStats.hphil * (initialStats.hphob - currentStats.hphob)) /
Math.sqrt(part_tot * initialStats.hphob * initialStats.hphil * (initialStats.hphob + initialStats.hphil - part_tot));
}
export function isInMembranePlane(testPoint: Vec3, normalVector: Vec3, planePoint1: Vec3, planePoint2: Vec3): boolean {
const d1 = -Vec3.dot(normalVector, planePoint1);
const d2 = -Vec3.dot(normalVector, planePoint2);
const d = -Vec3.dot(normalVector, testPoint);
return d > Math.min(d1, d2) && d < Math.max(d1, d2);
}
// generates a defined number of points on a sphere with radius = extent around the specified centroid
function generateSpherePoints(ctx: ANVILContext, numberOfSpherePoints: number): Vec3[] {
const { centroid, extent } = ctx;
const points = [];
let oldPhi = 0, h, theta, phi;
for(let k = 1, kl = numberOfSpherePoints + 1; k < kl; k++) {
h = -1 + 2 * (k - 1) / (numberOfSpherePoints - 1);
theta = Math.acos(h);
phi = (k === 1 || k === numberOfSpherePoints) ? 0 : (oldPhi + 3.6 / Math.sqrt(numberOfSpherePoints * (1 - h * h))) % (2 * Math.PI);
const point = Vec3.create(
extent * Math.sin(phi) * Math.sin(theta) + centroid[0],
extent * Math.cos(theta) + centroid[1],
extent * Math.cos(phi) * Math.sin(theta) + centroid[2]
);
points[k - 1] = point;
oldPhi = phi;
}
return points;
}
// generates sphere points close to that of the initial membrane
function findProximateAxes(ctx: ANVILContext, membrane: MembraneCandidate): Vec3[] {
const { numberOfSpherePoints, extent } = ctx;
const points = generateSpherePoints(ctx, 30000);
let j = 4;
let sphere_pts2: Vec3[] = [];
while (sphere_pts2.length < numberOfSpherePoints) {
const d = 2 * extent / numberOfSpherePoints + j;
const dsq = d * d;
sphere_pts2 = [];
for (let i = 0, il = points.length; i < il; i++) {
if (Vec3.squaredDistance(points[i], membrane.spherePoint!) < dsq) {
sphere_pts2.push(points[i]);
}
}
j += 0.2;
}
return sphere_pts2;
}
interface HphobHphil {
hphob: number,
hphil: number,
total: number
}
namespace HphobHphil {
export function of(hphob: number, hphil: number, total?: number) {
return {
hphob: hphob,
hphil: hphil,
total: !!total ? total : hphob + hphil
};
}
const testPoint = Vec3();
export function filtered(ctx: ANVILContext, label_comp_id: StructureElement.Property<string>, filter?: (test: Vec3) => boolean): HphobHphil {
const { offsets, exposed, structure } = ctx;
const l = StructureElement.Location.create(structure);
const { x, y, z } = StructureProperties.atom;
let hphob = 0;
let hphil = 0;
for (let k = 0, kl = offsets.length; k < kl; k++) {
// ignore buried residues
if (!exposed[k]) {
continue;
}
setLocation(l, structure, offsets[k]);
Vec3.set(testPoint, x(l), y(l), z(l));
// testPoints have to be in putative membrane layer
if (filter && !filter(testPoint)) {
continue;
}
if (isHydrophobic(label_comp_id(l))) {
hphob++;
} else {
hphil++;
}
}
return of(hphob, hphil);
}
}
// ANVIL-specific (not general) definition of membrane-favoring amino acids
const HYDROPHOBIC_AMINO_ACIDS = new Set(['ALA', 'CYS', 'GLY', 'HIS', 'ILE', 'LEU', 'MET', 'PHE', 'SER', 'THR', 'VAL']);
export function isHydrophobic(label_comp_id: string): boolean {
return HYDROPHOBIC_AMINO_ACIDS.has(label_comp_id);
}
function setLocation(l: StructureElement.Location, structure: Structure, serialIndex: number) {
l.structure = structure;
l.unit = structure.units[structure.serialMapping.unitIndices[serialIndex]];
l.element = structure.serialMapping.elementIndices[serialIndex];
return l;
}

View File

@@ -0,0 +1,174 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
*/
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../mol-plugin-state/builder/structure/representation-preset';
import { MembraneOrientationProvider, MembraneOrientation } from './prop';
import { StateObjectRef, StateTransformer, StateTransform } from '../../mol-state';
import { Task } from '../../mol-task';
import { PluginBehavior } from '../../mol-plugin/behavior';
import { MembraneOrientationRepresentationProvider, MembraneOrientationParams, MembraneOrientationRepresentation } from './representation';
import { HydrophobicityColorThemeProvider } from '../../mol-theme/color/hydrophobicity';
import { PluginStateObject, PluginStateTransform } from '../../mol-plugin-state/objects';
import { PluginContext } from '../../mol-plugin/context';
import { DefaultQueryRuntimeTable } from '../../mol-script/runtime/query/compiler';
import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { GenericRepresentationRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
const Tag = MembraneOrientation.Tag;
export const ANVILMembraneOrientation = PluginBehavior.create<{ autoAttach: boolean }>({
name: 'anvil-membrane-orientation-prop',
category: 'custom-props',
display: {
name: 'Membrane Orientation',
description: 'Data calculated with ANVIL algorithm.'
},
ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> {
private provider = MembraneOrientationProvider
register(): void {
DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider);
this.ctx.query.structure.registry.add(isTransmembrane);
this.ctx.genericRepresentationControls.set(Tag.Representation, selection => {
const refs: GenericRepresentationRef[] = [];
selection.structures.forEach(structure => {
const memRepr = structure.genericRepresentations?.filter(r => r.cell.transform.transformer.id === MembraneOrientation3D.id)[0];
if (memRepr) refs.push(memRepr);
});
return [refs, 'Membrane Orientation'];
});
this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset);
}
update(p: { autoAttach: boolean }) {
let updated = this.params.autoAttach !== p.autoAttach;
this.params.autoAttach = p.autoAttach;
this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
return updated;
}
unregister() {
DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider);
this.ctx.query.structure.registry.remove(isTransmembrane);
this.ctx.genericRepresentationControls.delete(Tag.Representation);
this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset);
}
},
params: () => ({
autoAttach: PD.Boolean(false)
})
});
//
export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
MS.struct.modifier.wholeResidues([
MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
'atom-test': MembraneOrientation.symbols.isTransmembrane.symbol(),
})
])
])
]), {
description: 'Select residues that are embedded between the membrane layers.',
category: StructureSelectionCategory.Residue,
ensureCustomProperties: (ctx, structure) => {
return MembraneOrientationProvider.attach(ctx, structure);
}
});
//
export { MembraneOrientation3D };
type MembraneOrientation3D = typeof MembraneOrientation3D
const MembraneOrientation3D = PluginStateTransform.BuiltIn({
name: 'membrane-orientation-3d',
display: {
name: 'Membrane Orientation',
description: 'Membrane Orientation planes and rims. Data calculated with ANVIL algorithm.'
},
from: PluginStateObject.Molecule.Structure,
to: PluginStateObject.Shape.Representation3D,
params: (a) => {
return {
...MembraneOrientationParams,
};
}
})({
canAutoUpdate({ oldParams, newParams }) {
return true;
},
apply({ a, params }, plugin: PluginContext) {
return Task.create('Membrane Orientation', async ctx => {
await MembraneOrientationProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, a.data);
const repr = MembraneOrientationRepresentation({ webgl: plugin.canvas3d?.webgl, ...plugin.representation.structure.themes }, () => MembraneOrientationParams);
await repr.createOrUpdate(params, a.data).runInContext(ctx);
return new PluginStateObject.Shape.Representation3D({ repr, source: a }, { label: 'Membrane Orientation' });
});
},
update({ a, b, newParams }, plugin: PluginContext) {
return Task.create('Membrane Orientation', async ctx => {
await MembraneOrientationProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, a.data);
const props = { ...b.data.repr.props, ...newParams };
await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);
return StateTransformer.UpdateResult.Updated;
});
},
isApplicable(a) {
return MembraneOrientationProvider.isApplicable(a.data);
}
});
export const MembraneOrientationPreset = StructureRepresentationPresetProvider({
id: 'preset-membrane-orientation',
display: {
name: 'Membrane Orientation', group: 'Annotation',
description: 'Shows orientation of membrane layers. Data calculated with ANVIL algorithm.' // TODO add ' or obtained via RCSB PDB'
},
isApplicable(a) {
return MembraneOrientationProvider.isApplicable(a.data);
},
params: () => StructureRepresentationPresetProvider.CommonParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
const structure = structureCell?.obj?.data;
if (!structureCell || !structure) return {};
if (!MembraneOrientationProvider.get(structure).value) {
await plugin.runTask(Task.create('Membrane Orientation', async runtime => {
await MembraneOrientationProvider.attach({ runtime, assetManager: plugin.managers.asset }, structure);
}));
}
const membraneOrientation = await tryCreateMembraneOrientation(plugin, structureCell);
const colorTheme = HydrophobicityColorThemeProvider.name as any;
const preset = await PresetStructureRepresentations.auto.apply(ref, { ...params, theme: { globalName: colorTheme, focus: { name: colorTheme } } }, plugin);
return { components: preset.components, representations: { ...preset.representations, membraneOrientation } };
}
});
export function tryCreateMembraneOrientation(plugin: PluginContext, structure: StateObjectRef<PluginStateObject.Molecule.Structure>, params?: StateTransformer.Params<MembraneOrientation3D>, initialState?: Partial<StateTransform.State>) {
const state = plugin.state.data;
const membraneOrientation = state.build().to(structure)
.applyOrUpdateTagged('membrane-orientation-3d', MembraneOrientation3D, params, { state: initialState });
return membraneOrientation.commit({ revertOnError: true });
}

View File

@@ -0,0 +1,82 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Structure, StructureProperties, Unit } from '../../mol-model/structure';
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './algorithm';
import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property';
import { CustomProperty } from '../../mol-model-props/common/custom-property';
import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area';
import { Vec3 } from '../../mol-math/linear-algebra';
import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base';
import { CustomPropSymbol } from '../../mol-script/language/symbol';
import { Type } from '../../mol-script/language/type';
export const MembraneOrientationParams = {
...ANVILParams
};
export type MembraneOrientationParams = typeof MembraneOrientationParams
export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
export { MembraneOrientation };
interface MembraneOrientation {
// point in membrane boundary
readonly planePoint1: Vec3,
// point in opposite side of membrane boundary
readonly planePoint2: Vec3,
// normal vector of membrane layer
readonly normalVector: Vec3,
// the radius of the membrane layer
readonly radius: number,
readonly centroid: Vec3
}
namespace MembraneOrientation {
export enum Tag {
Representation = 'membrane-orientation-3d'
}
const pos = Vec3();
export const symbols = {
isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool),
ctx => {
const { unit, structure } = ctx.element;
const { x, y, z } = StructureProperties.atom;
if (!Unit.isAtomic(unit)) return 0;
const membraneOrientation = MembraneOrientationProvider.get(structure).value;
if (!membraneOrientation) return 0;
Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element));
const { normalVector, planePoint1, planePoint2 } = membraneOrientation!;
return isInMembranePlane(pos, normalVector, planePoint1, planePoint2);
})
};
}
export const MembraneOrientationProvider: CustomStructureProperty.Provider<MembraneOrientationParams, MembraneOrientation> = CustomStructureProperty.createProvider({
label: 'Membrane Orientation',
descriptor: CustomPropertyDescriptor({
name: 'anvil_computed_membrane_orientation',
symbols: MembraneOrientation.symbols,
// TODO `cifExport`
}),
type: 'root',
defaultParams: MembraneOrientationParams,
getParams: (data: Structure) => MembraneOrientationParams,
isApplicable: (data: Structure) => true,
obtain: async (ctx: CustomProperty.Context, data: Structure, props: Partial<MembraneOrientationProps>) => {
const p = { ...PD.getDefaultValues(MembraneOrientationParams), ...props };
return { value: await computeAnvil(ctx, data, p) };
}
});
async function computeAnvil(ctx: CustomProperty.Context, data: Structure, props: Partial<ANVILProps>): Promise<MembraneOrientation> {
await AccessibleSurfaceAreaProvider.attach(ctx, data);
const p = { ...PD.getDefaultValues(ANVILParams), ...props };
return await computeANVIL(data, p).runInContext(ctx.runtime);
}

View File

@@ -0,0 +1,156 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
*/
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Vec3, Mat4 } from '../../mol-math/linear-algebra';
import { Representation, RepresentationContext, RepresentationParamsGetter } from '../../mol-repr/representation';
import { Structure } from '../../mol-model/structure';
import { Spheres } from '../../mol-geo/geometry/spheres/spheres';
import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation';
import { MembraneOrientation } from './prop';
import { ThemeRegistryContext } from '../../mol-theme/theme';
import { ShapeRepresentation } from '../../mol-repr/shape/representation';
import { Shape } from '../../mol-model/shape';
import { RuntimeContext } from '../../mol-task';
import { Lines } from '../../mol-geo/geometry/lines/lines';
import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
import { LinesBuilder } from '../../mol-geo/geometry/lines/lines-builder';
import { Circle } from '../../mol-geo/primitive/circle';
import { transformPrimitive } from '../../mol-geo/primitive/primitive';
import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
import { MembraneOrientationProvider } from './prop';
import { MarkerActions } from '../../mol-util/marker-action';
import { lociLabel } from '../../mol-theme/label';
import { ColorNames } from '../../mol-util/color/names';
import { CustomProperty } from '../../mol-model-props/common/custom-property';
const SharedParams = {
color: PD.Color(ColorNames.lightgrey),
radiusFactor: PD.Numeric(0.8333, { min: 0.1, max: 3.0, step: 0.01 }, { description: 'Scale the radius of the membrane layer' })
};
const BilayerSpheresParams = {
...Spheres.Params,
...SharedParams,
sphereSize: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }, { description: 'Size of spheres that represent membrane planes' }),
density: PD.Numeric(1, { min: 0.25, max: 10, step: 0.25 }, { description: 'Distance between spheres'})
};
export type BilayerSpheresParams = typeof BilayerSpheresParams
export type BilayerSpheresProps = PD.Values<BilayerSpheresParams>
const BilayerPlanesParams = {
...Mesh.Params,
...SharedParams,
sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
};
export type BilayerPlanesParams = typeof BilayerPlanesParams
export type BilayerPlanesProps = PD.Values<BilayerPlanesParams>
const BilayerRimsParams = {
...Lines.Params,
...SharedParams,
lineSizeAttenuation: PD.Boolean(true),
linesSize: PD.Numeric(0.3, { min: 0.01, max: 50, step: 0.01 }),
dashedLines: PD.Boolean(true),
};
export type BilayerRimsParams = typeof BilayerRimsParams
export type BilayerRimsProps = PD.Values<BilayerRimsParams>
const MembraneOrientationVisuals = {
'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }),
'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) })
};
export const MembraneOrientationParams = {
...BilayerSpheresParams,
...BilayerPlanesParams,
...BilayerRimsParams,
visuals: PD.MultiSelect(['bilayer-planes', 'bilayer-rims'], PD.objectToOptions(MembraneOrientationVisuals)),
};
export type MembraneOrientationParams = typeof MembraneOrientationParams
export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
export function getMembraneOrientationParams(ctx: ThemeRegistryContext, structure: Structure) {
return PD.clone(MembraneOrientationParams);
}
export type MembraneOrientationRepresentation = StructureRepresentation<MembraneOrientationParams>
export function MembraneOrientationRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MembraneOrientationParams>): MembraneOrientationRepresentation {
return Representation.createMulti('Membrane Orientation', ctx, getParams, StructureRepresentationStateBuilder, MembraneOrientationVisuals as unknown as Representation.Def<Structure, MembraneOrientationParams>);
}
export const MembraneOrientationRepresentationProvider = StructureRepresentationProvider({
name: 'membrane-orientation',
label: 'Membrane Orientation',
description: 'Displays a grid of points representing membrane layers.',
factory: MembraneOrientationRepresentation,
getParams: getMembraneOrientationParams,
defaultValues: PD.getDefaultValues(MembraneOrientationParams),
defaultColorTheme: { name: 'shape-group' },
defaultSizeTheme: { name: 'shape-group' },
isApplicable: (structure: Structure) => structure.elementCount > 0,
ensureCustomProperties: {
attach: (ctx: CustomProperty.Context, structure: Structure) => MembraneOrientationProvider.attach(ctx, structure, void 0, true),
detach: (data) => MembraneOrientationProvider.ref(data, false)
}
});
function membraneLabel(data: Structure) {
return `${lociLabel(Structure.Loci(data))} | Membrane Orientation`;
}
function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps, shape?: Shape<Lines>): Shape<Lines> {
const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!;
const scaledRadius = props.radiusFactor * radius;
const builder = LinesBuilder.create(128, 64, shape?.geometry);
getLayerCircle(builder, p1, centroid, normal, scaledRadius, props);
getLayerCircle(builder, p2, centroid, normal, scaledRadius, props);
return Shape.create('Bilayer rims', data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data));
}
function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps, shape?: Shape<Lines>) {
const circle = getCircle(p, centroid, normal, radius);
const { indices, vertices } = circle;
for (let j = 0, jl = indices.length; j < jl; j += 3) {
if (props.dashedLines && j % 2 === 1) continue; // draw every other segment to get dashes
const start = indices[j] * 3;
const end = indices[j + 1] * 3;
const startX = vertices[start];
const startY = vertices[start + 1];
const startZ = vertices[start + 2];
const endX = vertices[end];
const endY = vertices[end + 1];
const endZ = vertices[end + 2];
builder.add(startX, startY, startZ, endX, endY, endZ, 0);
}
}
const tmpMat = Mat4();
function getCircle(p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
Mat4.targetTo(tmpMat, p, centroid, normal);
Mat4.setTranslation(tmpMat, p);
Mat4.mul(tmpMat, tmpMat, Mat4.rotX90);
const circle = Circle({ radius, segments: 64 });
return transformPrimitive(circle, tmpMat);
}
function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPlanesProps, shape?: Shape<Mesh>): Shape<Mesh> {
const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!;
const state = MeshBuilder.createState(128, 64, shape && shape.geometry);
const scaledRadius = props.radiusFactor * radius;
getLayerPlane(state, p1, centroid, normal, scaledRadius);
getLayerPlane(state, p2, centroid, normal, scaledRadius);
return Shape.create('Bilayer planes', data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data));
}
function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
const circle = getCircle(p, centroid, normal, radius);
state.currentGroup = 0;
MeshBuilder.addPrimitive(state, Mat4.id, circle);
MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle);
}

View File

@@ -0,0 +1,95 @@
/**
* Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ThemeDataContext } from '../../../mol-theme/theme';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { Color } from '../../../mol-util/color';
import { getPalette } from '../../../mol-util/color/palette';
import { ColorTheme, LocationColor } from '../../../mol-theme/color';
import { ScaleLegend, TableLegend } from '../../../mol-util/legend';
import { StructureElement, Bond, Model } from '../../../mol-model/structure';
import { Location } from '../../../mol-model/location';
import { CellPackInfoProvider } from '../property';
import { distinctColors } from '../../../mol-util/color/distinct';
import { Hcl } from '../../../mol-util/color/spaces/hcl';
const DefaultColor = Color(0xCCCCCC);
const Description = 'Gives every model in a CellPack packing a unique generated color similar to other models in the packing.';
export const CellPackGenerateColorThemeParams = {};
export type CellPackGenerateColorThemeParams = typeof CellPackGenerateColorThemeParams
export function getCellPackGenerateColorThemeParams(ctx: ThemeDataContext) {
return CellPackGenerateColorThemeParams; // TODO return copy
}
export function CellPackGenerateColorTheme(ctx: ThemeDataContext, props: PD.Values<CellPackGenerateColorThemeParams>): ColorTheme<CellPackGenerateColorThemeParams> {
let color: LocationColor;
let legend: ScaleLegend | TableLegend | undefined;
const info = ctx.structure && CellPackInfoProvider.get(ctx.structure).value;
if (ctx.structure && info) {
const colors = distinctColors(info.packingsCount);
let hcl = Hcl.fromColor(Hcl(), colors[info.packingIndex]);
const hue = [Math.max(0, hcl[0] - 35), Math.min(360, hcl[0] + 35)] as [number, number];
const { models } = ctx.structure.root;
let size = 0;
for (const m of models) size = Math.max(size, Model.TrajectoryInfo.get(m).size);
const palette = getPalette(size, { palette: {
name: 'generate',
params: {
hue, chroma: [30, 80], luminance: [15, 85],
clusteringStepCount: 50, minSampleCount: 800, maxCount: 75
}
}}, { minLabel: 'Min', maxLabel: 'Max' });
legend = palette.legend;
const modelColor = new Map<number, Color>();
for (let i = 0, il = models.length; i < il; ++i) {
const idx = Model.TrajectoryInfo.get(models[i]).index;
modelColor.set(Model.TrajectoryInfo.get(models[i]).index, palette.color(idx));
}
color = (location: Location): Color => {
if (StructureElement.Location.is(location)) {
return modelColor.get(Model.TrajectoryInfo.get(location.unit.model).index)!;
} else if (Bond.isLocation(location)) {
return modelColor.get(Model.TrajectoryInfo.get(location.aUnit.model).index)!;
}
return DefaultColor;
};
} else {
color = () => DefaultColor;
}
return {
factory: CellPackGenerateColorTheme,
granularity: 'instance',
color,
props,
description: Description,
legend
};
}
export const CellPackGenerateColorThemeProvider: ColorTheme.Provider<CellPackGenerateColorThemeParams, 'cellpack-generate'> = {
name: 'cellpack-generate',
label: 'CellPack Generate',
category: ColorTheme.Category.Chain,
factory: CellPackGenerateColorTheme,
getParams: getCellPackGenerateColorThemeParams,
defaultValues: PD.getDefaultValues(CellPackGenerateColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => {
return (
!!ctx.structure && ctx.structure.elementCount > 0 &&
!!CellPackInfoProvider.get(ctx.structure).value
);
}
};

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ThemeDataContext } from '../../../mol-theme/theme';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { Color } from '../../../mol-util/color';
import { ColorTheme, LocationColor } from '../../../mol-theme/color';
import { ScaleLegend, TableLegend } from '../../../mol-util/legend';
import { StructureElement, Model, Bond } from '../../../mol-model/structure';
import { Location } from '../../../mol-model/location';
import { CellPackInfoProvider } from '../property';
const DefaultColor = Color(0xCCCCCC);
const Description = 'Gives every model in a CellPack the color provied in the packing data.';
export const CellPackProvidedColorThemeParams = {};
export type CellPackProvidedColorThemeParams = typeof CellPackProvidedColorThemeParams
export function getCellPackProvidedColorThemeParams(ctx: ThemeDataContext) {
return CellPackProvidedColorThemeParams; // TODO return copy
}
export function CellPackProvidedColorTheme(ctx: ThemeDataContext, props: PD.Values<CellPackProvidedColorThemeParams>): ColorTheme<CellPackProvidedColorThemeParams> {
let color: LocationColor;
let legend: ScaleLegend | TableLegend | undefined;
const info = ctx.structure && CellPackInfoProvider.get(ctx.structure).value;
if (ctx.structure && info?.colors) {
const { models } = ctx.structure.root;
const modelColor = new Map<number, Color>();
for (let i = 0, il = models.length; i < il; ++i) {
const idx = Model.TrajectoryInfo.get(models[i]).index;
modelColor.set(Model.TrajectoryInfo.get(models[i]).index, info.colors[idx]);
}
color = (location: Location): Color => {
if (StructureElement.Location.is(location)) {
return modelColor.get(Model.TrajectoryInfo.get(location.unit.model).index)!;
} else if (Bond.isLocation(location)) {
return modelColor.get(Model.TrajectoryInfo.get(location.aUnit.model).index)!;
}
return DefaultColor;
};
} else {
color = () => DefaultColor;
}
return {
factory: CellPackProvidedColorTheme,
granularity: 'instance',
color,
props,
description: Description,
legend
};
}
export const CellPackProvidedColorThemeProvider: ColorTheme.Provider<CellPackProvidedColorThemeParams, 'cellpack-provided'> = {
name: 'cellpack-provided',
label: 'CellPack Provided',
category: ColorTheme.Category.Chain,
factory: CellPackProvidedColorTheme,
getParams: getCellPackProvidedColorThemeParams,
defaultValues: PD.getDefaultValues(CellPackProvidedColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => {
return (
!!ctx.structure && ctx.structure.elementCount > 0 &&
Model.TrajectoryInfo.get(ctx.structure.models[0]).size > 1 &&
!!CellPackInfoProvider.get(ctx.structure).value?.colors
);
}
};

View File

@@ -0,0 +1,229 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Ludovic Autin <autin@scripps.edu>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3, Quat, Mat4 } from '../../mol-math/linear-algebra';
import { NumberArray } from '../../mol-util/type-helpers';
interface Frame {
t: Vec3,
r: Vec3,
s: Vec3,
}
const a0Tmp = Vec3();
const a1Tmp = Vec3();
const a2Tmp = Vec3();
const a3Tmp = Vec3();
function CubicInterpolate(out: Vec3, y0: Vec3, y1: Vec3, y2: Vec3, y3: Vec3, mu: number): Vec3 {
const mu2 = mu * mu;
Vec3.sub(a0Tmp, y3, y2);
Vec3.sub(a0Tmp, a0Tmp, y0);
Vec3.add(a0Tmp, a0Tmp, y1);
Vec3.sub(a1Tmp, y0, y1);
Vec3.sub(a1Tmp, a1Tmp, a0Tmp);
Vec3.sub(a2Tmp, y2, y0);
Vec3.copy(a3Tmp, y1);
out[0] = a0Tmp[0] * mu * mu2 + a1Tmp[0] * mu2 + a2Tmp[0] * mu + a3Tmp[0];
out[1] = a0Tmp[1] * mu * mu2 + a1Tmp[1] * mu2 + a2Tmp[1] * mu + a3Tmp[1];
out[2] = a0Tmp[2] * mu * mu2 + a1Tmp[2] * mu2 + a2Tmp[2] * mu + a3Tmp[2];
return out;
}
const cp0 = Vec3();
const cp1 = Vec3();
const cp2 = Vec3();
const cp3 = Vec3();
const currentPosition = Vec3();
function ResampleControlPoints(points: NumberArray, segmentLength: number) {
const nP = points.length / 3;
// insert a point at the end and at the begining
// controlPoints.Insert(0, controlPoints[0] + (controlPoints[0] - controlPoints[1]) / 2.0f);
// controlPoints.Add(controlPoints[nP - 1] + (controlPoints[nP - 1] - controlPoints[nP - 2]) / 2.0f);
let resampledControlPoints: Vec3[] = [];
// resampledControlPoints.Add(controlPoints[0]);
// resampledControlPoints.Add(controlPoints[1]);
let idx = 1;
// const currentPosition = Vec3.create(points[idx * 3], points[idx * 3 + 1], points[idx * 3 + 2])
Vec3.fromArray(currentPosition, points, idx * 3);
let lerpValue = 0.0;
// Normalize the distance between control points
while (true) {
if (idx + 2 >= nP) break;
Vec3.fromArray(cp0, points, (idx - 1) * 3);
Vec3.fromArray(cp1, points, idx * 3);
Vec3.fromArray(cp2, points, (idx + 1) * 3);
Vec3.fromArray(cp3, points, (idx + 2) * 3);
// const cp0 = Vec3.create(points[(idx-1)*3], points[(idx-1)*3+1], points[(idx-1)*3+2]) // controlPoints[currentPointId - 1];
// const cp1 = Vec3.create(points[idx*3], points[idx*3+1], points[idx*3+2]) // controlPoints[currentPointId];
// const cp2 = Vec3.create(points[(idx+1)*3], points[(idx+1)*3+1], points[(idx+1)*3+2]) // controlPoints[currentPointId + 1];
// const cp3 = Vec3.create(points[(idx+2)*3], points[(idx+2)*3+1], points[(idx+2)*3+2]); // controlPoints[currentPointId + 2];
let found = false;
for (; lerpValue <= 1; lerpValue += 0.01) {
// lerp?slerp
// let candidate:Vec3 = Vec3.lerp(Vec3.zero(), cp0, cp1, lerpValue);
// const candidate:Vec3 = Vec3.bezier(Vec3.zero(), cp0, cp1, cp2, cp3, lerpValue);
const candidate = CubicInterpolate(Vec3(), cp0, cp1, cp2, cp3, lerpValue);
const d = Vec3.distance(currentPosition, candidate);
if (d > segmentLength) {
resampledControlPoints.push(candidate);
Vec3.copy(currentPosition, candidate);
found = true;
break;
}
}
if (!found) {
lerpValue = 0;
idx += 1;
}
}
return resampledControlPoints;
}
const prevV = Vec3();
const tmpV1 = Vec3();
const tmpV2 = Vec3();
const tmpV3 = Vec3();
// easier to align to theses normals
function GetSmoothNormals(points: Vec3[]) {
const nP: number = points.length;
const smoothNormals: Vec3[] = [];
if (points.length < 3) {
for (let i = 0; i < points.length; ++i)
smoothNormals.push(Vec3.normalize(Vec3(), points[i]));
return smoothNormals;
}
let p0 = points[0];
let p1 = points[1];
let p2 = points[2];
const p21 = Vec3.sub(tmpV1, p2, p1);
const p01 = Vec3.sub(tmpV2, p0, p1);
const p0121 = Vec3.cross(tmpV3, p01, p21);
Vec3.normalize(prevV, p0121);
smoothNormals.push(Vec3.clone(prevV));
for (let i = 1; i < points.length - 1; ++i) {
p0 = points[i - 1];
p1 = points[i];
p2 = points[i + 1];
const t = Vec3.normalize(tmpV1, Vec3.sub(tmpV1, p2, p0));
const b = Vec3.normalize(tmpV2, Vec3.cross(tmpV2, t, prevV));
const n = Vec3.normalize(Vec3(), Vec3.cross(tmpV3, t, b));
Vec3.negate(n, n);
Vec3.copy(prevV, n);
smoothNormals.push(n);
}
const last = Vec3();
Vec3.normalize(last, Vec3.cross(last,
Vec3.sub(tmpV1, points[nP - 3], points[nP - 2]),
Vec3.sub(tmpV2, points[nP - 2], points[nP - 1]))
);
smoothNormals.push(last);
return smoothNormals;
}
const frameTmpV1 = Vec3();
const frameTmpV2 = Vec3();
const frameTmpV3 = Vec3();
function getFrame(reference: Vec3, tangent: Vec3) {
const t = Vec3.normalize(Vec3(), tangent);
// make reference vector orthogonal to tangent
const proj_r_to_t = Vec3.scale(
frameTmpV1, tangent, Vec3.dot(reference, tangent) / Vec3.dot(tangent, tangent)
);
const r = Vec3.normalize(Vec3(), Vec3.sub(frameTmpV2, reference, proj_r_to_t));
// make bitangent vector orthogonal to the others
const s = Vec3.normalize(Vec3(), Vec3.cross(frameTmpV3, t, r));
return { t, r, s };
}
const mfTmpV1 = Vec3();
const mfTmpV2 = Vec3();
const mfTmpV3 = Vec3();
const mfTmpV4 = Vec3();
const mfTmpV5 = Vec3();
const mfTmpV6 = Vec3();
const mfTmpV7 = Vec3();
const mfTmpV8 = Vec3();
const mfTmpV9 = Vec3();
// easier to align to theses normals
// https://github.com/bzamecnik/gpg/blob/master/rotation-minimizing-frame/rmf.py
function GetMiniFrame(points: Vec3[], normals: Vec3[]) {
const frames: Frame[] = [];
const t0 = Vec3.normalize(mfTmpV1, Vec3.sub(mfTmpV1, points[1], points[0]));
frames.push(getFrame(normals[0], t0));
for (let i = 0; i < points.length - 2; ++i) {
const t2 = Vec3.normalize(mfTmpV1, Vec3.sub(mfTmpV1, points[i + 2], points[i + 1]));
const v1 = Vec3.sub(mfTmpV2, points[i + 1], points[i]); // this is tangeant
const c1 = Vec3.dot(v1, v1);
// compute r_i^L = R_1 * r_i
const v1r = Vec3.scale(mfTmpV3, v1, (2.0 / c1) * Vec3.dot(v1, frames[i].r));
const ref_L_i = Vec3.sub(mfTmpV4, frames[i].r, v1r);
// compute t_i^L = R_1 * t_i
const v1t = Vec3.scale(mfTmpV5, v1, (2.0 / c1) * Vec3.dot(v1, frames[i].t));
const tan_L_i = Vec3.sub(mfTmpV6, frames[i].t, v1t);
// # compute reflection vector of R_2
const v2 = Vec3.sub(mfTmpV7, t2, tan_L_i);
const c2 = Vec3.dot(v2, v2);
// compute r_(i+1) = R_2 * r_i^L
const v2l = Vec3.scale(mfTmpV8, v1, (2.0 / c2) * Vec3.dot(v2, ref_L_i));
const ref_next = Vec3.sub(mfTmpV9, ref_L_i, v2l); // ref_L_i - (2 / c2) * v2.dot(ref_L_i) * v2
frames.push(getFrame(ref_next, t2)); // frames.append(Frame(ref_next, tangents[i+1]))
}
return frames;
}
const rpTmpVec1 = Vec3();
export function getMatFromResamplePoints(points: NumberArray, segmentLength: number, resample: boolean) {
let new_points: Vec3[] = [];
if (resample) new_points = ResampleControlPoints(points, segmentLength);
else {
for (let idx = 0; idx < points.length / 3; ++idx){
new_points.push(Vec3.fromArray(Vec3.zero(), points, idx * 3));
}
}
const npoints = new_points.length;
const new_normal = GetSmoothNormals(new_points);
const frames = GetMiniFrame(new_points, new_normal);
const limit = npoints;
const transforms: Mat4[] = [];
const pti = Vec3.copy(rpTmpVec1, new_points[0]);
for (let i = 0; i < npoints - 2; ++i) {
const pti1: Vec3 = new_points[i + 1]; // Vec3.create(points[(i+1)*3],points[(i+1)*3+1],points[(i+1)*3+2]);
const d = Vec3.distance(pti, pti1);
if (d >= segmentLength) {
// use twist or random?
const quat = Quat.rotationTo(Quat.zero(), Vec3.create(0, 0, 1), frames[i].t); // Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),new_normal[i]);//Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),direction);new_normal
const rq = Quat.setAxisAngle(Quat.zero(), frames[i].t, Math.random() * 3.60 ); // Quat.setAxisAngle(Quat.zero(),direction, Math.random()*3.60 );//Quat.identity();//
const m = Mat4.fromQuat(Mat4.zero(), Quat.multiply(Quat.zero(), rq, quat)); // Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),quat1,quat2));//Mat4.fromQuat(Mat4.zero(),quat);//Mat4.identity();//Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),rq,quat));
// let pos:Vec3 = Vec3.add(Vec3.zero(),pti1,pti)
// pos = Vec3.scale(pos,pos,1.0/2.0);
// Vec3.makeRotation(Mat4.zero(),Vec3.create(0,0,1),frames[i].t);//
Mat4.setTranslation(m, pti1);
// let m2:Mat4 = GetTubePropertiesMatrix(pti,pti1);
// let q:Quat = Quat.rotationTo(Quat.zero(), Vec3.create(0,1,0),Vec3.create(0,0,1))
// m2=Mat4.mul(Mat4.identity(),Mat4.fromQuat(Mat4.zero(),q),m2);
transforms.push(m);
Vec3.copy(pti, pti1);
}
if (transforms.length >= limit) break;
}
return transforms;
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3, Quat } from '../../mol-math/linear-algebra';
export interface CellPack {
cell: Cell
packings: CellPacking[]
}
export interface CellPacking {
name: string,
location: 'surface' | 'interior' | 'cytoplasme',
ingredients: Packing['ingredients']
}
//
export interface Cell {
recipe: Recipe
cytoplasme?: Packing
compartments?: { [key: string]: Compartment }
}
export interface Recipe {
setupfile: string
paths: [string, string][] // [name: string, path: string][]
version: string
name: string
}
export interface Compartment {
surface?: Packing
interior?: Packing
}
export interface Packing {
ingredients: { [key: string]: Ingredient }
}
export interface Positions {
coords?: Vec3[];
}
export interface Radii {
radii?: number[];
}
export interface Ingredient {
source: IngredientSource;
results: [Vec3, Quat][];
name: string;
/** Vec3[]];CoarseGraind Beads coordinates LOD */
positions?: [Positions];
/** number[]];CoarseGraind Beads radii LOD */
radii?: [Radii];
/** Number of `curveX` properties in the object where `X` is a 0-indexed number */
nbCurve?: number;
uLength?: number;
/** Curve properties are Vec3[] but that is not expressable in TypeScript */
[curveX: string]: unknown;
/** the orientation in the membrane */
principalAxis?: Vec3;
/** offset along membrane */
offset?: Vec3;
ingtype?: string;
color?: Vec3;
confidence?: number;
}
export interface IngredientSource {
pdb: string;
bu?: string; /** biological unit e.g AU,BU1,etc.. */
selection?: string; /** NGL selection or :A or :B etc.. */
model?: string; /** model number e.g 0,1,2... */
transform: {
center: boolean;
translate?: Vec3;
};
biomt?: boolean;
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { PluginBehavior } from '../../mol-plugin/behavior';
import { LoadCellPackModel } from './model';
import { CellPackGenerateColorThemeProvider } from './color/generate';
import { CellPackProvidedColorThemeProvider } from './color/provided';
export const CellPack = PluginBehavior.create<{ autoAttach: boolean, showTooltip: boolean }>({
name: 'cellpack',
category: 'custom-props',
display: {
name: 'CellPack',
description: 'CellPack Model Loading and Viewing.'
},
ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean, showTooltip: boolean }> {
register(): void {
this.ctx.state.data.actions.add(LoadCellPackModel);
this.ctx.representation.structure.themes.colorThemeRegistry.add(CellPackGenerateColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.add(CellPackProvidedColorThemeProvider);
}
unregister() {
this.ctx.state.data.actions.remove(LoadCellPackModel);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(CellPackGenerateColorThemeProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(CellPackProvidedColorThemeProvider);
}
}
});

View File

@@ -0,0 +1,584 @@
/**
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { StateAction, StateBuilder, StateTransformer, State } from '../../mol-state';
import { PluginContext } from '../../mol-plugin/context';
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Ingredient, IngredientSource, CellPacking } from './data';
import { getFromPdb, getFromCellPackDB, IngredientFiles, parseCif, parsePDBfile, getStructureMean, getFromOPM } from './util';
import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit, Trajectory } from '../../mol-model/structure';
import { trajectoryFromMmCIF, MmcifFormat } from '../../mol-model-formats/structure/mmcif';
import { trajectoryFromPDB } from '../../mol-model-formats/structure/pdb';
import { Mat4, Vec3, Quat } from '../../mol-math/linear-algebra';
import { SymmetryOperator } from '../../mol-math/geometry';
import { Task, RuntimeContext } from '../../mol-task';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { ParseCellPack, StructureFromCellpack, DefaultCellPackBaseUrl, StructureFromAssemblies } from './state';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { getMatFromResamplePoints } from './curve';
import { compile } from '../../mol-script/runtime/query/compiler';
import { CifCategory, CifField } from '../../mol-io/reader/cif';
import { mmCIF_Schema } from '../../mol-io/reader/cif/schema/mmcif';
import { Column } from '../../mol-data/db';
import { createModels } from '../../mol-model-formats/structure/basic/parser';
import { CellpackPackingPreset, CellpackMembranePreset } from './preset';
import { Asset } from '../../mol-util/assets';
import { Color } from '../../mol-util/color';
import { readFromFile } from '../../mol-util/data-source';
import { objectForEach } from '../../mol-util/object';
function getCellPackModelUrl(fileName: string, baseUrl: string) {
return `${baseUrl}/results/${fileName}`;
}
class TrajectoryCache {
private map = new Map<string, Trajectory>();
set(id: string, trajectory: Trajectory) { this.map.set(id, trajectory); }
get(id: string) { return this.map.get(id); }
}
async function getModel(plugin: PluginContext, id: string, ingredient: Ingredient, baseUrl: string, trajCache: TrajectoryCache, file?: Asset.File) {
const assetManager = plugin.managers.asset;
const modelIndex = (ingredient.source.model) ? parseInt(ingredient.source.model) : 0;
const surface = (ingredient.ingtype) ? (ingredient.ingtype === 'transmembrane') : false;
let trajectory = trajCache.get(id);
let assets: Asset.Wrapper[] = [];
if (!trajectory) {
if (file) {
if (file.name.endsWith('.cif')) {
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
assets.push(text);
const cif = (await parseCif(plugin, text.data)).blocks[0];
trajectory = await plugin.runTask(trajectoryFromMmCIF(cif));
} else if (file.name.endsWith('.bcif')) {
const binary = await plugin.runTask(assetManager.resolve(file, 'binary'));
assets.push(binary);
const cif = (await parseCif(plugin, binary.data)).blocks[0];
trajectory = await plugin.runTask(trajectoryFromMmCIF(cif));
} else if (file.name.endsWith('.pdb')) {
const text = await plugin.runTask(assetManager.resolve(file, 'string'));
assets.push(text);
const pdb = await parsePDBfile(plugin, text.data, id);
trajectory = await plugin.runTask(trajectoryFromPDB(pdb));
} else {
throw new Error(`unsupported file type '${file.name}'`);
}
} else if (id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) {
if (surface){
try {
const data = await getFromOPM(plugin, id, assetManager);
assets.push(data.asset);
trajectory = await plugin.runTask(trajectoryFromPDB(data.pdb));
} catch (e) {
// fallback to getFromPdb
// console.error(e);
const { mmcif, asset } = await getFromPdb(plugin, id, assetManager);
assets.push(asset);
trajectory = await plugin.runTask(trajectoryFromMmCIF(mmcif));
}
} else {
const { mmcif, asset } = await getFromPdb(plugin, id, assetManager);
assets.push(asset);
trajectory = await plugin.runTask(trajectoryFromMmCIF(mmcif));
}
} else {
const data = await getFromCellPackDB(plugin, id, baseUrl, assetManager);
assets.push(data.asset);
if ('pdb' in data) {
trajectory = await plugin.runTask(trajectoryFromPDB(data.pdb));
} else {
trajectory = await plugin.runTask(trajectoryFromMmCIF(data.mmcif));
}
}
trajCache.set(id, trajectory!);
}
const model = await plugin.resolveTask(trajectory?.getFrameAtIndex(modelIndex)!);
return { model, assets };
}
async function getStructure(plugin: PluginContext, model: Model, source: IngredientSource, props: { assembly?: string } = {}) {
let structure = Structure.ofModel(model);
const { assembly } = props;
if (assembly) {
structure = await plugin.runTask(StructureSymmetry.buildAssembly(structure, assembly));
}
let query;
if (source.selection){
const asymIds: string[] = source.selection.replace(' ', '').replace(':', '').split('or');
query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
'chain-test': MS.core.set.has([MS.set(...asymIds), MS.ammp('auth_asym_id')])
})
]);
} else {
query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
})
]);
}
const compiled = compile<StructureSelection>(query);
const result = compiled(new QueryContext(structure));
structure = StructureSelection.unionStructure(result);
return structure;
}
function getTransformLegacy(trans: Vec3, rot: Quat) {
const q: Quat = Quat.create(-rot[3], rot[0], rot[1], rot[2]);
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q);
Mat4.transpose(m, m);
Mat4.scale(m, m, Vec3.create(-1.0, 1.0, -1.0));
Mat4.setTranslation(m, trans);
return m;
}
function getTransform(trans: Vec3, rot: Quat) {
const q: Quat = Quat.create(rot[0], rot[1], rot[2], rot[3]);
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q);
const p: Vec3 = Vec3.create(trans[0], trans[1], trans[2]);
Mat4.setTranslation(m, p);
return m;
}
function getResultTransforms(results: Ingredient['results'], legacy: boolean) {
if (legacy) return results.map((r: Ingredient['results'][0]) => getTransformLegacy(r[0], r[1]));
else return results.map((r: Ingredient['results'][0]) => getTransform(r[0], r[1]));
}
function getCurveTransforms(ingredient: Ingredient) {
const n = ingredient.nbCurve || 0;
const instances: Mat4[] = [];
let segmentLength = 3.4;
if (ingredient.uLength){
segmentLength = ingredient.uLength;
} else if (ingredient.radii){
segmentLength = ingredient.radii[0].radii
? ingredient.radii[0].radii[0] * 2.0
: 3.4;
}
let resampling: boolean = false;
for (let i = 0; i < n; ++i) {
const cname = `curve${i}`;
if (!(cname in ingredient)) {
// console.warn(`Expected '${cname}' in ingredient`)
continue;
}
const _points = ingredient[cname] as Vec3[];
if (_points.length <= 2) {
// TODO handle curve with 2 or less points
continue;
}
// test for resampling
let distance: number = Vec3.distance(_points[0], _points[1]);
if (distance >= segmentLength + 2.0) {
console.info(distance);
resampling = true;
}
const points = new Float32Array(_points.length * 3);
for (let i = 0, il = _points.length; i < il; ++i) Vec3.toArray(_points[i], points, i * 3);
const newInstances = getMatFromResamplePoints(points, segmentLength, resampling);
instances.push(...newInstances);
}
return instances;
}
function getAssembly(transforms: Mat4[], structure: Structure) {
const builder = Structure.Builder();
const { units } = structure;
for (let i = 0, il = transforms.length; i < il; ++i) {
const id = `${i + 1}`;
const op = SymmetryOperator.create(id, transforms[i], { assembly: { id, operId: i, operList: [ id ] } });
for (const unit of units) {
builder.addWithOperator(unit, op);
}
}
return builder.getStructure();
}
function getCifCurve(name: string, transforms: Mat4[], model: Model) {
if (!MmcifFormat.is(model.sourceData)) throw new Error('mmcif source data needed');
const { db } = model.sourceData.data;
const d = db.atom_site;
const n = d._rowCount;
const rowCount = n * transforms.length;
const { offsets, count } = model.atomicHierarchy.chainAtomSegments;
const x = d.Cartn_x.toArray();
const y = d.Cartn_y.toArray();
const z = d.Cartn_z.toArray();
const Cartn_x = new Float32Array(rowCount);
const Cartn_y = new Float32Array(rowCount);
const Cartn_z = new Float32Array(rowCount);
const map = new Uint32Array(rowCount);
const seq = new Int32Array(rowCount);
let offset = 0;
for (let c = 0; c < count; ++c) {
const cStart = offsets[c];
const cEnd = offsets[c + 1];
const cLength = cEnd - cStart;
for (let t = 0, tl = transforms.length; t < tl; ++t) {
const m = transforms[t];
for (let j = cStart; j < cEnd; ++j) {
const i = offset + j - cStart;
const xj = x[j], yj = y[j], zj = z[j];
Cartn_x[i] = m[0] * xj + m[4] * yj + m[8] * zj + m[12];
Cartn_y[i] = m[1] * xj + m[5] * yj + m[9] * zj + m[13];
Cartn_z[i] = m[2] * xj + m[6] * yj + m[10] * zj + m[14];
map[i] = j;
seq[i] = t + 1;
}
offset += cLength;
}
}
function multColumn<T>(column: Column<T>) {
const array = column.toArray();
return Column.ofLambda({
value: row => array[map[row]],
areValuesEqual: (rowA, rowB) => map[rowA] === map[rowB] || array[map[rowA]] === array[map[rowB]],
rowCount, schema: column.schema
});
}
const _atom_site: CifCategory.SomeFields<mmCIF_Schema['atom_site']> = {
auth_asym_id: CifField.ofColumn(multColumn(d.auth_asym_id)),
auth_atom_id: CifField.ofColumn(multColumn(d.auth_atom_id)),
auth_comp_id: CifField.ofColumn(multColumn(d.auth_comp_id)),
auth_seq_id: CifField.ofNumbers(seq),
B_iso_or_equiv: CifField.ofColumn(Column.ofConst(0, rowCount, Column.Schema.float)),
Cartn_x: CifField.ofNumbers(Cartn_x),
Cartn_y: CifField.ofNumbers(Cartn_y),
Cartn_z: CifField.ofNumbers(Cartn_z),
group_PDB: CifField.ofColumn(Column.ofConst('ATOM', rowCount, Column.Schema.str)),
id: CifField.ofColumn(Column.ofLambda({
value: row => row,
areValuesEqual: (rowA, rowB) => rowA === rowB,
rowCount, schema: d.id.schema,
})),
label_alt_id: CifField.ofColumn(multColumn(d.label_alt_id)),
label_asym_id: CifField.ofColumn(multColumn(d.label_asym_id)),
label_atom_id: CifField.ofColumn(multColumn(d.label_atom_id)),
label_comp_id: CifField.ofColumn(multColumn(d.label_comp_id)),
label_seq_id: CifField.ofNumbers(seq),
label_entity_id: CifField.ofColumn(Column.ofConst('1', rowCount, Column.Schema.str)),
occupancy: CifField.ofColumn(Column.ofConst(1, rowCount, Column.Schema.float)),
type_symbol: CifField.ofColumn(multColumn(d.type_symbol)),
pdbx_PDB_ins_code: CifField.ofColumn(Column.ofConst('', rowCount, Column.Schema.str)),
pdbx_PDB_model_num: CifField.ofColumn(Column.ofConst(1, rowCount, Column.Schema.int)),
};
const categories = {
entity: CifCategory.ofTable('entity', db.entity),
chem_comp: CifCategory.ofTable('chem_comp', db.chem_comp),
atom_site: CifCategory.ofFields('atom_site', _atom_site)
};
return {
header: name,
categoryNames: Object.keys(categories),
categories
};
}
async function getCurve(plugin: PluginContext, name: string, ingredient: Ingredient, transforms: Mat4[], model: Model) {
const cif = getCifCurve(name, transforms, model);
const curveModelTask = Task.create('Curve Model', async ctx => {
const format = MmcifFormat.fromFrame(cif);
const models = await createModels(format.data.db, format, ctx);
return models.representative;
});
const curveModel = await plugin.runTask(curveModelTask);
return getStructure(plugin, curveModel, ingredient.source);
}
async function getIngredientStructure(plugin: PluginContext, ingredient: Ingredient, baseUrl: string, ingredientFiles: IngredientFiles, trajCache: TrajectoryCache) {
const { name, source, results, nbCurve } = ingredient;
if (source.pdb === 'None') return;
const file = ingredientFiles[source.pdb];
if (!file) {
// TODO can these be added to the library?
if (name === 'HIV1_CAhex_0_1_0') return; // 1VU4CtoH_hex.pdb
if (name === 'HIV1_CAhexCyclophilA_0_1_0') return; // 1AK4fitTo1VU4hex.pdb
if (name === 'iLDL') return; // EMD-5239
if (name === 'peptides') return; // peptide.pdb
if (name === 'lypoglycane') return;
}
// model id in case structure is NMR
const { model, assets } = await getModel(plugin, source.pdb || name, ingredient, baseUrl, trajCache, file);
if (!model) return;
let structure: Structure;
if (nbCurve) {
structure = await getCurve(plugin, name, ingredient, getCurveTransforms(ingredient), model);
} else {
let bu: string|undefined = source.bu ? source.bu : undefined;
if (bu){
if (bu === 'AU') {
bu = undefined;
} else {
bu = bu.slice(2);
}
}
structure = await getStructure(plugin, model, source, { assembly: bu });
// transform with offset and pcp
let legacy: boolean = true;
if (ingredient.offset || ingredient.principalAxis){
legacy = false;
const structureMean = getStructureMean(structure);
Vec3.negate(structureMean, structureMean);
const m1: Mat4 = Mat4.identity();
Mat4.setTranslation(m1, structureMean);
structure = Structure.transform(structure, m1);
if (ingredient.offset){
if (!Vec3.exactEquals(ingredient.offset, Vec3.zero())){
const m: Mat4 = Mat4.identity();
Mat4.setTranslation(m, ingredient.offset);
structure = Structure.transform(structure, m);
}
}
if (ingredient.principalAxis){
if (!Vec3.exactEquals(ingredient.principalAxis, Vec3.unitZ)){
const q: Quat = Quat.identity();
Quat.rotationTo(q, ingredient.principalAxis, Vec3.unitZ);
const m: Mat4 = Mat4.fromQuat(Mat4.zero(), q);
structure = Structure.transform(structure, m);
}
}
}
structure = getAssembly(getResultTransforms(results, legacy), structure);
}
return { structure, assets };
}
export function createStructureFromCellPack(plugin: PluginContext, packing: CellPacking, baseUrl: string, ingredientFiles: IngredientFiles) {
return Task.create('Create Packing Structure', async ctx => {
const { ingredients, name } = packing;
const assets: Asset.Wrapper[] = [];
const trajCache = new TrajectoryCache();
const structures: Structure[] = [];
const colors: Color[] = [];
let skipColors: boolean = false;
for (const iName in ingredients) {
if (ctx.shouldUpdate) await ctx.update(iName);
const ingredientStructure = await getIngredientStructure(plugin, ingredients[iName], baseUrl, ingredientFiles, trajCache);
if (ingredientStructure) {
structures.push(ingredientStructure.structure);
assets.push(...ingredientStructure.assets);
const c = ingredients[iName].color;
if (c){
colors.push(Color.fromNormalizedRgb(c[0], c[1], c[2]));
} else {
skipColors = true;
}
}
}
if (ctx.shouldUpdate) await ctx.update(`${name} - units`);
const units: Unit[] = [];
let offsetInvariantId = 0;
let offsetChainGroupId = 0;
for (const s of structures) {
if (ctx.shouldUpdate) await ctx.update(`${s.label}`);
let maxInvariantId = 0;
let maxChainGroupId = 0;
for (const u of s.units) {
const invariantId = u.invariantId + offsetInvariantId;
const chainGroupId = u.chainGroupId + offsetChainGroupId;
if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId;
units.push(Unit.create(units.length, invariantId, chainGroupId, u.traits, u.kind, u.model, u.conformation.operator, u.elements, u.props));
}
offsetInvariantId += maxInvariantId + 1;
offsetChainGroupId += maxChainGroupId + 1;
}
if (ctx.shouldUpdate) await ctx.update(`${name} - structure`);
const structure = new Structure(units);
for( let i = 0, il = structure.models.length; i < il; ++i) {
Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
}
return { structure, assets, colors: skipColors ? undefined : colors };
});
}
async function handleHivRna(plugin: PluginContext, packings: CellPacking[], baseUrl: string) {
for (let i = 0, il = packings.length; i < il; ++i) {
if (packings[i].name === 'HIV1_capsid_3j3q_PackInner_0_1_0') {
const url = Asset.getUrlAsset(plugin.managers.asset, `${baseUrl}/extras/rna_allpoints.json`);
const json = await plugin.runTask(plugin.managers.asset.resolve(url, 'json', false));
const points = json.data.points as number[];
const curve0: Vec3[] = [];
for (let j = 0, jl = points.length; j < jl; j += 3) {
curve0.push(Vec3.fromArray(Vec3(), points, j));
}
packings[i].ingredients['RNA'] = {
source: { pdb: 'RNA_U_Base.pdb', transform: { center: false } },
results: [],
name: 'RNA',
nbCurve: 1,
curve0
};
}
}
}
async function loadMembrane(plugin: PluginContext, name: string, state: State, params: LoadCellPackModelParams) {
let file: Asset.File | undefined = undefined;
if (params.ingredients !== null) {
const fileName = `${name}.bcif`;
for (const f of params.ingredients) {
if (fileName === f.name) {
file = f;
break;
}
}
if (!file){
// check for cif directly
const cifileName = `${name}.cif`;
for (const f of params.ingredients) {
if (cifileName === f.name) {
file = f;
break;
}
}
}
}
let b = state.build().toRoot();
if (file) {
if (file.name.endsWith('.cif')) {
b = b.apply(StateTransforms.Data.ReadFile, { file, isBinary: false, label: file.name }, { state: { isGhost: true } });
} else if (file.name.endsWith('.bcif')) {
b = b.apply(StateTransforms.Data.ReadFile, { file, isBinary: true, label: file.name }, { state: { isGhost: true } });
}
} else {
const url = Asset.getUrlAsset(plugin.managers.asset, `${params.baseUrl}/membranes/${name}.bcif`);
b = b.apply(StateTransforms.Data.Download, { url, isBinary: true, label: name }, { state: { isGhost: true } });
}
const membrane = await b.apply(StateTransforms.Data.ParseCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.TrajectoryFromMmCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.ModelFromTrajectory, undefined, { state: { isGhost: true } })
.apply(StructureFromAssemblies, undefined, { state: { isGhost: true } })
.commit({ revertOnError: true });
const membraneParams = {
representation: params.preset.representation,
};
await CellpackMembranePreset.apply(membrane, membraneParams, plugin);
}
async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, state: State, params: LoadCellPackModelParams) {
const ingredientFiles = params.ingredients || [];
let cellPackJson: StateBuilder.To<PSO.Format.Json, StateTransformer<PSO.Data.String, PSO.Format.Json>>;
if (params.source.name === 'id') {
const url = Asset.getUrlAsset(plugin.managers.asset, getCellPackModelUrl(params.source.params, params.baseUrl));
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.source.params }, { state: { isGhost: true } });
} else {
const file = params.source.params;
if (!file?.file) {
plugin.log.error('No file selected');
return;
}
let jsonFile: Asset.File;
if (file.name.toLowerCase().endsWith('.zip')) {
const data = await readFromFile(file.file, 'zip').runInContext(runtime);
jsonFile = Asset.File(new File([data['model.json']], 'model.json'));
objectForEach(data, (v, k) => {
if (k === 'model.json') return;
ingredientFiles.push(Asset.File(new File([v], k)));
});
} else {
jsonFile = file;
}
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.ReadFile, { file: jsonFile, isBinary: false, label: jsonFile.name }, { state: { isGhost: true } });
}
const cellPackBuilder = cellPackJson
.apply(StateTransforms.Data.ParseJson, undefined, { state: { isGhost: true } })
.apply(ParseCellPack);
const cellPackObject = await state.updateTree(cellPackBuilder).runInContext(runtime);
const { packings } = cellPackObject.obj!.data;
await handleHivRna(plugin, packings, params.baseUrl);
for (let i = 0, il = packings.length; i < il; ++i) {
const p = { packing: i, baseUrl: params.baseUrl, ingredientFiles };
const packing = await state.build()
.to(cellPackBuilder.ref)
.apply(StructureFromCellpack, p)
.commit({ revertOnError: true });
const packingParams = {
traceOnly: params.preset.traceOnly,
representation: params.preset.representation,
};
await CellpackPackingPreset.apply(packing, packingParams, plugin);
if ( packings[i].location === 'surface' && params.membrane){
await loadMembrane(plugin, packings[i].name, state, params);
}
}
}
const LoadCellPackModelParams = {
source: PD.MappedStatic('id', {
'id': PD.Select('InfluenzaModel2.json', [
['blood_hiv_immature_inside.json', 'Blood HIV immature'],
['HIV_immature_model.json', 'HIV immature'],
['BloodHIV1.0_mixed_fixed_nc1.cpr', 'Blood HIV'],
['HIV-1_0.1.6-8_mixed_radii_pdb.cpr', 'HIV'],
['influenza_model1.json', 'Influenza envelope'],
['InfluenzaModel2.json', 'Influenza Complete'],
['ExosomeModel.json', 'Exosome Model'],
['Mycoplasma1.5_mixed_pdb_fixed.cpr', 'Mycoplasma simple'],
['MycoplasmaModel.json', 'Mycoplasma WholeCell model'],
] as const, { description: 'Download the model definition with `id` from the server at `baseUrl.`' }),
'file': PD.File({ accept: '.json,.cpr,.zip', description: 'Open model definition from .json/.cpr file or open .zip file containing model definition plus ingredients.' }),
}, { options: [['id', 'Id'], ['file', 'File']] }),
baseUrl: PD.Text(DefaultCellPackBaseUrl),
membrane: PD.Boolean(true),
ingredients: PD.FileList({ accept: '.cif,.bcif,.pdb', label: 'Ingredients' }),
preset: PD.Group({
traceOnly: PD.Boolean(false),
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'orientation']))
}, { isExpanded: true })
};
type LoadCellPackModelParams = PD.Values<typeof LoadCellPackModelParams>
export const LoadCellPackModel = StateAction.build({
display: { name: 'Load CellPack', description: 'Open or download a model' },
params: LoadCellPackModelParams,
from: PSO.Root
})(({ state, params }, ctx: PluginContext) => Task.create('CellPack Loader', async taskCtx => {
await loadPackings(ctx, taskCtx, state, params);
}));

View File

@@ -4,16 +4,18 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { StateObjectRef } from '../../../../mol-state';
import { StructureRepresentationPresetProvider, presetStaticComponent } from '../../../../mol-plugin-state/builder/structure/representation-preset';
import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
import { ColorNames } from '../../../../mol-util/color/names';
import { CellPackColorThemeProvider } from './color';
import { StateObjectRef } from '../../mol-state';
import { StructureRepresentationPresetProvider, presetStaticComponent } from '../../mol-plugin-state/builder/structure/representation-preset';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { ColorNames } from '../../mol-util/color/names';
import { CellPackGenerateColorThemeProvider } from './color/generate';
import { CellPackInfoProvider } from './property';
import { CellPackProvidedColorThemeProvider } from './color/provided';
export const CellpackPackingPresetParams = {
traceOnly: PD.Boolean(true),
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['gaussian-surface', 'spacefill', 'point', 'orientation'])),
}
};
export type CellpackPackingPresetParams = PD.ValuesFor<typeof CellpackPackingPresetParams>
export const CellpackPackingPreset = StructureRepresentationPresetProvider({
@@ -35,18 +37,20 @@ export const CellpackPackingPreset = StructureRepresentationPresetProvider({
if (params.representation === 'gaussian-surface') {
Object.assign(reprProps, {
quality: 'custom', resolution: 10, radiusOffset: 2, doubleSided: false
})
});
} else if (params.representation === 'spacefill' && params.traceOnly) {
Object.assign(reprProps, { sizeFactor: 2 })
Object.assign(reprProps, { sizeFactor: 2 });
}
const info = structureCell.obj?.data && CellPackInfoProvider.get(structureCell.obj?.data).value;
const color = info?.colors ? CellPackProvidedColorThemeProvider.name : CellPackGenerateColorThemeProvider.name;
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, {});
const color = CellPackColorThemeProvider.name
const representations = {
polymer: builder.buildRepresentation<any>(update, components.polymer, { type: params.representation, typeParams: { ...typeParams, ...reprProps }, color }, { tag: 'polymer' })
};
await plugin.updateDataState(update, { revertOnError: true });
await update.commit({ revertOnError: true });
return { components, representations };
}
});
@@ -55,7 +59,7 @@ export const CellpackPackingPreset = StructureRepresentationPresetProvider({
export const CellpackMembranePresetParams = {
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['gaussian-surface', 'spacefill', 'point', 'orientation'])),
}
};
export type CellpackMembranePresetParams = PD.ValuesFor<typeof CellpackMembranePresetParams>
export const CellpackMembranePreset = StructureRepresentationPresetProvider({
@@ -76,7 +80,7 @@ export const CellpackMembranePreset = StructureRepresentationPresetProvider({
if (params.representation === 'gaussian-surface') {
Object.assign(reprProps, {
quality: 'custom', resolution: 10, radiusOffset: 2, doubleSided: false
})
});
}
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, {});
@@ -84,7 +88,8 @@ export const CellpackMembranePreset = StructureRepresentationPresetProvider({
membrane: builder.buildRepresentation(update, components.membrane, { type: 'gaussian-surface', typeParams: { ...typeParams, ...reprProps }, color: 'uniform', colorParams: { value: ColorNames.lightgrey } }, { tag: 'all' })
};
await plugin.updateDataState(update, { revertOnError: true });
await update.commit({ revertOnError: true });
return { components, representations };
}
});

View File

@@ -4,19 +4,22 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { CustomStructureProperty } from '../../../../mol-model-props/common/custom-structure-property'
import { Structure, CustomPropertyDescriptor } from '../../../../mol-model/structure'
import { CustomProperty } from '../../../../mol-model-props/common/custom-property'
import { ParamDefinition as PD } from '../../../../mol-util/param-definition'
import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property';
import { Structure } from '../../mol-model/structure';
import { CustomProperty } from '../../mol-model-props/common/custom-property';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Color } from '../../mol-util/color';
import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
export type CellPackInfoValue = {
packingsCount: number
packingIndex: number
colors?: Color[]
}
const CellPackInfoParams = {
info: PD.Value<CellPackInfoValue>({ packingsCount: 1, packingIndex: 0 }, { isHidden: true })
}
info: PD.Value<CellPackInfoValue>({ packingsCount: 1, packingIndex: 0, colors: undefined }, { isHidden: true })
};
type CellPackInfoParams = PD.Values<typeof CellPackInfoParams>
export const CellPackInfoProvider: CustomStructureProperty.Provider<typeof CellPackInfoParams, CellPackInfoValue> = CustomStructureProperty.createProvider({
@@ -27,6 +30,8 @@ export const CellPackInfoProvider: CustomStructureProperty.Provider<typeof CellP
getParams: (data: Structure) => CellPackInfoParams,
isApplicable: (data: Structure) => true,
obtain: async (ctx: CustomProperty.Context, data: Structure, props: CellPackInfoParams) => {
return { ...CellPackInfoParams.info.defaultValue, ...props.info }
return {
value: { ...CellPackInfoParams.info.defaultValue, ...props.info }
};
}
})
});

View File

@@ -0,0 +1,150 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Task } from '../../mol-task';
import { CellPack as _CellPack, Cell, CellPacking } from './data';
import { createStructureFromCellPack } from './model';
import { IngredientFiles } from './util';
import { Asset } from '../../mol-util/assets';
import { PluginContext } from '../../mol-plugin/context';
import { CellPackInfoProvider } from './property';
import { Structure, StructureSymmetry, Unit, Model } from '../../mol-model/structure';
import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry';
export const DefaultCellPackBaseUrl = 'https://mesoscope.scripps.edu/data/cellPACK_data/cellPACK_database_1.1.0/';
export class CellPack extends PSO.Create<_CellPack>({ name: 'CellPack', typeClass: 'Object' }) { }
export { ParseCellPack };
type ParseCellPack = typeof ParseCellPack
const ParseCellPack = PluginStateTransform.BuiltIn({
name: 'parse-cellpack',
display: { name: 'Parse CellPack', description: 'Parse CellPack from JSON data' },
from: PSO.Format.Json,
to: CellPack
})({
apply({ a }) {
return Task.create('Parse CellPack', async ctx => {
const cell = a.data as Cell;
const packings: CellPacking[] = [];
const { compartments, cytoplasme } = cell;
if (compartments) {
for (const name in compartments) {
const { surface, interior } = compartments[name];
if (surface) packings.push({ name, location: 'surface', ingredients: surface.ingredients });
if (interior) packings.push({ name, location: 'interior', ingredients: interior.ingredients });
}
}
if (cytoplasme) packings.push({ name: 'Cytoplasme', location: 'cytoplasme', ingredients: cytoplasme.ingredients });
return new CellPack({ cell, packings });
});
}
});
export { StructureFromCellpack };
type StructureFromCellpack = typeof ParseCellPack
const StructureFromCellpack = PluginStateTransform.BuiltIn({
name: 'structure-from-cellpack',
display: { name: 'Structure from CellPack', description: 'Create Structure from CellPack Packing' },
from: CellPack,
to: PSO.Molecule.Structure,
params: a => {
const options = a ? a.data.packings.map((d, i) => [i, d.name] as const) : [];
return {
packing: PD.Select(0, options),
baseUrl: PD.Text(DefaultCellPackBaseUrl),
ingredientFiles: PD.FileList({ accept: '.cif,.bcif,.pdb' })
};
}
})({
apply({ a, params, cache }, plugin: PluginContext) {
return Task.create('Structure from CellPack', async ctx => {
const packing = a.data.packings[params.packing];
const ingredientFiles: IngredientFiles = {};
if (params.ingredientFiles !== null) {
for (const file of params.ingredientFiles) {
ingredientFiles[file.name] = file;
}
}
const { structure, assets, colors } = await createStructureFromCellPack(plugin, packing, params.baseUrl, ingredientFiles).runInContext(ctx);
await CellPackInfoProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, structure, {
info: { packingsCount: a.data.packings.length, packingIndex: params.packing, colors }
});
(cache as any).assets = assets;
return new PSO.Molecule.Structure(structure, { label: packing.name });
});
},
dispose({ b, cache }) {
const assets = (cache as any).assets as Asset.Wrapper[];
if(assets) {
for (const a of assets) a.dispose();
}
if (b) {
b.data.customPropertyDescriptors.dispose();
for (const m of b.data.models) {
m.customProperties.dispose();
}
}
}
});
export { StructureFromAssemblies };
type StructureFromAssemblies = typeof StructureFromAssemblies
const StructureFromAssemblies = PluginStateTransform.BuiltIn({
name: 'Structure from all assemblies',
display: { name: 'Structure from all assemblies' },
from: PSO.Molecule.Model,
to: PSO.Molecule.Structure,
params: {
}
})({
canAutoUpdate({ newParams }) {
return true;
},
apply({ a, params }) {
return Task.create('Build Structure', async ctx => {
// TODO: optimze
// TODO: think of ways how to fast-track changes to this for animations
const model = a.data;
let initial_structure = Structure.ofModel(model);
const structures: Structure[] = [];
let structure: Structure = initial_structure;
// the list of asambly *?
const symmetry = ModelSymmetry.Provider.get(model);
if (symmetry && symmetry.assemblies.length !== 0){
for (const a of symmetry.assemblies) {
const s = await StructureSymmetry.buildAssembly(initial_structure, a.id).runInContext(ctx);
structures.push(s);
}
const builder = Structure.Builder();
let offsetInvariantId = 0;
for (const s of structures) {
let maxInvariantId = 0;
for (const u of s.units) {
const invariantId = u.invariantId + offsetInvariantId;
if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId;
builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, Unit.Trait.None, invariantId);
}
offsetInvariantId += maxInvariantId + 1;
}
structure = builder.getStructure();
for( let i = 0, il = structure.models.length; i < il; ++i) {
Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
}
}
return new PSO.Molecule.Structure(structure, { label: a.label, description: `${a.description}` });
});
},
dispose({ b }) {
b?.data.customPropertyDescriptors.dispose();
}
});

View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { CIF } from '../../mol-io/reader/cif';
import { parsePDB } from '../../mol-io/reader/pdb/parser';
import { AssetManager, Asset } from '../../mol-util/assets';
import { Structure } from '../../mol-model/structure';
import { Vec3 } from '../../mol-math/linear-algebra';
import { PluginContext } from '../../mol-plugin/context';
export async function parseCif(plugin: PluginContext, data: string | Uint8Array) {
const comp = CIF.parse(data);
const parsed = await plugin.runTask(comp);
if (parsed.isError) throw parsed;
return parsed.result;
}
export async function parsePDBfile(plugin: PluginContext, data: string, id: string) {
const comp = parsePDB(data, id);
const parsed = await plugin.runTask(comp);
if (parsed.isError) throw parsed;
return parsed.result;
}
async function downloadCif(plugin: PluginContext, url: string, isBinary: boolean, assetManager: AssetManager) {
const type = isBinary ? 'binary' : 'string';
const asset = await plugin.runTask(assetManager.resolve(Asset.getUrlAsset(assetManager, url), type));
return { cif: await parseCif(plugin, asset.data), asset };
}
async function downloadPDB(plugin: PluginContext, url: string, id: string, assetManager: AssetManager) {
const asset = await assetManager.resolve(Asset.getUrlAsset(assetManager, url), 'string').run();
return { pdb: await parsePDBfile(plugin, asset.data, id), asset };
}
export async function getFromPdb(plugin: PluginContext, pdbId: string, assetManager: AssetManager) {
const { cif, asset } = await downloadCif(plugin, `https://models.rcsb.org/${pdbId.toUpperCase()}.bcif`, true, assetManager);
return { mmcif: cif.blocks[0], asset };
}
export async function getFromOPM(plugin: PluginContext, pdbId: string, assetManager: AssetManager){
const asset = await plugin.runTask(assetManager.resolve(Asset.getUrlAsset(assetManager, `https://opm-assets.storage.googleapis.com/pdb/${pdbId.toLowerCase()}.pdb`), 'string'));
return { pdb: await parsePDBfile(plugin, asset.data, pdbId), asset };
}
export async function getFromCellPackDB(plugin: PluginContext, id: string, baseUrl: string, assetManager: AssetManager) {
if (id.toLowerCase().endsWith('.cif') || id.toLowerCase().endsWith('.bcif')) {
const isBinary = id.toLowerCase().endsWith('.bcif');
const { cif, asset } = await downloadCif(plugin, `${baseUrl}/other/${id}`, isBinary, assetManager);
return { mmcif: cif.blocks[0], asset };
} else {
const name = id.endsWith('.pdb') ? id.substring(0, id.length - 4) : id;
return await downloadPDB(plugin, `${baseUrl}/other/${name}.pdb`, name, assetManager);
}
}
export type IngredientFiles = { [name: string]: Asset.File }
export function getStructureMean(structure: Structure) {
let xSum = 0, ySum = 0, zSum = 0;
for (let i = 0, il = structure.units.length; i < il; ++i) {
const unit = structure.units[i];
const { elements } = unit;
const { x, y, z } = unit.conformation;
for (let j = 0, jl = elements.length; j < jl; ++j) {
const eI = elements[j];
xSum += x(eI);
ySum += y(eI);
zSum += z(eI);
}
}
const { elementCount } = structure;
return Vec3.create(xSum / elementCount, ySum / elementCount, zSum / elementCount);
}

View File

@@ -0,0 +1,10 @@
## DNATCO Extensions
### Confal Pyramids
The Confal Pyramids extensions displays tetrahedron-like pyramids. These pyramids are a simple visual representation of nucleotide conformer classes that can be assigned to individual steps in nucleic acid structures.
For more information, see:
* [Černý et al., Nucleic Acids Research, 44, W284 (2016)](http://dx.doi.org/10.1093/nar/gkw381)
* [Schneider et al., Acta Cryst D, 74, 52-64 (2018)](http://dx.doi.org/10.1107/S2059798318000050)
* [Schneider et al., Genes, 8(10), 278, (2017)](http://dx.doi.org/10.3390/genes8100278)

View File

@@ -0,0 +1,103 @@
/**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Michal Malý <michal.maly@ibt.cas.cz>
* @author Jiří Černý <jiri.cerny@ibt.cas.cz>
*/
import { ConfalPyramidsColorThemeProvider } from './color';
import { ConfalPyramids, ConfalPyramidsProvider } from './property';
import { ConfalPyramidsRepresentationProvider } from './representation';
import { Loci } from '../../../mol-model/loci';
import { PluginBehavior } from '../../../mol-plugin/behavior/behavior';
import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../../mol-plugin-state/builder/structure/representation-preset';
import { StateObjectRef } from '../../../mol-state';
import { Task } from '../../../mol-task';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
export const DnatcoConfalPyramidsPreset = StructureRepresentationPresetProvider({
id: 'preset-structure-representation-confal-pyramids',
display: {
name: 'Confal Pyramids', group: 'Annotation',
description: 'Schematic depiction of conformer class and confal value.',
},
isApplicable(a) {
return a.data.models.length >= 1 && a.data.models.some(m => ConfalPyramids.isApplicable(m));
},
params: () => StructureRepresentationPresetProvider.CommonParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
const model = structureCell?.obj?.data.model;
if (!structureCell || !model) return {};
await plugin.runTask(Task.create('Confal Pyramids', async runtime => {
await ConfalPyramidsProvider.attach({ runtime, assetManager: plugin.managers.asset }, model);
}));
const { components, representations } = await PresetStructureRepresentations.auto.apply(ref, { ...params }, plugin);
const pyramids = await plugin.builders.structure.tryCreateComponentStatic(structureCell, 'nucleic', { label: 'Confal Pyramids' });
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
let pyramidsRepr;
if (representations)
pyramidsRepr = builder.buildRepresentation(update, pyramids, { type: ConfalPyramidsRepresentationProvider, typeParams, color: ConfalPyramidsColorThemeProvider }, { tag: 'confal-pyramdis' } );
await update.commit({ revertOnError: true });
return { components: { ...components, pyramids }, representations: { ...representations, pyramidsRepr } };
}
});
export const DnatcoConfalPyramids = PluginBehavior.create<{ autoAttach: boolean, showToolTip: boolean }>({
name: 'dnatco-confal-pyramids-prop',
category: 'custom-props',
display: {
name: 'Confal Pyramids',
description: 'Schematic depiction of conformer class and confal value.',
},
ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean, showToolTip: boolean }> {
private provider = ConfalPyramidsProvider;
private labelConfalPyramids = {
label: (loci: Loci): string | undefined => {
if (!this.params.showToolTip) return void 0;
/* TODO: Implement this */
return void 0;
}
}
register(): void {
this.ctx.customModelProperties.register(this.provider, this.params.autoAttach);
this.ctx.managers.lociLabels.addProvider(this.labelConfalPyramids);
this.ctx.representation.structure.themes.colorThemeRegistry.add(ConfalPyramidsColorThemeProvider);
this.ctx.representation.structure.registry.add(ConfalPyramidsRepresentationProvider);
this.ctx.builders.structure.representation.registerPreset(DnatcoConfalPyramidsPreset);
}
update(p: { autoAttach: boolean, showToolTip: boolean }) {
const updated = this.params.autoAttach !== p.autoAttach;
this.params.autoAttach = p.autoAttach;
this.params.showToolTip = p.showToolTip;
this.ctx.customModelProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
return updated;
}
unregister() {
this.ctx.customModelProperties.unregister(ConfalPyramidsProvider.descriptor.name);
this.ctx.managers.lociLabels.removeProvider(this.labelConfalPyramids);
this.ctx.representation.structure.registry.remove(ConfalPyramidsRepresentationProvider);
this.ctx.representation.structure.themes.colorThemeRegistry.remove(ConfalPyramidsColorThemeProvider);
this.ctx.builders.structure.representation.unregisterPreset(DnatcoConfalPyramidsPreset);
}
},
params: () => ({
autoAttach: PD.Boolean(true),
showToolTip: PD.Boolean(true)
})
});

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