Compare commits

...

1677 Commits

Author SHA1 Message Date
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
Alexander Rose
4a7413a8d9 0.6.2 2020-04-06 12:43:22 -07:00
Alexander Rose
593b34bfe3 added binding to add loci to current focus 2020-04-06 12:40:24 -07:00
Alexander Rose
691b1721b2 tweaked select mode icon 2020-04-06 11:27:09 -07:00
David Sehnal
b8133b4300 Canvas3dInteractionHelper.maxFps = 30
- makes the interaction feel more responsive
2020-04-06 18:42:10 +02:00
David Sehnal
0c459b98db mol-plugin: added PluginContext.state.updateBehavior 2020-04-06 17:33:22 +02:00
David Sehnal
060725642f mol-plugin: state tree UI fix + remove global current object 2020-04-06 16:45:28 +02:00
David Sehnal
eaf28bf016 fix PDBeStructureQualityReport.autoAttach 2020-04-06 16:23:11 +02:00
David Sehnal
ed6084c40b mol-plugin-ui: optimize state tree rendering 2020-04-06 16:18:23 +02:00
David Sehnal
e56063b065 mol-plugin: selection mode 2020-04-06 15:08:00 +02:00
Alexander Rose
f8ddfb1638 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-05 20:59:49 -07:00
Alexander Rose
900f2e1f76 wip, selection viewport controls
- refactored selection controls as components
- initial css, buggy
2020-04-05 20:59:17 -07:00
David Sehnal
00c9e05a65 mol-plugin-ui: use componentDidUpdated instead of getDerivedStateFromProps where appropriate 2020-04-06 03:20:54 +02:00
Alexander Rose
ecaab51315 support update of props.initiallyCollapsed in CollapsableControls 2020-04-05 17:17:48 -07:00
Alexander Rose
2a4d45714c added npm script and webpack config for viewer debugging
- generates sourcemaps that work with vscode/chrome debugging
2020-04-05 14:18:17 -07:00
Alexander Rose
6e13ef5cbc use webpack.DefinePlugin.runtimeValue for __VERSION__ 2020-04-03 18:54:04 -07:00
Alexander Rose
f48e2ab238 0.6.1 2020-04-03 17:52:16 -07:00
Alexander Rose
0e34d976c0 use version from package.json for plugin 2020-04-03 17:50:50 -07:00
Alexander Rose
2d6cd4c6da package updates 2020-04-03 17:42:59 -07:00
Alexander Rose
4a4b3ef5b4 fix whitespace linting issues 2020-04-03 17:29:59 -07:00
Alexander Rose
67e6167b55 removed orientation from measurements for now
- too limited and confusing
2020-04-03 17:26:32 -07:00
Alexander Rose
79b33bfbd8 selection and focus tweaks
- support highlight for current selection UI
2020-04-03 17:25:36 -07:00
Alexander Rose
f5fc96ee3b more label tweaks
- show entity in locilabel-provider for single-entity loci
- better category handling in focus ui
2020-04-03 16:49:41 -07:00
Alexander Rose
691571ec39 better handling of labels from multiple structures
- intruduced group hash
2020-04-03 15:48:05 -07:00
Alexander Rose
f2b20a646e cellpack tweaks 2020-04-03 12:37:35 -07:00
Alexander Rose
bef9ff86d2 remove console.log 2020-04-03 12:20:07 -07:00
Alexander Rose
ff3da5f2db refactored cellpack loader
- properly handle coloring
- support hiv_lipids loading
2020-04-03 12:09:35 -07:00
Alexander Rose
129727d5d1 calculateTransformBoundingSphere: only use extrema if there are not too many transforms 2020-04-03 12:06:51 -07:00
Alexander Rose
6e26b4d5f9 fix SequenceWrapper type determination
- failed in case of Partitioned chains
2020-04-03 12:06:08 -07:00
Alexander Rose
371bb11ce8 0.6.0 2020-04-02 21:11:10 -07:00
Alexander Rose
556196ae3f wip, cellpack model loader 2020-04-02 21:09:36 -07:00
Alexander Rose
f5667411d7 check if carbs are applicable without calculating them 2020-04-02 20:56:36 -07:00
Alexander Rose
774f419a53 add traceOnly support to element-sphere visual 2020-04-02 20:55:59 -07:00
Alexander Rose
9fa5d40306 improved labels in measurement representations 2020-04-02 18:48:38 -07:00
Alexander Rose
ba89d5ec1e simple PD.Mat4 2020-04-02 17:47:32 -07:00
Alexander Rose
b7fa577d9b improved validation-report and assembly-symmetry presets 2020-04-02 17:21:05 -07:00
David Sehnal
949425d14d mol-plugin-ui: fixed crash caused by invalid state during updates 2020-04-03 00:40:48 +02:00
Alexander Rose
2cb0d63750 added more descriptions and titles
- added description prop to action-item
- use for presets and selection queries
2020-04-02 13:16:14 -07:00
Alexander Rose
038aa47578 update assembly-symmetry UI when repr is added 2020-04-02 12:01:42 -07:00
Alexander Rose
c833598c26 improved computing of covalent bonds with hydrogen
- added more X-H pair thresholds
- removed maxCovalentHydrogenBondingLength param
2020-04-02 11:20:24 -07:00
Alexander Rose
489c52361a measurement label tweaks 2020-04-02 10:18:01 -07:00
David Sehnal
9edf41a2f2 model-server: requestTimeout config option 2020-04-02 16:08:05 +02:00
David Sehnal
5bcca99f60 mol-plugin: support request body in Download(Blob) transforms 2020-04-02 14:33:29 +02:00
David Sehnal
1b0a310fc7 mol-state & volume streaming updates
- error cells are no longer considered valid update roots
- volume streaming now better handles initialization errors
2020-04-02 14:27:55 +02:00
David Sehnal
e3e7fa3040 model-server: support tar.gz output in local mode 2020-04-02 13:52:42 +02:00
David Sehnal
5297dd6f11 model-server: query many limit 2020-04-02 12:49:39 +02:00
David Sehnal
c557e93255 model-server: do not apply content-encoing: gzip to tar.gz resposes 2020-04-02 03:03:52 +02:00
Alexander Rose
ad5f0c987a 0.6.0-dev.11 2020-04-01 17:32:01 -07:00
Alexander Rose
30aa6d035d tweaked volume streaming labels 2020-04-01 17:29:15 -07:00
Alexander Rose
b198289fc4 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-01 17:25:25 -07:00
Alexander Rose
51e45085f1 package updates 2020-04-01 17:22:47 -07:00
Alexander Rose
97ebb2dccc fixed labels for MultiChain units 2020-04-01 17:07:53 -07:00
David Sehnal
29d28bd3f4 UI tweaks 2020-04-02 01:40:23 +02:00
David Sehnal
09c5c040f2 Merge branch 'master' of https://github.com/molstar/molstar 2020-04-02 01:26:39 +02:00
David Sehnal
6e60a2f9dc model-server: query-many result as tar.gz 2020-04-02 01:26:30 +02:00
Alexander Rose
5d36108113 added title tooltip to CollapsableControls 2020-04-01 16:16:37 -07:00
Alexander Rose
f4a423ebe5 show mssage when enabling volume streaming fails 2020-04-01 16:13:21 -07:00
Alexander Rose
9942fbe549 added EmdbHeaderServer plugin config item 2020-04-01 14:46:56 -07:00
Alexander Rose
dbde7521e4 improved volume streaming type determination 2020-04-01 14:34:38 -07:00
David Sehnal
6eee3e8368 model-server: refactored result writer 2020-04-01 22:25:25 +02:00
Alexander Rose
cc0ccd7830 made cameraHelper part of drawPass, screenshot improvements 2020-04-01 12:41:33 -07:00
Alexander Rose
7ad25249a9 removed async renderObject creation in cameraHelper 2020-04-01 12:40:29 -07:00
Alexander Rose
687c7d54ff Shape: extracted helper methods 2020-04-01 12:39:16 -07:00
Alexander Rose
d6fff1ffdf Merge pull request #27 from ValentaTomas/ValentaTomas-readme-typo-fix
Fix README typos
2020-04-01 10:54:42 -07:00
David Sehnal
20a8b8892e colored icons for structure tools 2020-04-01 18:50:37 +02:00
David Sehnal
5c09ecc98d StateTree facelift 2020-04-01 18:04:22 +02:00
ValentaTomas
19539a2c9d Fix README typos 2020-04-01 14:54:53 +02:00
David Sehnal
5c093c7f22 mol-canvas-3d: camera transition tweak 2020-04-01 14:30:51 +02:00
Alexander Rose
c43ed90607 improve volume streaming method determination
- take content_type of related entry into account
2020-03-31 22:26:05 -07:00
Alexander Rose
a85242d9c5 improved focus entry computation
- handle branched
- handle Unit.Trait.MultiChain
2020-03-31 18:43:54 -07:00
Alexander Rose
722d2a9c6c include selected values in sequence panel select titles 2020-03-31 17:31:56 -07:00
Alexander Rose
f7d65ff52c avoid breaking long residue names in sequence panel 2020-03-31 16:52:24 -07:00
Alexander Rose
7bee2be12d added traceOnly param to gaussian-surface
- avoids creating trace structure selection with slow labeling, stats and bundle params
2020-03-31 15:31:41 -07:00
Alexander Rose
326649d4f5 fix broken getLoci in Representation.createMulti 2020-03-31 15:28:56 -07:00
David Sehnal
6aba5df55d Merge branch 'master' of https://github.com/molstar/molstar 2020-03-31 21:08:34 +02:00
David Sehnal
57bbcf9425 fixed issue that prevented delayed isBusy and enabled it again
- lesson learned: do not raise events inside property getters
2020-03-31 21:08:15 +02:00
Alexander Rose
08ba34d607 0.6.0-dev.10 2020-03-31 11:15:57 -07:00
David Sehnal
4c122227a7 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-31 20:10:31 +02:00
David Sehnal
e14afb4dad reverted delayed isBusy
- made CSS/code tweaks in the process
2020-03-31 20:10:22 +02:00
Alexander Rose
472def49f6 0.6.0-dev.9 2020-03-31 10:17:54 -07:00
Alexander Rose
90549893e3 added pdbx_entity_instance_feature to mmcif schema 2020-03-31 09:49:18 -07:00
Alexander Rose
73a8e45202 added missing pdbx_branch_scheme fields to mmcif schema 2020-03-31 09:26:29 -07:00
David Sehnal
35df55cb4f CSS & structure type auto-apply tweaks 2020-03-31 17:19:03 +02:00
David Sehnal
c2028d20a8 mol-plugin: do not disable UI for fast updates 2020-03-31 16:35:45 +02:00
David Sehnal
eaffdc6a98 mol-plugin-ui: do not auto-apply symmetry structure types 2020-03-31 15:52:56 +02:00
David Sehnal
0b1e6100a9 mol-canvas-3d: fix camera transition when adding new representations 2020-03-31 15:25:00 +02:00
David Sehnal
2168905c11 StructureHierarchyManager.updateCurrent fix 2020-03-31 14:57:49 +02:00
David Sehnal
f955e6a299 mol-plugin-state: changing structure "type" recreates the subtree
* different assemblies can have different default components
* i.e. assembly 1 doesn't have carbs and asm 2 does
2020-03-31 14:55:59 +02:00
David Sehnal
98f3981e12 Fix CSS issues 2020-03-31 14:12:45 +02:00
Alexander Rose
82f94d20ea wip, cellpack file input 2020-03-31 02:04:18 -07:00
Alexander Rose
fbc6d47117 wip, cellpack loader update 2020-03-31 01:19:07 -07:00
Alexander Rose
6a2e4cf813 handle orphan models and structures in StructureHierarchyManager 2020-03-31 01:18:41 -07:00
Alexander Rose
4aabef7683 package updates 2020-03-31 00:48:40 -07:00
Alexander Rose
74ae91ee1b support initiallyCollapsed in CustomStructureControls 2020-03-31 00:24:17 -07:00
Alexander Rose
8b62766474 add data-color to ButtonProps (for color swatches) 2020-03-30 23:03:20 -07:00
Alexander Rose
2995504916 made StructureMeasurementsControls seperate panel again 2020-03-30 22:56:01 -07:00
Alexander Rose
63f6848d26 0.6.0-dev.8 2020-03-30 22:35:58 -07:00
Alexander Rose
988e429693 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-30 19:27:35 -07:00
David Sehnal
ba1c6ef046 CameraTransitionManager.apply reverse change 2020-03-31 03:49:20 +02:00
David Sehnal
7ceff92a4e fix structure focus camera animation
+ more UI code tweaks
2020-03-31 03:45:48 +02:00
Alexander Rose
1f968b2836 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-30 18:37:14 -07:00
Alexander Rose
d97d7e3b14 AssemblySymmetryControls fixes 2020-03-30 18:37:03 -07:00
Alexander Rose
5c4c4811e4 added .props() to CustomProperty.Provider 2020-03-30 18:35:30 -07:00
David Sehnal
f2a6e63a20 mol-plugin-ui: general refactoring & code improvements 2020-03-31 02:35:58 +02:00
David Sehnal
1aace4a26f mol-plugin-ui: added Button common ctrl 2020-03-31 01:43:04 +02:00
David Sehnal
b1c140d23e IconButton flex prop 2020-03-31 00:42:54 +02:00
David Sehnal
ee16212c31 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-31 00:14:29 +02:00
David Sehnal
f6d232b1c5 mol-plugin-ui: removed unused CSS 2020-03-31 00:14:13 +02:00
Alexander Rose
c8a002933e take PluginContext.spec into account for SimpleSettingsMapping.layout 2020-03-30 14:55:28 -07:00
Alexander Rose
4757ca9913 fix clashes variable in validationReportPreset 2020-03-30 14:30:00 -07:00
Alexander Rose
5264c75e37 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-30 12:29:23 -07:00
Alexander Rose
032bf44863 package updates (npm audit fix) 2020-03-30 12:02:28 -07:00
David Sehnal
2f4f5e43f3 StructureFocusManager.behaviors.current
replaces events.changed
2020-03-30 20:57:39 +02:00
Alexander Rose
7b1edcadf6 fous fixes and improvements 2020-03-30 11:53:55 -07:00
Alexander Rose
f0f74d182d updated schemas 2020-03-30 11:36:37 -07:00
Alexander Rose
59142adbbc updated packages 2020-03-30 11:26:09 -07:00
Alexander Rose
2fda8c5db1 tweaked assembly symmetry ui 2020-03-30 11:21:07 -07:00
Alexander Rose
7b5efa3e42 LociLabelManager: fold and count identical labels 2020-03-30 10:05:14 -07:00
Alexander Rose
d784d202bd volume streaming: ensure current focus is shown upon registering 2020-03-30 09:52:48 -07:00
Alexander Rose
8833474a43 structure size and quality threshold improvements 2020-03-30 09:51:04 -07:00
David Sehnal
57cbb2f8b6 StructureSourceControls: Fix crash when selecting "Symmetry (assembly)" 2020-03-28 18:01:56 +01:00
David Sehnal
b6112a914f StateTransformer.dispose
- use in StructureRepresentation3D to release custom props
2020-03-28 17:45:16 +01:00
David Sehnal
2008f8538c Various tweaks and fixes
- allow to hide expand button in Viewport
- principal axes fix for single element
- fixes to preset syncing
- CSS fixes
- picking level grouping
2020-03-28 16:46:47 +01:00
David Sehnal
09fba43a1c mol-plugin-state: representation presets "sync" instead of recreate 2020-03-28 14:00:01 +01:00
David Sehnal
b76c3613f9 Focus/Selection UI tweaks 2020-03-28 12:38:39 +01:00
Alexander Rose
cf4ddcb587 label tweaks 2020-03-27 23:42:03 -07:00
Alexander Rose
696106f48b check distance for IntraUnitClashes 2020-03-27 21:54:30 -07:00
Alexander Rose
fb286cd9cf take pixelRatio into account for camera-helper 2020-03-27 21:44:02 -07:00
Alexander Rose
5121bd700e changed assembly-symmetry preset to StructureRepresentationPresetProvider 2020-03-27 21:25:18 -07:00
Alexander Rose
6173520ad0 add validation-report preset 2020-03-27 20:09:17 -07:00
Alexander Rose
a7189232dd wip, StructureFocus controls and manager 2020-03-27 20:00:02 -07:00
Alexander Rose
4a96b45b04 added StructureSelectionQueryRegistry
- register hasClashes, isAccessible, isBuried from their custom props
2020-03-27 19:51:19 -07:00
David Sehnal
20ac549dd6 Plugin UI tweaks
- component focus ensures visibility
- moved measurements to selection section
2020-03-27 18:46:27 +01:00
David Sehnal
38be00c0b7 fix StateTreeNode display bug 2020-03-27 17:10:44 +01:00
David Sehnal
0a9bdc8cf6 model-server: query-many (wip)
+ some UI changes
2020-03-27 16:01:29 +01:00
David Sehnal
0b4318280a cosmetic UI changes 2020-03-27 12:29:51 +01:00
Alexander Rose
b1da60e1c0 wip, focus manager, focus repr refactoring 2020-03-26 18:32:21 -07:00
David Sehnal
2cc5987f9e cosmetic UI changes 2020-03-26 15:52:23 +01:00
David Sehnal
745415a1d8 rename first-model trajectory preset to default 2020-03-26 14:09:50 +01:00
David Sehnal
c80658f368 hide reprLabel in StructureComponentGroup 2020-03-26 13:15:27 +01:00
David Sehnal
033675a417 mol-plugin-ui: GenericEntry.showOnFocus option 2020-03-26 13:09:09 +01:00
David Sehnal
3dd57e9dc8 PD.ColorList refactoring 2020-03-26 12:49:31 +01:00
Alexander Rose
1e3daa6c98 fixed color-theme param getters for palette.scale.list.predefined 2020-03-25 19:44:57 -07:00
Alexander Rose
8855f51cfc Merge branch 'master' of https://github.com/molstar/molstar 2020-03-25 19:33:13 -07:00
Alexander Rose
50d8debb2b refactored assembly-symmetry
- provide a single symmetry-index, story data in AssemblySymmetryDataProvider
2020-03-25 19:32:30 -07:00
Alexander Rose
e682eb78b0 various ui tweaks 2020-03-25 19:31:39 -07:00
Alexander Rose
bd2bbf3e2d plugin: added customStructureControls renamed genericRepresentationControls 2020-03-25 19:30:46 -07:00
Alexander Rose
f38f040aea updated DefaultCellPackBaseUrl 2020-03-25 19:25:02 -07:00
David Sehnal
f912b2d802 proteopedia wrapper bugfix 2020-03-25 21:20:51 +01:00
David Sehnal
0ad03e6a0b custom interpolation list for color palette 2020-03-25 20:46:14 +01:00
Alexander Rose
160d8c529e Merge branch 'master' of https://github.com/molstar/molstar 2020-03-25 10:42:43 -07:00
David Sehnal
28edfd810c mol-model: molstar_atom_site_operator_mapping parsing 2020-03-25 18:29:10 +01:00
Alexander Rose
7b931cfb66 wip, assembly-symmetry preset 2020-03-25 10:28:55 -07:00
David Sehnal
5575c61577 mmcif export updates- rename chains with asm/symm/ncs operators- molstar_atom_site_operator_mapping category 2020-03-25 17:32:15 +01:00
Alexander Rose
8f93dce105 tweaked Structure.hasHighSymmetry 2020-03-25 08:48:26 -07:00
David Sehnal
0eb3d7226a SymmetryOperator.create refactor, added SymmetryOperator.suffix 2020-03-25 15:56:20 +01:00
Alexander Rose
a9533b666c added TrajectoryHierarchyBuilder 2020-03-24 19:23:13 -07:00
David Sehnal
6d67b4db56 update camera axes default params to make it less distracting 2020-03-24 11:46:38 +01:00
David Sehnal
1b5eff6454 ui improvements
- state tree update/apply transform
- focus label, customize radius
- StructureComponentGroup repr label
2020-03-24 11:41:30 +01:00
Alexander Rose
83fb28cc9d wip, generic representation entry 2020-03-23 19:31:07 -07:00
Alexander Rose
c39ffc0b0e fix Infinity in projection matrix
- ensure near and far are not identical
2020-03-23 19:30:18 -07:00
Alexander Rose
23892cfbdd fixed genericTarget in hierarchy-state tagMap 2020-03-23 19:05:45 -07:00
Alexander Rose
3bdabc444d camera helper param tweaks 2020-03-23 15:14:16 -07:00
Alexander Rose
c233be4467 set isoValue param as essential 2020-03-23 15:08:54 -07:00
Alexander Rose
8468f33803 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-23 14:56:55 -07:00
Alexander Rose
0e77369fdb added camera helper showing orientation axes 2020-03-23 14:55:54 -07:00
Alexander Rose
9fcc8e7977 param handling tweaks 2020-03-23 12:16:57 -07:00
David Sehnal
538371ced8 Remove StructureBuilderTags.Component
+ remove some unused code
2020-03-23 19:11:00 +01:00
Alexander Rose
380887bd22 improved trackball.focusCamera
- radius change is now relative to current radius and not fixed
2020-03-23 11:03:35 -07:00
Alexander Rose
17b4b1cb86 added visible bounding sphere to debug helper 2020-03-23 11:01:33 -07:00
Alexander Rose
3e7c358c07 improved unitcell bounding sphere (added extrema) 2020-03-23 11:00:51 -07:00
Alexander Rose
05b592a173 removed unused runTask canvas3d argument 2020-03-23 11:00:12 -07:00
Alexander Rose
e1d0515fae unified font and svg icons 2020-03-23 10:48:02 -07:00
David Sehnal
d4d3b9645e treat "current interaction" as a "structure component" 2020-03-23 18:14:01 +01:00
David Sehnal
d12d99dcfa remove unused StructureBuilderTags 2020-03-23 17:57:28 +01:00
David Sehnal
174324d21c added 'reds-darker' color list 2020-03-23 15:24:49 +01:00
David Sehnal
26156a5982 ProteopediaWrapper: snapshots 2020-03-23 15:18:40 +01:00
David Sehnal
af5ddf6950 StructureHierarchy now relies less on tags 2020-03-23 15:03:38 +01:00
David Sehnal
2ef35e5fb9 CustomElementProperty label fix 2020-03-23 13:43:52 +01:00
David Sehnal
513bfeaae7 StructureHierarchyManager sync on demand
+ PluginComponent updates
2020-03-23 11:01:37 +01:00
David Sehnal
7311e6f484 mol-plugin-state: StructureCoordinateSystem decorator (wip)
+ SymmetryOperator.assembly now optional
2020-03-22 22:08:37 +01:00
David Sehnal
90ecedcae8 mol-state: StateTransformer.Definition.isDecorator
- moved from StateTransform.isDecorator
- when using StateBuilder.apply:
  * decorators are always "inserted"
  * if a node has a decorator, the transformer is applied to the decorator instead (recursive)
2020-03-22 15:09:33 +01:00
David Sehnal
352a20ac48 camera manager focus multiple loci/spheres
+ show Unitcell control for multiple structures
+ misc fixes
2020-03-21 13:07:35 +01:00
David Sehnal
b1d8c5f6ea mol-plugin-ui: left panel tweak 2020-03-21 12:16:45 +01:00
Alexander Rose
6497be9e52 0.6.0-dev.7 2020-03-20 19:14:45 -07:00
Alexander Rose
40a8cee8e5 improved scene bounding sphere (reset) handling 2020-03-20 19:13:26 -07:00
Alexander Rose
112cfcac90 0.6.0-dev.6 2020-03-20 14:21:38 -07:00
David Sehnal
8016fcbd54 mol-plugin-state: use 'deposited' as default value for structure if no assembly is present 2020-03-20 21:37:23 +01:00
David Sehnal
6de97f1d03 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-20 21:22:54 +01:00
David Sehnal
204075bbe0 updateStructureComponent bugfix 2020-03-20 21:22:40 +01:00
David Sehnal
eb448bce37 fix volume streaming with custom props enabled 2020-03-20 20:59:23 +01:00
Alexander Rose
3d09b5cb67 use shallow cloning in PD.merge 2020-03-20 12:53:28 -07:00
Alexander Rose
35d06040f7 update debugHelper when visibility changes 2020-03-20 12:22:07 -07:00
Alexander Rose
0868e81944 improved download density action
- combined pdb providers
2020-03-20 12:08:44 -07:00
Alexander Rose
7efbeb7d0f improved download structure action
- updated pdb-dev url
- added archival pdbe
- combined pdb providers
2020-03-20 11:12:52 -07:00
David Sehnal
815f61b550 StructureHierarchyManagerState: auto-select newly added refs 2020-03-20 16:17:47 +01:00
David Sehnal
c3a90ab499 mol-canvas3d: shouldResetCamera check 2020-03-20 13:35:20 +01:00
David Sehnal
321126afa2 show current selection desc in StructureComponentControls header 2020-03-20 11:52:34 +01:00
Alexander Rose
9ad4a9c3c9 recreate vao to fix attempted binding of deleted attributes 2020-03-19 17:29:04 -07:00
Alexander Rose
b12f7c7ce4 add .name property to ShaderCode 2020-03-19 17:26:43 -07:00
Alexander Rose
6d7d3c0794 unitcell label tweaks 2020-03-19 14:24:32 -07:00
Alexander Rose
92b988a8d5 added PD.merge, always use props from structure.root for custom properties 2020-03-19 14:07:48 -07:00
Alexander Rose
18952ee2bd deepClone fix 2020-03-19 14:03:39 -07:00
David Sehnal
bff07888f9 StructureBuilder.tryCreateComponent* refactoring 2020-03-19 20:32:50 +01:00
David Sehnal
8e6b0b220a do not auto-attach interactions in component manager 2020-03-19 20:12:29 +01:00
David Sehnal
74acb0d078 mol-model-state: fix custom props transform bug 2020-03-19 19:14:11 +01:00
Alexander Rose
d4727eea02 removed console.log statement 2020-03-19 10:07:48 -07:00
Alexander Rose
76d14eba0c fix broken units-representation visual state update 2020-03-19 10:01:57 -07:00
David Sehnal
90d05d9260 fix bug in structure repr interaction 2020-03-19 17:43:11 +01:00
David Sehnal
23b24bbb6c custom props are now included by default
+ structure parent helper now takes decorators into account
+ ui & api tweaks
2020-03-19 15:33:37 +01:00
David Sehnal
91bc6f07c5 mol-plugin-state: added TrajectoryHierarchy presets
refactored representation presets
2020-03-19 12:56:47 +01:00
David Sehnal
9b2181667d mol-plugin-state: do not create empty unit cells 2020-03-19 10:59:35 +01:00
Alexander Rose
40347e3e46 0.6.0-dev.5 2020-03-18 21:16:44 -07:00
Alexander Rose
ed277f6e16 Merge remote-tracking branch 'origin/master' into objects 2020-03-18 21:12:52 -07:00
Alexander Rose
8f2085d8b4 0.6.0-dev.4 2020-03-18 20:59:42 -07:00
Alexander Rose
b5a48ad201 package updates 2020-03-18 20:59:01 -07:00
Alexander Rose
14b900791f wip, unitcell ref 2020-03-18 20:49:30 -07:00
Alexander Rose
de80799e68 allow any Loci in CameraManager.focusLoci 2020-03-18 20:44:54 -07:00
Alexander Rose
53eca387fc take renderable visibility into account for scene bounding-sphere 2020-03-18 20:35:14 -07:00
Alexander Rose
fc3005f271 ui tweaks 2020-03-18 16:47:57 -07:00
Alexander Rose
c95fdff00c tweaked StructureSelectionCategorys 2020-03-18 16:04:09 -07:00
Alexander Rose
3cd9042c72 added helpers to Model, better InitVolumeStreaming.isApplicable check 2020-03-18 15:47:58 -07:00
Alexander Rose
4d3914426e improved LociLabelManager to handle multiple loci 2020-03-18 15:46:29 -07:00
David Sehnal
af1fb7041e removed apps/model-server-query 2020-03-18 18:28:19 +01:00
David Sehnal
e2eb1bf223 model-server: config tweak 2020-03-18 13:49:54 +01:00
David Sehnal
5a64a6f1a3 mol-model: fixed a bug in secondary structure export 2020-03-18 13:45:43 +01:00
David Sehnal
88aa9303d7 model-server: fixed data_source bug, allow fetching source data over http(s) 2020-03-18 13:20:08 +01:00
Alexander Rose
5c77eec184 bounding-sphere fixes
- fixed renderable.spec
- simplify extrema for calculateInvariantBoundingSphere when possible
- fixed Sphere3D.expand
2020-03-17 23:19:26 -07:00
Alexander Rose
a931ed7c01 Merge branch 'master' into objects 2020-03-17 21:46:22 -07:00
Alexander Rose
94cd2b618c wip 2020-03-17 20:17:41 -07:00
Alexander Rose
9c97fc258d better box3d calculation in boundary-helper 2020-03-17 16:35:57 -07:00
Alexander Rose
0ac1cfe555 improved bounding sphere- drop hierarchy in favor of extrema points 2020-03-17 16:28:34 -07:00
Alexander Rose
3942f1bc33 added PickRequired type helper 2020-03-17 15:21:06 -07:00
Alexander Rose
a66e38a901 use unit/structure bounding-sphere in visuals geometry 2020-03-17 12:15:39 -07:00
Alexander Rose
f65f4f4aeb seperate grid and boundary calculation 2020-03-17 12:14:36 -07:00
Alexander Rose
f28b13bf87 shader: fixed broken flat-shaded & flip-sided 2020-03-17 09:48:28 -07:00
David Sehnal
8f211a0785 servers readme tweak 2020-03-17 15:50:05 +01:00
David Sehnal
ba1dfb2851 remove preprocess app from webpack config 2020-03-17 15:35:06 +01:00
David Sehnal
964d56752e 0.6.0-dev.3 2020-03-17 15:32:11 +01:00
David Sehnal
cb6a66eba5 0.6.0-dev.2 2020-03-17 15:25:18 +01:00
David Sehnal
94adf7259d model and volume server configuration and docs 2020-03-17 14:46:28 +01:00
David Sehnal
3c831b549a volume-server JSON config 2020-03-17 12:34:32 +01:00
Alexander Rose
7ccf36a0fa moved unitcell representation to mol-repr/shape 2020-03-16 22:38:46 -07:00
Alexander Rose
b0ee640c12 calc bespoke boundingSphere for unitcell 2020-03-16 22:18:09 -07:00
Alexander Rose
cd6d41a035 allow direct setting of geo bounding sphere
- support mesh, lines, text, spheres, points
2020-03-16 21:20:07 -07:00
Alexander Rose
9c8f1f3e11 wip 2020-03-16 17:20:20 -07:00
Alexander Rose
7c50a5a456 HierarchyHelper: check if the split spheres actually result in a smaller radius 2020-03-16 16:12:13 -07:00
David Sehnal
f3b6703fd4 mol-plugin-ui unsubscribe events 2020-03-16 20:05:06 +01:00
Alexander Rose
60f2716b5a fix missing camera reset from scene with only empty objects 2020-03-16 11:42:11 -07:00
David Sehnal
d7007ef99d CSS oveflow: hidden related fixes 2020-03-16 19:22:01 +01:00
David Sehnal
4aca41cdbb Controls Help in volume streaming controls 2020-03-16 15:54:47 +01:00
David Sehnal
7e31fac99a StructureHierarchy.childRoot for structure/model
- to correctly support decorators like custom props
2020-03-16 15:44:25 +01:00
David Sehnal
3bcf1cb6b5 VolumeStreaming manager & UI 2020-03-16 15:14:56 +01:00
David Sehnal
a29cc74304 StructureSourceControls tweak 2020-03-16 12:00:44 +01:00
David Sehnal
95c43d0864 fix camera.radius = 0 (leads to NaNs) 2020-03-16 11:59:32 +01:00
David Sehnal
369b958335 Refactor Bindings and show them in "Simple settings" 2020-03-16 11:51:05 +01:00
David Sehnal
9a17da8f65 Component UI improvements 2020-03-16 10:59:22 +01:00
Alexander Rose
0c4ba20d6e Merge branch 'master' of https://github.com/molstar/molstar 2020-03-15 23:46:55 -07:00
Alexander Rose
22936ff6c9 canvas3d settings improvements
- added clipping params
- show clipping radius
- ranmed render-style to lighting
2020-03-15 23:46:27 -07:00
David Sehnal
3369ad0bdc Change ParameterControls property name 2020-03-15 23:31:40 +01:00
David Sehnal
20853ef60b StructureSource: hide "actions button" when empty 2020-03-15 23:29:10 +01:00
David Sehnal
da0c66bd8e disable "Selected" button when empty 2020-03-15 23:25:08 +01:00
David Sehnal
44664917ff StateTree: always show remove all button 2020-03-15 23:22:36 +01:00
David Sehnal
ce26e002c7 StructureSource UI 2020-03-15 23:20:00 +01:00
David Sehnal
345b9f546c inline actions and updates in StateTree
mol-plugin code cleanup
2020-03-15 19:50:39 +01:00
David Sehnal
f4ed5e301d mol-plugin: code cleanup 2020-03-15 17:37:54 +01:00
David Sehnal
4818f851b3 measurements ui improvements 2020-03-15 16:54:25 +01:00
David Sehnal
6f2c47c0ca spinSpeed param update 2020-03-15 16:00:53 +01:00
David Sehnal
5e6bc0f0df ui tweaks 2020-03-15 15:47:30 +01:00
David Sehnal
083daa0b76 state undo label 2020-03-15 15:40:29 +01:00
David Sehnal
139a10ba8c do not freeze immer objects 2020-03-15 15:29:50 +01:00
David Sehnal
0b512487f5 add PD.Group.pivot, simplified viewport settings 2020-03-15 15:11:55 +01:00
David Sehnal
a85adfdf1f refactored Repr/Color/Size registry & built-ins
updated component UI
2020-03-15 14:32:04 +01:00
David Sehnal
0171b785af optimized Slider control 2020-03-15 01:37:47 +01:00
David Sehnal
4c1c484af9 PurePluginUIComponent fix 2020-03-15 00:25:53 +01:00
David Sehnal
db7585b6b6 CameraManager 2020-03-15 00:16:25 +01:00
David Sehnal
d263f6d929 allow to undo more than 1 step 2020-03-14 23:17:53 +01:00
David Sehnal
034c28e487 selection history updates
updated measurements ui
added focusLoci/Sphere
Loci stats label fixes
2020-03-14 22:44:36 +01:00
David Sehnal
9a88f57ce6 Unify PluginCommands.Highlight and HighlighAll
Select newly created models and structure for create all models
2020-03-14 20:40:40 +01:00
David Sehnal
28415646a2 StructureComponentManager.updateRepresentations tweak 2020-03-14 17:18:04 +01:00
David Sehnal
b03295ef81 undo button tweak 2020-03-14 16:49:13 +01:00
David Sehnal
7d3e849ff3 undo tweak 2020-03-14 15:24:03 +01:00
David Sehnal
926f20a6a4 mol-state: undo support 2020-03-14 15:21:45 +01:00
David Sehnal
c12d577ce6 Add intersect to Component modify options 2020-03-14 14:17:27 +01:00
David Sehnal
aa8d3a9841 tweak non-convalent interactions size factor 2020-03-14 13:41:59 +01:00
David Sehnal
f11e03eb85 Component UI: show modify operations only if available 2020-03-14 13:36:25 +01:00
David Sehnal
ab996b5189 Selection UI improvements 2020-03-14 13:19:03 +01:00
Alexander Rose
4c91e730a2 various params tweaks
- added more descriptions
- cleaned-up structure related params
- added missing quality categorisation
- clearer picking/granularity param
2020-03-13 23:39:35 -07:00
Alexander Rose
5ca5f44c61 tweaked set svg icons 2020-03-13 18:26:01 -07:00
Alexander Rose
f8a89b1c0d add HighlightMany plugin command 2020-03-13 18:12:30 -07:00
Alexander Rose
99dacef747 check structure equality for StructureElement.Loci 2020-03-13 18:10:20 -07:00
Alexander Rose
24fc37105e revert eslint indent rule (conflicts with switch statement) 2020-03-13 17:16:11 -07:00
Alexander Rose
cbd493d834 use sequential list as default for model-index color theme 2020-03-13 16:59:31 -07:00
Alexander Rose
53dbd1aedf ignore type params in eslint indent rule 2020-03-13 16:27:17 -07:00
Alexander Rose
6ab1af54aa added svg icon shapes for set operations 2020-03-13 15:59:47 -07:00
Alexander Rose
615d9758bb Merge branch 'master' of https://github.com/molstar/molstar 2020-03-13 10:17:20 -07:00
David Sehnal
341f9f8c91 repr/theme/size providers now contain unique name 2020-03-13 17:23:12 +01:00
David Sehnal
ba7d4a5215 customize current interaction, wip refactroring repr registries 2020-03-13 16:33:12 +01:00
David Sehnal
428187ad81 refactoring and tweaks 2020-03-13 13:47:20 +01:00
David Sehnal
fe96172fcd wip structure tools 2020-03-13 13:21:02 +01:00
David Sehnal
8b13be698c mol-plugin-state: StructureHierarchy tweaks 2020-03-13 12:23:04 +01:00
David Sehnal
5edc924e4f unify structure representation params creation 2020-03-13 11:55:06 +01:00
David Sehnal
78c50a4339 build config 2020-03-13 09:49:01 +01:00
Alexander Rose
607284585c intersect modifier for ui selections 2020-03-12 17:46:08 -07:00
Alexander Rose
f7af352f03 package updates 2020-03-12 17:45:10 -07:00
David Sehnal
008ec2c88c use tslib to provide helper functions (saves a lot of code) 2020-03-12 22:53:12 +01:00
David Sehnal
c91074ad91 add watch-viewer npm task for faster build times 2020-03-12 22:19:43 +01:00
David Sehnal
51fbb619e5 UI customization via spec & tweaks 2020-03-12 21:14:20 +01:00
David Sehnal
062c4b335b fix typo 2020-03-12 20:39:46 +01:00
David Sehnal
d4107e273d Merge branch 'master' of https://github.com/molstar/molstar 2020-03-12 20:33:14 +01:00
David Sehnal
4dad67fc2e improved Representation params 2020-03-12 20:33:02 +01:00
David Sehnal
64b0713742 represention preset common props 2020-03-12 20:19:24 +01:00
Alexander Rose
22c45e788e improved renderer and postprocessing params 2020-03-12 11:20:06 -07:00
David Sehnal
75de544669 wip source controls 2020-03-12 18:38:29 +01:00
David Sehnal
768ec10809 removed LociHighligh command extend 2020-03-12 17:29:16 +01:00
David Sehnal
4d5d9be399 wip: source structure manager 2020-03-12 17:26:51 +01:00
David Sehnal
7f4afc111e StructureHierarchyManager.currentTrajectories 2020-03-12 15:06:43 +01:00
David Sehnal
0365f883dd mol-plugin: customuze UI layout in viewport params 2020-03-12 14:04:42 +01:00
David Sehnal
6f98549f31 mol-state: doNotUpdateCurrent false as default 2020-03-12 13:23:49 +01:00
David Sehnal
77920818d9 icon tweak 2020-03-12 13:19:49 +01:00
David Sehnal
0682d54ee2 ActionMenu.Item.disabled 2020-03-12 13:17:11 +01:00
David Sehnal
fbcc3b2fa2 Measurement UI, updated "more options" icon in MappedParam 2020-03-12 12:46:26 +01:00
David Sehnal
c3f47b2ecb mol-plugin-state: component representation update 2020-03-12 12:16:34 +01:00
David Sehnal
8b9f59ac5a mol-plugin: component/selection managers/UI 2020-03-12 12:01:31 +01:00
David Sehnal
362dcabe5c PD.Color.isExpanded property 2020-03-12 07:49:33 +01:00
Alexander Rose
6e205661bd tweak 2020-03-11 23:02:52 -07:00
Alexander Rose
c1a8627702 fix BoundaryHelper edge cases & naming tweaks 2020-03-11 23:00:25 -07:00
Alexander Rose
2c5253943c lint and test fixes 2020-03-11 18:22:16 -07:00
Alexander Rose
03668216fa use EPOS-based boundary-helper throughout 2020-03-11 17:56:04 -07:00
Alexander Rose
37ef234803 wip, improved bounding sphere calculation
- Sphere3D.Hierarchy (one level)
- use hierarchy when merging spheres
- split sphere into two when data unevenly spread
2020-03-11 16:58:21 -07:00
David Sehnal
d25aa97fca ui tweaks 2020-03-11 23:29:36 +01:00
David Sehnal
17dc973305 mol-plugin-state: update label/desc for in custom props transform 2020-03-11 22:08:42 +01:00
David Sehnal
eed4e4a134 tweak 2020-03-11 21:03:21 +01:00
David Sehnal
5fd28c6cad mol-plugin-state: do not update interaction params if they didnt change 2020-03-11 21:00:50 +01:00
David Sehnal
0f69ea197d fix custom property transforms, isBusy behavior, other tweaks 2020-03-11 20:46:57 +01:00
David Sehnal
e1a214e1a8 fix component merging 2020-03-11 18:55:51 +01:00
David Sehnal
e7e14750cb Merge branch 'master' of https://github.com/molstar/molstar 2020-03-11 18:49:46 +01:00
David Sehnal
cb83013967 component ui tweak 2020-03-11 18:49:33 +01:00
Alexander Rose
0a84e1bb7b wip, bounding sphere of spheres calculation improvements 2020-03-11 10:22:51 -07:00
David Sehnal
aee7f4988a removed overpaint and repr helpers 2020-03-11 18:18:42 +01:00
David Sehnal
e762c402fa mol-plugin: component manager options 2020-03-11 18:17:06 +01:00
David Sehnal
4375cae70d structure builder tweaks 2020-03-11 17:26:12 +01:00
David Sehnal
90268a9041 Bundle.fromSubStructure 2020-03-11 16:46:52 +01:00
David Sehnal
a3ebc4df45 mol-plugin: modify component manager/ui 2020-03-11 16:42:59 +01:00
David Sehnal
b2743c76e0 wip mol-plugin managers 2020-03-11 12:58:53 +01:00
Alexander Rose
969a70d571 wip, use EPOS for boundary calculation 2020-03-10 18:50:29 -07:00
Alexander Rose
e6a538dbd7 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-10 17:38:18 -07:00
Alexander Rose
9cffce55c9 added EPOS for bounding sphere calculation 2020-03-10 17:37:57 -07:00
David Sehnal
7bc91d7e99 mol-plugin-state: StructureHierarchy fix 2020-03-10 22:50:41 +01:00
David Sehnal
943f5feb59 mol-plugin-state: TrajectoryFormatProvider 2020-03-10 22:12:41 +01:00
David Sehnal
dc72dbbc97 mol-plugin: PluginContext refactoring 2020-03-10 20:16:41 +01:00
David Sehnal
1513a1e2d2 mol-plugin: code cleanup and refactoring 2020-03-10 19:41:56 +01:00
David Sehnal
82989cae57 mol-plugin-ui: Selection/measurement UI updates 2020-03-10 18:27:20 +01:00
David Sehnal
74f8a5053e refactored StructureSelectionManager 2020-03-10 17:43:32 +01:00
David Sehnal
79f7ea209a wip StructureSelectionManager 2020-03-10 17:14:00 +01:00
David Sehnal
ba65e35c51 refactoring 2020-03-10 15:24:27 +01:00
David Sehnal
5bc4e3ce3b css tweaks 2020-03-10 15:13:43 +01:00
David Sehnal
1c7ac60c11 mol-plugin: state.isBusy behavior 2020-03-10 15:01:24 +01:00
David Sehnal
00cd54b69c mol-state: nested transactions 2020-03-10 14:53:05 +01:00
David Sehnal
90e3a3f0c7 ActionMenu tweak 2020-03-10 13:27:27 +01:00
David Sehnal
5eef3fc42a mol-plugin: Structure components UI 2020-03-10 13:10:47 +01:00
David Sehnal
83a8474731 mol-state: accept partial params for transforms; refactored measurements 2020-03-10 12:15:42 +01:00
Alexander Rose
a5e13c5152 wip, measurements controls improvements 2020-03-09 19:03:15 -07:00
Alexander Rose
b19f53d380 added distanceLabel, angleLabel, dihedralLabel 2020-03-09 19:02:30 -07:00
Alexander Rose
abadef1d2e moved FiniteArray to type helpers 2020-03-09 19:01:17 -07:00
Alexander Rose
a3d976c5b8 consistency fix, Vec3.dihedralAngle now returns radians 2020-03-09 19:00:56 -07:00
Alexander Rose
414b20f06d added Sphere3D.fromSphere3Ds and Loci.getBundleBoundingSphere 2020-03-09 19:00:07 -07:00
David Sehnal
d03a442b6c StructureHierarchyManager tweak 2020-03-09 18:46:00 +01:00
David Sehnal
e5acce03e5 mol-plugin-ui: StructureComponentControls 2020-03-09 18:42:27 +01:00
David Sehnal
fe714d4515 wip: StructureHierarchyManager 2020-03-09 17:27:59 +01:00
David Sehnal
7959344bca Current Interaction -> Focus, Fix StructureSelectionFromBundle 2020-03-08 17:12:40 +01:00
David Sehnal
b9582f171d rename 2020-03-08 15:41:03 +01:00
David Sehnal
410123d933 plugin/state: helpers & fixes 2020-03-08 15:34:15 +01:00
David Sehnal
ae484443d8 decorator transforms 2020-03-08 14:40:23 +01:00
David Sehnal
9d97e56f03 mol-state: StateObjectSelector.update 2020-03-08 13:39:18 +01:00
David Sehnal
01269ec1ef mol-state: use produce in "old params" update 2020-03-08 13:28:34 +01:00
David Sehnal
a204264bcc label fix 2020-03-07 15:53:06 +01:00
David Sehnal
eb0a048926 mol-plugin-ui: strongly typed icons & icons preview HTML 2020-03-07 14:43:57 +01:00
Alexander Rose
ba1509b37a wip, measurements ui 2020-03-06 18:02:47 -08:00
Alexander Rose
ad379e7a32 improved Interactions params 2020-03-06 16:12:46 -08:00
Alexander Rose
9d45beea3b ui: add option to cycle through select options on click 2020-03-06 16:12:16 -08:00
Alexander Rose
b2d134aeb4 added ObjectKeys type helper function 2020-03-06 15:07:20 -08:00
Alexander Rose
d500b8ea19 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-06 13:07:24 -08:00
Alexander Rose
8b3df4b373 plugin-state: preset improvements 2020-03-06 13:07:04 -08:00
David Sehnal
f01fc7c8ba mol-state: log error in transaction 2020-03-06 20:35:57 +01:00
David Sehnal
0e6da0bffa Merge branch 'master' of https://github.com/molstar/molstar 2020-03-06 19:10:58 +01:00
David Sehnal
eab8b1c2bf mol-plugin-state: fix in repr presets 2020-03-06 18:46:41 +01:00
Alexander Rose
8b42a0fede Merge branch 'master' of https://github.com/molstar/molstar 2020-03-06 08:49:13 -08:00
David Sehnal
4bbe078230 custom property reference counting 2020-03-06 17:03:19 +01:00
David Sehnal
aabb931d27 wip Custom Property references 2020-03-06 16:53:24 +01:00
David Sehnal
b1c1b21975 mol-plugin-state: representation components/presets 2020-03-06 14:57:31 +01:00
David Sehnal
7b5dc3ef96 PD.ValuesFor 2020-03-06 14:12:33 +01:00
David Sehnal
1f831f90e0 mol-plugin-state: StructureBuilder 2020-03-06 13:54:14 +01:00
Alexander Rose
ef2c1b51e9 tweaked geometry param info categories 2020-03-05 16:40:19 -08:00
David Sehnal
ace73c041b fix CustomElementProperty color theme 2020-03-05 10:44:55 +01:00
David Sehnal
3c70fe5303 support hiding remote state 2020-03-05 10:03:51 +01:00
Alexander Rose
137e23c025 wip, interactions options for representation panel 2020-03-04 18:18:56 -08:00
Alexander Rose
969a19d515 added defaultParams to CustomProperty.Provider 2020-03-04 18:18:05 -08:00
Alexander Rose
7536abe96c workaround for buggy gl_FrontFacing
- e.g. on some integrated Intel GPUs
2020-03-04 16:27:11 -08:00
Alexander Rose
8e20e163f9 Merge branch 'master' of https://github.com/molstar/molstar 2020-03-04 15:09:16 -08:00
Alexander Rose
adbe8e1f67 take parent structure into account for surface calculations
- new option `includeParent`
2020-03-04 15:08:46 -08:00
David Sehnal
5db134f34f mol-plugin-state: StructureComponent 2020-03-04 19:20:52 +01:00
David Sehnal
80cf7c1dd2 wip state builders 2020-03-04 15:01:46 +01:00
David Sehnal
9e5cc184ed State transactions, better error message for failed downloads 2020-03-04 13:44:38 +01:00
David Sehnal
a5185b456c mol-plugin-state: DataBuilder 2020-03-04 12:56:17 +01:00
Alexander Rose
0615198ad2 0.5.6 2020-03-03 15:13:50 -08:00
Alexander Rose
6cd422f5b3 package updates 2020-03-03 15:13:16 -08:00
Alexander Rose
4416178d6f fix error handling in readData 2020-03-03 14:52:11 -08:00
David Sehnal
b8cef99dc1 ParameterControls fix 2020-03-03 23:04:56 +01:00
David Sehnal
4dcb68af33 ParamDefinition category and hideIf support 2020-03-03 22:45:20 +01:00
David Sehnal
b4c70ab14a fix camera reset when loading stored state 2020-03-03 17:29:51 +01:00
David Sehnal
8436e17af9 removed PD.categories, added PD.isEssential & UI support 2020-03-03 16:05:56 +01:00
David Sehnal
bda04cbdc7 ParamDefinition categories (wip) 2020-03-03 15:27:10 +01:00
David Sehnal
7287947a55 added mol-plugin-state, refactored PluginCommand 2020-03-03 13:46:34 +01:00
David Sehnal
fb5eb1e19c Merge branch 'master' into plugin 2020-03-03 13:11:51 +01:00
David Sehnal
d735dcdc3e mol-plugin-ui: ActionMenu helpers 2020-03-03 13:09:51 +01:00
Alexander Rose
83d8a61400 0.5.5 2020-03-02 17:22:34 -08:00
Alexander Rose
b72f57c040 assembly symmetry tweaks 2020-03-02 17:21:07 -08:00
Alexander Rose
8a7ef1c704 added StructureOverpaintHelper.setFromExpression and alpha prop 2020-03-02 16:28:10 -08:00
Alexander Rose
8731bc13d1 StructureElement.Loci helpers
- firstElement
- firstResidue
- firstChain
2020-03-02 16:27:37 -08:00
Alexander Rose
d103cda0c8 StructureSelectionQuery improvements
- added categories
- StructureSelectionQueryList with standard residues
2020-03-02 14:04:27 -08:00
Alexander Rose
ca4e864e46 StructureRepresentationHelper.getRepresentationParams tweaks 2020-03-02 13:02:27 -08:00
Alexander Rose
0e25950d51 don't remove C! assembly symmetry 2020-03-02 13:01:35 -08:00
David Sehnal
2c29a90b5e fix 2020-03-02 15:32:24 +01:00
David Sehnal
2900836208 mol-canvas3d: requestCameraReset options 2020-03-02 15:28:20 +01:00
Alexander Rose
928a1df525 handle nullish values in SelectControl 2020-02-29 22:09:13 -08:00
Alexander Rose
16e0dff551 molecule types improvements 2020-02-29 22:08:29 -08:00
David Sehnal
7e443d5c9b mol-plugin-ui: simplified ActionMenu, fixed residue/amk selection 2020-02-29 18:15:39 +01:00
David Sehnal
172ae17966 mol-plugin-ui: SelectControl label fix 2020-02-29 15:40:28 +01:00
David Sehnal
8cbf7b5d0a mol-plugin-ui: Controls improvements 2020-02-29 15:27:21 +01:00
Alexander Rose
2c40b85880 0.5.4 2020-02-28 18:29:15 -08:00
Alexander Rose
ad388f23ae package updates 2020-02-28 18:28:39 -08:00
Alexander Rose
27b559a2d8 tweaked color-theme categories 2020-02-28 18:08:33 -08:00
Alexander Rose
c6d19e14c5 improved naming of PDBe and RCSB PDB provided properties 2020-02-28 17:46:10 -08:00
Alexander Rose
b807dca2d8 wip, StructureRepresentationHelper tweaks 2020-02-28 17:13:00 -08:00
Alexander Rose
2cae6e3f59 pass correct themeDataCtx in StructureRepresentation3DHelpers.createParams 2020-02-28 17:12:09 -08:00
Alexander Rose
69c73f3dcd StructureSelectionQuery improvements
- delayed query compilation to work with CustomPropSymbol
- optional async ensureCustomProperties method
- added hasClash, isBuried, isAccessible built-ins
- integrate .ensureCustomProperties with StructureSelectionHelper
2020-02-28 17:11:06 -08:00
Alexander Rose
4456ab2cd5 whitespace 2020-02-28 17:06:13 -08:00
Alexander Rose
bdda18de23 added mol-script symbol to ValidationReport 2020-02-28 17:05:22 -08:00
Alexander Rose
1b2c2f3d41 added Tag enum with common strings to AssemblySymmetry 2020-02-28 17:04:55 -08:00
Alexander Rose
fd19d29ef6 accessible surface area improvements
- added mol-script symbols
- helpers to get normalized value and flag
2020-02-28 17:04:03 -08:00
David Sehnal
1f0c0fd756 mol-geo: VisualQuality label fix 2020-02-27 16:56:28 +01:00
David Sehnal
83698cc52d mol-plugin-ui: ActionMenu fixes 2020-02-27 16:53:11 +01:00
David Sehnal
70b94deb20 tweak 2020-02-27 16:19:46 +01:00
David Sehnal
2da3df6e4d ParamDefinition.Select grouping & used in theme definitions 2020-02-27 16:17:23 +01:00
David Sehnal
509e633a69 mol-plugin-ui: use ActionMenu in SelectControl 2020-02-27 15:09:47 +01:00
David Sehnal
17fac2b82a mol-plugin-ui: ActionMenu refactoring 2020-02-27 14:36:48 +01:00
Alexander Rose
c543c4e10a 0.5.3 2020-02-26 17:20:24 -08:00
Alexander Rose
10073800dc added amino acids and nucleic bases queries 2020-02-26 17:14:40 -08:00
Alexander Rose
04c38250b4 tweaked action-menu offset 2020-02-26 17:14:08 -08:00
Alexander Rose
5ccb329af1 added SetUtils.toArray 2020-02-26 17:13:34 -08:00
Alexander Rose
3cecb53bc5 added model.properties.structAsymMap 2020-02-26 15:04:48 -08:00
Alexander Rose
0daf431d68 added and use cross-link loci/location 2020-02-26 14:23:51 -08:00
Alexander Rose
3e0c4242ad simplified interactions loci/location 2020-02-26 14:23:03 -08:00
Alexander Rose
17b775c377 areDataLociEqual, use shallowEqual to compare data objects 2020-02-26 14:22:05 -08:00
Alexander Rose
4525b98288 SecondaryStructure improvements
- use SecondaryStructureProvider in StructureProperties
- renamed mmCIF source to model
2020-02-26 11:43:15 -08:00
Alexander Rose
755699d479 fix structure/model props attachment 2020-02-26 11:37:57 -08:00
Alexander Rose
a84309b800 add mon_nstd_flag when deriving chemComp 2020-02-26 10:37:36 -08:00
Alexander Rose
16863535b8 cleanup, removed comment 2020-02-26 10:36:37 -08:00
Alexander Rose
dd9773d72e fix pdb parser: need cif-category not table 2020-02-26 10:36:12 -08:00
Alexander Rose
ec45f6c0ee removed 'modified residues'
- use non-standard flag in polymers residues instead to show interesting residues
- 'modified residues' is of limited value to get parent, better rely on chem_comp.type
2020-02-26 09:51:54 -08:00
David Sehnal
59235630bb mol-plugin-ui: ActionMenu, use in selection manager to test 2020-02-26 18:43:56 +01:00
David Sehnal
11ed0ca89b added draft of ParamMapping interface and control 2020-02-26 16:39:24 +01:00
Alexander Rose
188ea6e8e2 skin: fix select button hidden issue in FF 2020-02-25 22:06:52 -08:00
Alexander Rose
293b464d9f moved cross-link-restraint to props 2020-02-25 17:40:08 -08:00
Alexander Rose
0e91aa521e added IntervalControl, use 'step' for precision, allow 'range' in Vec3 2020-02-25 17:39:34 -08:00
Alexander Rose
5272593cc3 ermoved deprecated StructureAssemblyFromModel 2020-02-25 15:10:12 -08:00
Alexander Rose
c5f336b0e4 fix Assembly Symmetry Cluster coloring for deposited model 2020-02-25 14:53:37 -08:00
Alexander Rose
b1a6fa3ffc package updates, remove tslint related package 2020-02-25 14:52:55 -08:00
Alexander Rose
fe47134934 0.5.2 2020-02-25 12:00:59 -08:00
Alexander Rose
131cc606f0 added support to build custom assembly from symmetry operations and asym ids 2020-02-25 11:57:58 -08:00
Alexander Rose
3681f01fad added Spacegroup.getOperatorXyz 2020-02-25 11:56:48 -08:00
Alexander Rose
e966c112ab assymbly-symmetry: filter C1, export AssemblySymmetry3D 2020-02-24 17:25:49 -08:00
David Sehnal
d7b232b00b Merge branch 'master' into plugin 2020-02-24 10:12:35 +01:00
Alexander Rose
7986509ad3 0.5.1 2020-02-21 16:54:42 -08:00
Alexander Rose
73dcf970f3 fix fog handling so fog can be fully switched off 2020-02-21 16:26:14 -08:00
Alexander Rose
9377aa2d05 renamed renderstyle 'toon' to 'flat'
- reflects what the options is actually doing
2020-02-21 16:05:35 -08:00
Alexander Rose
686fa5a5ed package updates 2020-02-21 16:05:01 -08:00
Alexander Rose
c946ae6eab updated schemas, emmit .ts instead of .d.ts 2020-02-21 16:01:41 -08:00
David Sehnal
9b2f1d9415 updated to TypeScript 3.8 2020-02-21 17:13:10 +01:00
Alexander Rose
f6c28aa8e2 0.5.0 2020-02-20 16:25:38 -08:00
David Sehnal
2c327cfdf6 vscode tasks 2020-02-12 12:06:52 +01:00
David Sehnal
307f2efc97 Merge branch 'master' into plugin 2020-02-12 12:02:51 +01:00
David Sehnal
64c51f0d94 Merge branch 'master' into plugin 2020-02-10 11:51:29 +01:00
David Sehnal
7a0b4c4d23 Viewer: load from URL 2019-12-24 11:37:43 +01:00
David Sehnal
f45edbc4f0 mol-theme: truncate too long entry names 2019-12-24 11:27:47 +01:00
David Sehnal
65d3355b18 mol-plugin: DataManager [wip] 2019-12-23 17:19:38 +01:00
1306 changed files with 177420 additions and 68044 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

14
.vscode/tasks.json vendored
View File

@@ -9,6 +9,20 @@
"problemMatcher": [
"$tsc"
]
},
{
"type": "npm",
"script": "build-tsc",
"problemMatcher": [
"$tsc"
]
},
{
"type": "npm",
"script": "watch",
"problemMatcher": [
"$tsc"
]
}
]
}

View File

@@ -5,7 +5,7 @@
# Mol*
The goal of **Mol\*** (*/'mol-star/*) is to provide a technology stack that will serve as basis for the next-generation data delivery and analysis tools for macromolecular structure data. This is a collaboration between PDBe and RCSB PDB teams and the development will be open source and available to anyone who wants to use it for developing visualisation tools for macromolecular structure data available from [PDB](https://www.wwpdb.org/) and other institutions.
The goal of **Mol\*** (*/'mol-star/*) is to provide a technology stack that will serve as a basis for the next-generation data delivery and analysis tools for macromolecular structure data. This is a collaboration between PDBe and RCSB PDB teams and the development will be open-source and available to anyone who wants to use it for developing visualization tools for macromolecular structure data available from [PDB](https://www.wwpdb.org/) and other institutions.
This particular project is the implementation of this technology (still under development).
@@ -16,31 +16,32 @@ This particular project is the implementation of this technology (still under de
The core of Mol* currently consists of these modules (see under `src/`):
- `mol-task` Computation abstraction with progress tracking and cancellation support.
- `mol-data` Collections (integer based sets, interface to columns/tables, etc.)
- `mol-data` Collections (integer-based sets, interface to columns/tables, etc.)
- `mol-math` Math related (loosely) algorithms and data structures.
- `mol-io` Parsing library. Each format is parsed into an interface that corresponds to the data stored by it. Support for common coordinate, experimental/map, and annotation data formats.
- `mol-model` Data structures and algorithms (such as querying) for representing molecular data (including coordinate, experimental/map, and annotation data).
- `mol-model-formats` Data format parsers for `mol-model`.
- `mol-model-props` Common "custom properties".
- `mol-script` A scriting language for creating representations/scenes and querying (includes the [MolQL query language](https://molql.github.io)).
- `mol-script` A scripting language for creating representations/scenes and querying (includes the [MolQL query language](https://molql.github.io)).
- `mol-geo` Creating (molecular) geometries.
- `mol-theme` Theming for structure, volume and shape representations.
- `mol-repr` Molecular representations for structures, volumes and shapes.
- `mol-gl` A wrapper around WebGL.
- `mol-canvas3d` A low level 3d view component. Uses `mol-geo` to generate geometries.
- `mol-canvas3d` A low-level 3d view component. Uses `mol-geo` to generate geometries.
- `mol-state` State representation tree with state saving and automatic updates.
- `mol-app` Components for builduing UIs.
- `mol-app` Components for building UIs.
- `mol-plugin` Allow to define modular Mol* plugin instances utilizing `mol-state` and `mol-canvas3d`.
- `mol-plugin-ui` React based user interface for the Mol* plugin. Some components of the UI are usable outside the main plugin and can be integrated to 3rd party solutions.
- `mol-plugin-state` State transformations, builders, and managers.
- `mol-plugin-ui` React-based user interface for the Mol* plugin. Some components of the UI are usable outside the main plugin and can be integrated into 3rd party solutions.
- `mol-util` Useful things that do not fit elsewhere.
Moreover, the project contains the imlementation of `servers`, including
Moreover, the project contains the implementation of `servers`, including
- `servers/model` A tool for accessing coordinate and annotation data of molecular structures.
- `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:
@@ -61,6 +62,8 @@ This project builds on experience from previous solutions:
### Build automatically on file save:
npm run watch
If working on just the viewer, ``npm run watch-viewer`` will provide shorter compile times.
### Build with debug mode enabled:
DEBUG=molstar npm run watch
@@ -86,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**
@@ -112,22 +123,26 @@ 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
### Intallation
### Installation
If node complains about a missine acorn peer dependency, run the following commands
If node complains about a missing acorn peer dependency, run the following commands
npm update acorn --depth 20
npm dedupe
### Editor
To get syntax highlighting for shader and graphql files add the following to Visual Code's settings files and make sure relevant extanesions are installed in the editor.
To get syntax highlighting for shader and graphql files add the following to Visual Code's settings files and make sure relevant extensions are installed in the editor.
"files.associations": {
"*.glsl.ts": "glsl",
@@ -139,7 +154,7 @@ To get syntax highlighting for shader and graphql files add the following to Vis
## Publish
### Prerelease
npm version prerelease # asumes the current version ends with '-dev.X'
npm version prerelease # assumes the current version ends with '-dev.X'
npm publish --tag next
### Release
@@ -161,4 +176,5 @@ Continually develop this prototype project. As individual modules become stable,
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/)
* [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

@@ -6,133 +6,64 @@ Model Server is a tool for preprocessing and querying macromolecular structure d
Installing and Running
=====================
Getting the code (use node 8+):
Requires nodejs 8+.
## From GitHub
```
git clone https://github.com/molstar/molstar
npm install
```
Customize configuration at ``src/server/model/config.ts`` to point to your data and which custom properties to include (see the [Custom Properties](#custom-properties) section). Alternatively, the config can be edited in the compiled version in ``build/node_modules/servers/model/config.js``.
Afterwards, build the project:
Afterwards, build the project source:
```
npm run build
npm run build-tsc
```
(or run watch mode for automatic rebuilds: ``npm run watch``)
and run the server by
Running the server locally for testing:
```
npm run model-server
```
or
```
node build/node_modules/servers/model/server
node lib/commonjs/servers/model/server/server
```
In production it is a good idea to use a service that will keep the server running, such as [forever.js](https://github.com/foreverjs/forever).
## From NPM
```
npm install --production molstar
./model-server
```
(or ``node node_modules\.bin\model-server`` in Windows).
The NPM package contains all the tools mentioned here as "binaries":
- ``model-server``
- ``model-server-query``
- ``model-server-preprocess``
## Memory issues
### Production use
In production it is required to use a service that will keep the server running, such as [forever.js](https://github.com/foreverjs/forever).
### Memory issues
Sometimes nodejs might run into problems with memory. This is usually resolved by adding the ``--max-old-space-size=8192`` parameter.
Preprocessor
============
## Preprocessor
The preprocessor application allows to add custom data to CIF files and/or convert CIF to BinaryCIF. See the [Custom Properties](#custom-properties) section for providing custom properties.
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.
## Usage
The app works in two modes: single files and folders.
## Local Mode
Single files:
```
node build\node_modules\servers\model\preprocess -i input.cif [-oc output.cif] [-ob output.bcif] [--cfg config.json]
```
Folder:
```
node build\node_modules\servers\model\preprocess -fin input_folder [-foc output_cif_folder] [-fob output_bcif_folder] [--cfg config.json]
```
## Config
The config speficies the maximum number of processes to use (in case of folder processing) and defines sources and parameters for custom properties.
Example:
```json
{
"numProcesses": 4,
"customProperties": {
"sources": [
"./properties/pdbe"
],
"params": {
"PDBe": {
"UseFileSource": false,
"API": {
"residuewise_outlier_summary": "https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry",
"preferred_assembly": "https://www.ebi.ac.uk/pdbe/api/pdb/entry/summary",
"struct_ref_domain": "https://www.ebi.ac.uk/pdbe/api/mappings/sequence_domains"
}
}
}
}
}
```
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
=================
It is possible to provide property descriptors that transform data to internal representation and define how it should be exported into one or mode CIF categories. Examples of this are located in the ``mol-model-props`` module and are linked to the server in the config and ``servers/model/properties``.
This feature is still in development.
Local Mode
==========
The server can be run in local/file based mode:
```
node build/node_modules/servers/model/server jobs.json
```
where ``jobs.json`` is an array of
```ts
type LocalInput = {
input: string,
output: string,
query: QueryName,
modelNums?: number[],
params?: any,
binary?: boolean
}[]
```
For example
```json
[
{
"input": "c:/test/quick/1tqn.cif",
"output": "c:/test/quick/localapi/1tqn_full.cif",
"query": "full"
},
{
"input": "c:/test/quick/1tqn.cif",
"output": "c:/test/quick/localapi/1tqn_full.bcif",
"query": "full",
"params": {}
},
{
"input": "c:/test/quick/1cbs_updated.cif",
"output": "c:/test/quick/localapi/1cbs_ligint.cif",
"query": "residueInteraction",
"params": {
"atom_site": { "label_comp_id": "REA" }
}
}
]
```
It is possible to provide property descriptors that transform data to internal representation and define how it should be exported into one or mode CIF categories. Examples of this are located in the ``mol-model-props`` module and are linked to the server in the config and ``servers/model/properties``.

View File

@@ -7,107 +7,64 @@ It uses the text based CIF and BinaryCIF formats to deliver the data to the clie
For quick info about the benefits of using the server, check out the [examples](examples.md).
Installing the Server
Installing and Running
=====================
- Install [Node.js](https://nodejs.org/en/) (tested on Node 6.* and 7.*; x64 version is strongly preferred).
- Get the code.
- Prepare the data.
- Run the server.
Requires nodejs 8+.
Preparing the Data
------------------
## From GitHub
```
git clone https://github.com/molstar/molstar
npm install
```
Afterwards, build the project source:
```
npm run build-tsc
```
and run the server by
```
node lib/commonjs/servers/volume/server
```
## From NPM
```
npm install --production molstar
./volume-server
```
(or ``node node_modules\.bin\volume-server`` in Windows).
The NPM package contains all the tools mentioned here as "binaries":
- ``volume-server``
- ``volume-server-pack``
- ``volume-server-query``
### Production use
In production it is required to use a service that will keep the server running, such as [forever.js](https://github.com/foreverjs/forever).
### Memory issues
Sometimes nodejs might run into problems with memory. This is usually resolved by adding the ``--max-old-space-size=8192`` parameter.
## 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.
To achieve this, use the ``pack`` application (``node lib/commonjs/servers/volume/pack`` or ``volume-server-pack`` binary from the NPM package).
- To prepare data from x-ray based methods, use:
## Local Mode
```
node pack -xray main.ccp4 diff.ccp4 out.mdb
```
- For EM data, use:
```
node pack -em em.map out.mdb
```
Running the Server
------------------
- Install production dependencies:
```
npm install --only=production
```
- Update ``server-config.js`` to link to your data and optionally tweak the other parameters.
- Run it:
```
node server
```
In production it is a good idea to use a service that will keep the server running, such as [forever.js](https://github.com/foreverjs/forever).
### Local Mode
The program ``local`` in the build folder can be used to query the data without running a http server.
- ``node local`` prints the program usage.
- ``node local jobs.json`` takes a list of jobs to execute in JSON format. A job entry is defined by this interface:
```TypeScript
interface JobEntry {
source: {
filename: string,
name: string,
id: string
},
query: {
kind: 'box' | 'cell',
space?: 'fractional' | 'cartesian',
bottomLeft?: number[],
topRight?: number[],
}
params: {
/** Determines the detail level as specified in server-config */
detail?: number,
/**
* Determines the sampling level:
* 1: Original data
* 2: Downsampled by factor 1/2
* ...
* N: downsampled 1/2^(N-1)
*/
forcedSamplingLevel?: number,
asBinary: boolean,
},
outputFolder: string
}
```
Example ``jobs.json`` file content:
```TypeScript
[{
source: {
filename: `g:/test/mdb/emd-8116.mdb`,
name: 'em',
id: '8116',
},
query: {
kind: 'cell'
},
params: {
detail: 4,
asBinary: true
},
outputFolder: 'g:/test/local-test'
}]
```
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
@@ -122,8 +79,8 @@ The source code is split into 2 mains parts: ``pack`` and ``server``:
Consuming the Data
==================
The data can be consumed in any (modern) browser using the [CIFTools.js library](https://github.com/dsehnal/CIFTools.js) (or any other piece of code that can read text or binary CIF).
The data can be consumed in any (modern) browser using the [ciftools library](https://github.com/molstar/ciftools) (or any other piece of code that can read text or binary CIF).
The [Data Format](DataFormat.md) document gives a detailed description of the server response format.
As a reference/example of the server usage, please see the implementation in [LiteMol](https://github.com/dsehnal/LiteMol) ([CIF.ts + Data.ts](https://github.com/dsehnal/LiteMol/tree/master/src/lib/Core/Formats/Density), [UI](https://github.com/dsehnal/LiteMol/tree/master/src/Viewer/Extensions/DensityStreaming)) or in Mol*.
As a reference/example of the server usage is available in Mol* ``mol-plugin`` module.

50788
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "0.5.0-dev.3",
"version": "2.0.0-dev.0",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -11,28 +11,47 @@
"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",
"build-extra": "cpx \"src/**/*.{scss,woff,woff2,ttf,otf,eot,svg,html,ico}\" lib/",
"build-webpack": "webpack --mode production",
"watch": "concurrently --kill-others \"npm:watch-tsc\" \"npm:watch-extra\" \"npm:watch-webpack\"",
"watch-tsc": "tsc -watch",
"watch-extra": "cpx \"src/**/*.{scss,woff,woff2,ttf,otf,eot,svg,html,ico}\" lib/ --watch",
"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-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",
"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": "node lib/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
"plugin-state": "node lib/servers/plugin-state/index.js",
"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 -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": {
"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": [
"./node_modules",
@@ -60,69 +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.12.2",
"@graphql-codegen/cli": "^1.12.2",
"@graphql-codegen/time": "^1.12.2",
"@graphql-codegen/typescript": "^1.12.2",
"@graphql-codegen/typescript-graphql-files-modules": "^1.12.2",
"@graphql-codegen/typescript-graphql-request": "^1.12.2",
"@graphql-codegen/typescript-operations": "^1.12.2",
"@types/cors": "^2.8.6",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/eslint-plugin-tslint": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"@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": "^5.0.2",
"fs-extra": "^8.1.0",
"http-server": "^0.12.1",
"jest": "^25.1.0",
"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.131.0",
"style-loader": "^1.1.3",
"ts-jest": "^25.2.0",
"typescript": "^3.7.5",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
"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.2",
"@types/jest": "^25.1.2",
"@types/node": "^13.7.0",
"@types/node-fetch": "^2.5.4",
"@types/react": "^16.9.19",
"@types/react-dom": "^16.9.5",
"@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",
"h264-mp4-encoder": "^1.0.12",
"immer": "^8.0.0",
"immutable": "^3.8.2",
"node-fetch": "^2.6.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"rxjs": "^6.5.4",
"swagger-ui-dist": "^3.25.0",
"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,94 +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 { StructureRepresentation3DHelpers } from '../../mol-plugin/state/transforms/representation';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { StateBuilder } from '../../mol-state';
import Expression from '../../mol-script/language/expression';
import { BuiltInColorThemeName } from '../../mol-theme/color';
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,
{ 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.TransformStructureConformationByMatrix, { matrix }, { tags: 'transform' });
}
export function assemble(b: StateBuilder.To<PSO.Molecule.Model>, id?: string) {
return b.apply(StateTransforms.Model.StructureAssemblyFromModel, { id: id || 'deposited' }, { 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,
StructureRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'cartoon'), { tags: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'ball-and-stick'), { tags: 'het-visual' });
// visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' })
// .apply(StateTransforms.Representation.StructureRepresentation3D,
// StructureRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'ball-and-stick', { alpha: 0.51 }), { tags: 'water-visual' });
return visualRoot;
}
export function ballsAndSticks(ctx: PluginContext, visualRoot: StateBuilder.To<PSO.Molecule.Structure>, expression: Expression, coloring?: BuiltInColorThemeName) {
visualRoot
.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(ctx, 'ball-and-stick', void 0, coloring), { tags: 'het-visual' });
return visualRoot;
}
}

View File

@@ -1,206 +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/command';
import { StateTransforms } from '../../mol-plugin/state/transforms';
import { StructureRepresentation3DHelpers } from '../../mol-plugin/state/transforms/representation';
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';
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.structureRepresentation.themeCtx.colorThemeRegistry.add(StripedResidues.propertyProvider.descriptor.name, StripedResidues.colorThemeProvider!);
this.plugin.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);
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.StructureAssemblyFromModel, { id: assemblyId || 'deposited' }, { ref: 'asm' });
}
private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' }, { ref: 'seq' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'cartoon'), { ref: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick'), { ref: 'het-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'ball-and-stick', { alpha: 0.51 }), { ref: 'water-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, '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.dataState;
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.dispatch(this.plugin, { state, ref: state.tree.root.ref });
tree = state.build();
this.visual(this.parse(this.download(tree.toRoot(), url), format, assemblyId));
} else {
tree = state.build();
tree.to('asm').update(StateTransforms.Model.StructureAssemblyFromModel, p => ({ ...p, id: assemblyId || 'deposited' }));
}
await PluginCommands.State.Update.dispatch(this.plugin, { state: this.plugin.state.dataState, tree });
this.loadedParams = { url, format, assemblyId };
PluginCommands.Camera.Reset.dispatch(this.plugin, { });
}
setBackground(color: number) {
const renderer = this.plugin.canvas3d!.props.renderer;
PluginCommands.Canvas3D.SetSettings.dispatch(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.dispatch(this.plugin, { settings: { trackball: { ...trackball, spin: !trackball.spin } } });
if (!spinning) PluginCommands.Camera.Reset.dispatch(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.dataState;
const visuals = state.selectQ(q => q.ofTransformer(StateTransforms.Representation.StructureRepresentation3D));
const tree = state.build();
const colorTheme = { name: StripedResidues.propertyProvider.descriptor.name, params: this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.get(StripedResidues.propertyProvider.descriptor.name).defaultValues };
for (const v of visuals) {
tree.to(v).update(old => ({ ...old, colorTheme }));
}
await PluginCommands.State.Update.dispatch(this.plugin, { state, tree });
}
}
interactivity = {
highlightOn: () => {
const seq_id = 7;
const data = (this.plugin.state.dataState.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.interactivity.lociHighlights.highlightOnly({ loci });
},
clearHighlight: () => {
this.plugin.interactivity.lociHighlights.highlightOnly({ loci: EmptyLoci });
}
}
tests = {
staticSuperposition: async () => {
const state = this.plugin.state.dataState;
const tree = buildStaticSuperposition(this.plugin, StaticSuperpositionTestData);
await PluginCommands.State.RemoveObject.dispatch(this.plugin, { state, ref: StateTransform.RootRef });
await PluginCommands.State.Update.dispatch(this.plugin, { state, tree });
},
dynamicSuperposition: async () => {
await PluginCommands.State.RemoveObject.dispatch(this.plugin, { state: this.plugin.state.dataState, ref: StateTransform.RootRef });
await dynamicSuperpositionTest(this.plugin, ['1tqn', '2hhb', '4hhb'], 'HEM');
},
toggleValidationTooltip: async () => {
const state = this.plugin.state.behaviorState;
const tree = state.build().to(PDBeStructureQualityReport.id).update(PDBeStructureQualityReport, p => ({ ...p, showTooltip: !p.showTooltip }));
await PluginCommands.State.Update.dispatch(this.plugin, { state, tree });
},
showToasts: () => {
PluginCommands.Toast.Show.dispatch(this.plugin, {
title: 'Toast 1',
message: 'This is an example text, timeout 3s',
key: 'toast-1',
timeoutMs: 3000
});
PluginCommands.Toast.Show.dispatch(this.plugin, {
title: 'Toast 2',
message: CustomToastMessage,
key: 'toast-2'
});
},
hideToasts: () => {
PluginCommands.Toast.Hide.dispatch(this.plugin, { key: 'toast-1' });
PluginCommands.Toast.Hide.dispatch(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/command';
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.dataState.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.dataState;
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.dispatch(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.dispatch(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: string[] = []
const pdbx_aromatic_flag: string[] = []
const pdbx_stereo_config: string[] = []
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,166 +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/command';
import { StateTransforms } from '../../../mol-plugin/state/transforms';
import { StructureRepresentation3DHelpers } from '../../../mol-plugin/state/transforms/representation';
import { PluginStateObject as PSO } from '../../../mol-plugin/state/objects';
import { StateBuilder } from '../../../mol-state';
import { Canvas3DProps } from '../../../mol-canvas3d/canvas3d';
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.dispatch(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);
return parsed
.apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 })
.apply(StateTransforms.Model.StructureAssemblyFromModel, { id: assemblyId || 'deposited' }, { ref: 'asm' });
}
private visual(visualRoot: StateBuilder.To<PSO.Molecule.Structure>) {
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, 'spacefill', {}, 'illustrative'), { ref: 'seq-visual' });
visualRoot.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsStatic(this.plugin, '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.dataState;
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.dispatch(this.plugin, { state, ref: state.tree.root.ref });
tree = state.build();
this.visual(this.parse(this.download(tree.toRoot(), url), format, assemblyId));
} else {
tree = state.build();
tree.to('asm').update(StateTransforms.Model.StructureAssemblyFromModel, p => ({ ...p, id: assemblyId || 'deposited' }));
}
await PluginCommands.State.Update.dispatch(this.plugin, { state: this.plugin.state.dataState, tree });
this.loadedParams = { url, format, assemblyId };
PluginCommands.Camera.Reset.dispatch(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

@@ -1,12 +0,0 @@
<!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* ModelServer Query Builder</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>

View File

@@ -1,134 +0,0 @@
/**
* Copyright (c) 2018 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 * as Rx from 'rxjs'
import { QueryDefinition, QueryList } from '../../servers/model/server/api'
import './index.html'
interface State {
query: Rx.BehaviorSubject<QueryDefinition>,
id: Rx.BehaviorSubject<string>,
params: Rx.BehaviorSubject<any>,
isBinary: Rx.BehaviorSubject<boolean>,
models: Rx.BehaviorSubject<number[]>,
url: Rx.Subject<string>
}
class Root extends React.Component<{ state: State }, { }> {
render() {
return <div>
<div>
Query: <QuerySelect state={this.props.state} />
</div>
<div>
ID: <input type='text' onChange={t => this.props.state.id.next(t.currentTarget.value)} />
</div>
<div>
Params:<br/>
<QueryParams state={this.props.state} />
</div>
<div>
Model numbers (empty for all): <ModelNums state={this.props.state} />
</div>
<div>
<input type='checkbox' onChange={t => this.props.state.isBinary.next(!!t.currentTarget.checked)} /> Binary
</div>
<div>
Query string:
<QueryUrl state={this.props.state} />
</div>
</div>
}
}
class QuerySelect extends React.Component<{ state: State }> {
render() {
return <select onChange={s => this.props.state.query.next(QueryList[+s.currentTarget.value].definition)}>
{ QueryList.map((q, i) => <option value={i} key={i} selected={i === 1}>{q.definition.niceName}</option>) }
</select>
}
}
class QueryParams extends React.Component<{ state: State }, { prms: string }> {
state = { prms: '' };
parseParams(str: string) {
this.setState({ prms: str });
try {
const params = JSON.parse(str);
this.props.state.params.next(params);
} catch {
this.props.state.params.next({});
}
}
componentDidMount() {
this.props.state.query.subscribe(q => this.setState({ prms: formatParams(q) }))
}
render() {
return <textarea style={{height: '300px'}} value={this.state.prms} cols={80} onChange={t => this.parseParams(t.currentTarget.value)} />;
}
}
class QueryUrl extends React.Component<{ state: State }, { queryString: string }> {
state = { queryString: '' };
componentDidMount() {
this.props.state.url.subscribe(url => this.setState({ queryString: url }))
}
render() {
return <input type='text' value={this.state.queryString} style={{ width: '800px' }} />
}
}
class ModelNums extends React.Component<{ state: State }> {
render() {
return <input type='text' defaultValue='1' style={{ width: '300px' }} onChange={t =>
this.props.state.models.next(t.currentTarget.value.split(',')
.map(v => v.trim())
.filter(v => !!v)
.map(v => +v)
)} />
}
}
const state: State = {
query: new Rx.BehaviorSubject(QueryList[1].definition),
id: new Rx.BehaviorSubject('1cbs'),
params: new Rx.BehaviorSubject({ }),
isBinary: new Rx.BehaviorSubject<boolean>(false),
models: new Rx.BehaviorSubject<number[]>([]),
url: new Rx.Subject()
}
function formatParams(def: QueryDefinition) {
const prms = Object.create(null);
for (const p of def.jsonParams) {
prms[p.name] = p.exampleValues ? p.exampleValues[0] : void 0;
}
return JSON.stringify(prms, void 0, 2);
}
function formatUrl() {
const json = JSON.stringify({
name: state.query.value.name,
id: state.id.value,
modelNums: state.models.value.length ? state.models.value : void 0,
binary: state.isBinary.value,
params: state.params.value
});
state.url.next(encodeURIComponent(json));
}
Rx.merge(state.query, state.id, state.params, state.isBinary, state.models).subscribe(s => formatUrl());
ReactDOM.render(<Root state={state} />, document.getElementById('app'));

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,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,480 +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 } 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, Cell } 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 } from '../../../../mol-task';
import { StructureRepresentation3DHelpers } from '../../../../mol-plugin/state/transforms/representation';
import { StateTransforms } from '../../../../mol-plugin/state/transforms';
import { distinctColors } from '../../../../mol-util/color/distinct';
import { ModelIndexColorThemeProvider } from '../../../../mol-theme/color/model-index';
import { Hcl } from '../../../../mol-util/color/spaces/hcl';
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 { UniformColorThemeProvider } from '../../../../mol-theme/color/uniform';
import { ThemeRegistryContext } from '../../../../mol-theme/theme';
import { ColorTheme } from '../../../../mol-theme/color';
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';
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], { id, 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
}
if (ctx.shouldUpdate) await ctx.update(`${name} - structure`)
const s = builder.getStructure()
return s
})
}
const RepresentationOptions = PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'ellipsoid'] as const)
type RepresentationName = (typeof RepresentationOptions)[0][0]
export const LoadCellPackModel = StateAction.build({
display: { name: 'Load CellPack Model' },
params: {
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'],
['influenza_model1.json', 'influenza_model1'],
['Mycoplasma1.5_mixed_pdb_fixed.cpr', 'Mycoplasma1.5_mixed_pdb_fixed'],
['curveTest', 'Curve Test'],
] as const),
baseUrl: PD.Text(DefaultCellPackBaseUrl),
preset: PD.Group({
traceOnly: PD.Boolean(false),
representation: PD.Select('spacefill', RepresentationOptions)
}, { isExpanded: true })
},
from: PSO.Root
})(({ state, params }, ctx: PluginContext) => Task.create('CellPack Loader', async taskCtx => {
const url = getCellPackModelUrl(params.id, params.baseUrl)
const root = state.build().toRoot();
let cellPackBuilder: any
if (params.id === 'curveTest') {
const url = `${params.baseUrl}/extras/rna_allpoints.json`
const data = await ctx.fetch({ url, type: 'string' }).runInContext(taskCtx);
const { points } = await (new Response(data)).json() as { points: number[] }
const curve0: Vec3[] = []
for (let j = 0, jl = Math.min(points.length, 3 * 100); j < jl; j += 3) {
curve0.push(Vec3.fromArray(Vec3(), points, j))
}
const cell: Cell = {
recipe: { setupfile: '', paths: [], version: '', name: 'Curve Test' },
compartments: {
'CurveCompartment': {
interior: {
ingredients: {
'CurveIngredient': {
source: { pdb: 'RNA_U_Base.pdb', transform: { center: false } },
results: [],
name: 'RNA',
nbCurve: 1,
curve0
}
}
}
}
}
}
cellPackBuilder = root
.apply(StateTransforms.Data.ImportJson, { data: cell }, { state: { isGhost: true } })
.apply(ParseCellPack)
} else {
cellPackBuilder = root
.apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.id }, { state: { isGhost: true } })
.apply(StateTransforms.Data.ParseJson, undefined, { state: { isGhost: true } })
.apply(ParseCellPack)
}
const cellPackObject = await state.updateTree(cellPackBuilder).runInContext(taskCtx)
const { packings } = cellPackObject.data
const tree = state.build().to(cellPackBuilder.ref);
const isHiv = (
params.id === 'BloodHIV1.0_mixed_fixed_nc1.cpr' ||
params.id === 'HIV-1_0.1.6-8_mixed_radii_pdb.cpr'
)
if (isHiv) {
for (let i = 0, il = packings.length; i < il; ++i) {
if (packings[i].name === 'HIV1_capsid_3j3q_PackInner_0_1_0') {
const url = `${params.baseUrl}/extras/rna_allpoints.json`
const data = await ctx.fetch({ url, type: 'string' }).runInContext(taskCtx);
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
}
}
}
}
const colors = distinctColors(packings.length)
for (let i = 0, il = packings.length; i < il; ++i) {
const hcl = Hcl.fromColor(Hcl(), colors[i])
const hue = [Math.max(0, hcl[0] - 35), Math.min(360, hcl[0] + 35)] as [number, number]
const p = { packing: i, baseUrl: params.baseUrl }
let cellpackTree = tree.apply(StructureFromCellpack, p)
if (params.preset.traceOnly) {
const expression = MS.struct.generator.atomGroups({
'atom-test': MS.core.logic.or([
MS.core.rel.eq([MS.ammp('label_atom_id'), 'CA']),
MS.core.rel.eq([MS.ammp('label_atom_id'), 'P'])
])
})
cellpackTree = cellpackTree.apply(StateTransforms.Model.StructureSelectionFromExpression, { expression }, { state: { isGhost: true } }) as any
}
cellpackTree
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.createParams(ctx, Structure.Empty, {
repr: getReprParams(ctx, params.preset),
color: getColorParams(hue)
})
)
}
if (isHiv) {
const url = `${params.baseUrl}/membranes/hiv_lipids.bcif`
tree.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, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Misc.CreateGroup, { label: 'HIV1_envelope_Membrane' })
.apply(StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.createParams(ctx, Structure.Empty, {
repr: getReprParams(ctx, params.preset),
color: UniformColorThemeProvider
})
)
}
console.time('cellpack')
await state.updateTree(tree).runInContext(taskCtx);
console.timeEnd('cellpack')
}));
function getReprParams(ctx: PluginContext, params: { representation: RepresentationName, traceOnly: boolean }) {
const { representation, traceOnly } = params
switch (representation) {
case 'spacefill':
return traceOnly
? [
ctx.structureRepresentation.registry.get('spacefill'),
() => ({ sizeFactor: 2, ignoreHydrogens: true })
] as [any, any]
: [
ctx.structureRepresentation.registry.get('spacefill'),
() => ({ ignoreHydrogens: true })
] as [any, any]
case 'gaussian-surface':
return [
ctx.structureRepresentation.registry.get('gaussian-surface'),
() => ({
quality: 'custom', resolution: 10, radiusOffset: 2,
alpha: 1.0, flatShaded: false, doubleSided: false,
ignoreHydrogens: true
})
] as [any, any]
case 'point':
return [
ctx.structureRepresentation.registry.get('point'),
() => ({ ignoreHydrogens: true })
] as [any, any]
case 'ellipsoid':
return [
ctx.structureRepresentation.registry.get('orientation'),
() => ({})
] as [any, any]
}
}
function getColorParams(hue: [number, number]) {
return [
ModelIndexColorThemeProvider,
(c: ColorTheme.Provider<any>, ctx: ThemeRegistryContext) => {
return {
palette: {
name: 'generate',
params: {
hue, chroma: [30, 80], luminance: [15, 85],
clusteringStepCount: 50, minSampleCount: 800,
maxCount: 75
}
}
}
}
] as [any, any]
}

View File

@@ -1,74 +0,0 @@
/**
* Copyright (c) 2019 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://cdn.jsdelivr.net/gh/mesoscope/cellPACK_data@master/cellPACK_database_1.1.0/'
export const DefaultCellPackBaseUrl = 'https://mgldev.scripps.edu/projects/autoPACK/web/cellpackproject/'
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 { StructureRepresentation3DHelpers } 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,
// StructureRepresentation3DHelpers.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,
// StructureRepresentation3DHelpers.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,68 +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/command';
import { PluginCommands } from '../../mol-plugin/commands';
import { PluginSpec } from '../../mol-plugin/spec';
import { LoadCellPackModel } from './extensions/cellpack/model';
import { StructureFromCellpack } from './extensions/cellpack/state';
require('mol-plugin-ui/skin/light.scss')
import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
import { PluginConfig } from '../../mol-plugin/config';
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
};
const plugin = createPlugin(document.getElementById('app')!, spec);
trySetSnapshot(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.dispatch(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);
}
setRemoteSnapshot(id: string) {
const url = `${this.plugin.config.get(PluginConfig.State.CurrentServer)}/get/${id}`;
return PluginCommands.State.Snapshots.Fetch(this.plugin, { url });
}
loadSnapshotFromUrl(url: string, type: PluginState.SnapshotType) {
return PluginCommands.State.Snapshots.OpenUrl(this.plugin, { url, type });
}
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: 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,
}
}
}));
}
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

@@ -19,11 +19,15 @@ function paramInfo(param: PD.Any, offset: number): string {
case 'conditioned': return getParams(param.conditionParams, offset);
case 'multi-select': return `Array of ${oToS(param.options)}`;
case 'color': return 'Color as 0xrrggbb';
case 'color-list': return `One of ${oToS(param.options)}`;
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)}`;
@@ -39,7 +43,7 @@ function paramInfo(param: PD.Any, offset: number): string {
}
}
function oToS(options: readonly (readonly [string, string])[]) {
function oToS(options: readonly (readonly [string, string] | readonly [string, string, string | undefined])[]) {
return options.map(o => `'${o[0]}'`).join(', ');
}

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,25 +122,13 @@ 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();
}
export function printModRes(model: Model) {
console.log('\nModified Residues\n=============');
const map = model.properties.modifiedResidues.parentId;
const { label_comp_id, _rowCount } = model.atomicHierarchy.residues;
for (let i = 0; i < _rowCount; i++) {
const comp_id = label_comp_id.value(i);
if (!map.has(comp_id)) continue;
console.log(`[${i}] ${map.get(comp_id)} -> ${comp_id}`);
}
console.log();
}
export function printRings(structure: Structure) {
console.log('\nRings\n=============');
for (const unit of structure.units) {
@@ -144,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();
@@ -183,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(', ')}`);
@@ -192,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 {
@@ -207,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 };
}
@@ -215,18 +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.mod) printModRes(models[0]);
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);
}
@@ -268,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,7 +79,7 @@
addHeader('Camera');
addControl('Toggle Spin', () => BasicMolStarWrapper.toggleSpin());
addSeparator();
addHeader('Animation');
@@ -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,164 @@
/**
* 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, {});
}
animate = {
modelIndex: {
maxFPS: 8,
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), 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

@@ -38,16 +38,16 @@
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' })
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' }));

View File

@@ -0,0 +1,119 @@
/**
* 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: 64, radius: 8, bias: 1.0, blurKernelSize: 13 } },
outline: { name: 'on', params: { scale: 1, threshold: 0.33 } }
},
renderer: {
ambientIntensity: 1,
lightIntensity: 0,
}
},
occlusion: <Preset> {
multiSample: {
mode: 'temporal' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusion: { name: 'on', params: { samples: 64, radius: 8, bias: 1.0, blurKernelSize: 13 } },
outline: { name: 'off', params: { } }
},
renderer: {
ambientIntensity: 0.4,
lightIntensity: 0.6,
}
},
standard: <Preset> {
multiSample: {
mode: 'off' as Canvas3DProps['multiSample']['mode']
},
postprocessing: {
occlusion: { name: 'off', params: { } },
outline: { name: 'off', params: { } }
},
renderer: {
ambientIntensity: 0.4,
lightIntensity: 0.6,
}
}
};
type Canvas3DPreset = keyof typeof Canvas3DPresets
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 = Canvas3DPresets[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
},
}});
}
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);
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' });
}
}
(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,16 +91,16 @@ export function createProteopediaCustomTheme(colors: number[]) {
props,
description: Description,
legend: undefined
}
};
}
const ProteopediaCustomColorThemeProvider: ColorTheme.Provider<ProteopediaCustomColorThemeParams> = {
return {
name: 'proteopedia-custom',
label: 'Proteopedia Custom',
category: 'Custom',
factory: ProteopediaCustomColorTheme,
getParams: getChainIdColorThemeParams,
defaultValues: PD.getDefaultValues(ProteopediaCustomColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
}
return ProteopediaCustomColorThemeProvider;
};
}

View File

@@ -4,12 +4,11 @@
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { ResidueIndex, Model } from '../../mol-model/structure';
import { BuiltInStructureRepresentationsName } from '../../mol-repr/structure/registry';
import { BuiltInColorThemeName } from '../../mol-theme/color';
import { AminoAcidNames } from '../../mol-model/structure/model/types';
import { PluginContext } from '../../mol-plugin/context';
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';
export interface ModelInfo {
hetResidues: { name: string, indices: ResidueIndex[] }[],
@@ -54,14 +53,12 @@ export namespace ModelInfo {
const hetMap = new Map<string, ModelInfo['hetResidues'][0]>();
for (let rI = 0 as ResidueIndex; rI < residueCount; rI++) {
const comp_id = model.atomicHierarchy.residues.label_comp_id.value(rI);
if (AminoAcidNames.has(comp_id)) continue;
const mod_parent = model.properties.modifiedResidues.parentId.get(comp_id);
if (mod_parent && AminoAcidNames.has(mod_parent)) 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.atoms.label_comp_id.value(residueOffsets[rI]);
let lig = hetMap.get(comp_id);
if (!lig) {
@@ -73,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,
@@ -87,6 +84,7 @@ export type SupportedFormats = 'cif' | 'pdb'
export interface LoadParams {
url: string,
format?: SupportedFormats,
isBinary?: boolean,
assemblyId?: string,
representationStyle?: RepresentationStyle
}
@@ -99,7 +97,7 @@ export interface RepresentationStyle {
}
export namespace RepresentationStyle {
export type Entry = { hide?: boolean, kind?: BuiltInStructureRepresentationsName, coloring?: BuiltInColorThemeName }
export type Entry = { hide?: boolean, kind?: StructureRepresentationRegistry.BuiltIn, coloring?: ColorTheme.BuiltIn }
}
export enum StateElements {

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,7 +140,7 @@
// 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');
@@ -168,20 +173,24 @@
addControl('Init', () => PluginWrapper.experimentalData.init($('volume-streaming-wrapper')));
addControl('Remove', () => PluginWrapper.experimentalData.remove());
addSeparator();
addSeparator();
addHeader('State');
var snapshot;
addControl('Create Snapshot', () => {
snapshot = PluginWrapper.snapshot.get();
// could use JSON.stringify(snapshot) and upload the data
addControl('Set Snapshot', () => {
// 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('Apply Snapshot', () => {
addControl('Restore Snapshot', () => {
if (!snapshot) return;
PluginWrapper.snapshot.set(snapshot);
// or download snapshot using fetch or ajax or whatever
// or PluginWrapper.snapshot.download(url);
});
addControl('Download State', () => {
PluginWrapper.snapshot.download('molj');
});
addControl('Download Session', () => {
PluginWrapper.snapshot.download('molx');
});
////////////////////////////////////////////////////////
@@ -217,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,38 +5,35 @@
*/
import * as ReactDOM from 'react-dom';
import { createPlugin, DefaultPluginSpec } from '../../mol-plugin';
import './index.html'
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 { 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 { PluginCommands } from '../../mol-plugin/command';
import { StateTransforms } from '../../mol-plugin/state/transforms';
import { StructureRepresentation3DHelpers } from '../../mol-plugin/state/transforms/representation';
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 { ControlsWrapper, 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 { BuiltInStructureRepresentations } from '../../mol-repr/structure/registry';
import { BuiltInColorThemes } from '../../mol-theme/color';
import { BuiltInSizeThemes } from '../../mol-theme/size';
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 { InitVolumeStreaming, CreateVolumeStreamingInfo } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
import { DefaultCanvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d';
// import { Vec3 } from 'mol-math/linear-algebra';
// import { ParamDefinition } from 'mol-util/param-definition';
// import { Text } from 'mol-geo/geometry/text/text';
require('../../mol-plugin-ui/skin/light.scss')
import { getFormattedTime } from '../../mol-util/date';
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 = 3;
static VERSION_MINOR = 4;
static VERSION_MAJOR = 5;
static VERSION_MINOR = 5;
private _ev = RxEventHelper.create();
@@ -50,7 +47,7 @@ class MolStarProteopediaWrapper {
customColorList?: number[]
}) {
this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
...DefaultPluginSpec,
...DefaultPluginSpec(),
animations: [
AnimateModelIndex
],
@@ -58,27 +55,27 @@ class MolStarProteopediaWrapper {
initial: {
isExpanded: false,
showControls: false
},
controls: {
right: ControlsWrapper
}
},
components: {
remoteState: 'none'
}
});
const customColoring = createProteopediaCustomTheme((options && options.customColorList) || []);
this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add('proteopedia-custom', customColoring);
this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(EvolutionaryConservation.propertyProvider.descriptor.name, EvolutionaryConservation.colorThemeProvider!);
this.plugin.lociLabels.addProvider(EvolutionaryConservation.labelProvider!);
this.plugin.representation.structure.themes.colorThemeRegistry.add(customColoring);
this.plugin.representation.structure.themes.colorThemeRegistry.add(EvolutionaryConservation.colorThemeProvider!);
this.plugin.managers.lociLabels.addProvider(EvolutionaryConservation.labelProvider!);
this.plugin.customModelProperties.register(EvolutionaryConservation.propertyProvider, true);
}
get state() {
return this.plugin.state.dataState;
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) {
@@ -92,10 +89,18 @@ class MolStarProteopediaWrapper {
private structure(assemblyId: string) {
const model = this.state.build().to(StateElements.Model);
const props = {
type: assemblyId ? {
name: 'assembly' as const,
params: { id: assemblyId }
} : {
name: 'model' as const,
params: { }
}
};
const s = model
.apply(StateTransforms.Model.CustomModelProperties, { autoAttach: [EvolutionaryConservation.propertyProvider.descriptor.name], properties: {} }, { ref: StateElements.ModelProps, state: { isGhost: false } })
.apply(StateTransforms.Model.StructureAssemblyFromModel, { id: assemblyId || 'deposited' }, { ref: StateElements.Assembly });
.apply(StateTransforms.Model.StructureFromModel, props, { ref: StateElements.Assembly });
s.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' }, { ref: StateElements.Sequence });
s.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' }, { ref: StateElements.Het });
@@ -118,9 +123,10 @@ class MolStarProteopediaWrapper {
root.delete(StateElements.SequenceVisual);
} else {
root.applyOrUpdate(StateElements.SequenceVisual, StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsWithTheme(this.plugin,
(style.sequence && style.sequence.kind) || 'cartoon',
(style.sequence && style.sequence.coloring) || 'unit-index', structure));
createStructureRepresentationParams(this.plugin, structure, {
type: (style.sequence && style.sequence.kind) || 'cartoon',
color: (style.sequence && style.sequence.coloring) || 'unit-index'
}));
}
}
@@ -133,9 +139,10 @@ class MolStarProteopediaWrapper {
root.delete(StateElements.HetVisual);
} else {
root.applyOrUpdate(StateElements.HetVisual, StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsWithTheme(this.plugin,
(style.hetGroups && style.hetGroups.kind) || 'ball-and-stick',
(style.hetGroups && style.hetGroups.coloring), structure));
createStructureRepresentationParams(this.plugin, structure, {
type: (style.hetGroups && style.hetGroups.kind) || 'ball-and-stick',
color: style.hetGroups && style.hetGroups.coloring
}));
}
}
}
@@ -149,7 +156,7 @@ class MolStarProteopediaWrapper {
root.delete(StateElements.Het3DSNFG);
} else {
root.applyOrUpdate(StateElements.Het3DSNFG, StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsWithTheme(this.plugin, 'carbohydrate', void 0, structure));
createStructureRepresentationParams(this.plugin, structure, { type: 'carbohydrate' }));
}
}
}
@@ -160,9 +167,11 @@ class MolStarProteopediaWrapper {
root.delete(StateElements.WaterVisual);
} else {
root.applyOrUpdate(StateElements.WaterVisual, StateTransforms.Representation.StructureRepresentation3D,
StructureRepresentation3DHelpers.getDefaultParamsWithTheme(this.plugin,
(style.water && style.water.kind) || 'ball-and-stick',
(style.water && style.water.coloring), structure, { alpha: 0.51 }));
createStructureRepresentationParams(this.plugin, structure, {
type: (style.water && style.water.kind) || 'ball-and-stick',
typeParams: { alpha: 0.51 },
color: style.water && style.water.coloring
}));
}
}
@@ -180,20 +189,21 @@ 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;
}
private applyState(tree: StateBuilder) {
return PluginCommands.State.Update.dispatch(this.plugin, { state: this.plugin.state.dataState, tree });
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.dataState;
const state = this.plugin.state.data;
if (this.loadedParams.url !== url || this.loadedParams.format !== format) {
loadType = 'full';
@@ -202,8 +212,8 @@ class MolStarProteopediaWrapper {
}
if (loadType === 'full') {
await PluginCommands.State.RemoveObject.dispatch(this.plugin, { state, ref: state.tree.root.ref });
const modelTree = this.model(this.download(state.build().toRoot(), url), format);
await PluginCommands.State.RemoveObject(this.plugin, { state, ref: state.tree.root.ref });
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;
@@ -213,39 +223,45 @@ class MolStarProteopediaWrapper {
const tree = state.build();
const info = await this.doInfo(true);
const asmId = (assemblyId === 'preferred' && info && info.preferredAssemblyId) || assemblyId;
tree.to(StateElements.Assembly).update(StateTransforms.Model.StructureAssemblyFromModel, p => ({ ...p, id: asmId }));
const props = {
type: assemblyId ? {
name: 'assembly' as const,
params: { id: asmId }
} : {
name: 'model' as const,
params: { }
}
};
tree.to(StateElements.Assembly).update(StateTransforms.Model.StructureFromModel, p => ({ ...p, ...props }));
await this.applyState(tree);
}
await this.updateStyle(representationStyle);
this.loadedParams = { url, format, assemblyId };
Scheduler.setImmediate(() => PluginCommands.Camera.Reset.dispatch(this.plugin, { }));
}
async updateStyle(style?: RepresentationStyle, partial?: boolean) {
const tree = this.visual(style, partial);
if (!tree) return;
await PluginCommands.State.Update.dispatch(this.plugin, { state: this.plugin.state.dataState, tree });
await PluginCommands.State.Update(this.plugin, { state: this.plugin.state.data, tree });
}
setBackground(color: number) {
if (!this.plugin.canvas3d) return;
const renderer = this.plugin.canvas3d.props.renderer;
PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: { renderer: { ...renderer, backgroundColor: Color(color) } } });
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.dispatch(this.plugin, { settings: { trackball: { ...trackball, spin: !trackball.spin } } });
if (!spinning) PluginCommands.Camera.Reset.dispatch(this.plugin, { });
PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: { trackball: { ...trackball, spin: !trackball.spin } } });
}
viewport = {
setSettings: (settings?: Canvas3DProps) => {
PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, {
PluginCommands.Canvas3D.SetSettings(this.plugin, {
settings: settings || DefaultCanvas3DParams
});
}
@@ -253,36 +269,17 @@ class MolStarProteopediaWrapper {
camera = {
toggleSpin: () => this.toggleSpin(),
resetPosition: () => PluginCommands.Camera.Reset.dispatch(this.plugin, { }),
// setClip: (options?: { distance?: number, near?: number, far?: number }) => {
// if (!options) {
// PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, {
// settings: {
// cameraClipDistance: DefaultCanvas3DParams.cameraClipDistance,
// clip: DefaultCanvas3DParams.clip
// }
// });
// return;
// }
// 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.dispatch(this.plugin, {
// settings: { cameraClipDistance: options.distance, clip: [clipNear, clipFar] }
// });
// }
resetPosition: () => 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()
onceForward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'forward' } } }); },
onceBackward: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'once', params: { direction: 'backward' } } }); },
palindrome: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'palindrome', params: {} } }); },
loop: () => { this.plugin.managers.animation.play(AnimateModelIndex, { maxFPS: Math.max(0.5, this.animate.modelIndex.maxFPS | 0), mode: { name: 'loop', params: {} } }); },
stop: () => this.plugin.managers.animation.stop()
}
}
@@ -293,13 +290,8 @@ 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.structureRepresentation.themeCtx.colorThemeRegistry.get(EvolutionaryConservation.propertyProvider.descriptor.name).defaultValues };
const colorTheme = { name: EvolutionaryConservation.propertyProvider.descriptor.name, params: this.plugin.representation.structure.themes.colorThemeRegistry.get(EvolutionaryConservation.propertyProvider.descriptor.name).defaultValues };
if (!params || !!params.sequence) {
tree.to(StateElements.SequenceVisual).update(StateTransforms.Representation.StructureRepresentation3D, old => ({ ...old, colorTheme }));
@@ -308,7 +300,7 @@ class MolStarProteopediaWrapper {
tree.to(StateElements.HetVisual).update(StateTransforms.Representation.StructureRepresentation3D, old => ({ ...old, colorTheme }));
}
await PluginCommands.State.Update.dispatch(this.plugin, { state, tree });
await PluginCommands.State.Update(this.plugin, { state, tree });
}
}
@@ -328,7 +320,7 @@ class MolStarProteopediaWrapper {
remove: () => {
const r = this.state.select(StateSelection.Generators.ofTransformer(CreateVolumeStreamingInfo))[0];
if (!r) return;
PluginCommands.State.RemoveObject.dispatch(this.plugin, { state: this.state, ref: r.transform.ref });
PluginCommands.State.RemoveObject(this.plugin, { state: this.state, ref: r.transform.ref });
if (this.experimentalDataElement) {
ReactDOM.unmountComponentAtNode(this.experimentalDataElement);
this.experimentalDataElement = void 0;
@@ -339,14 +331,12 @@ class MolStarProteopediaWrapper {
hetGroups = {
reset: () => {
const update = this.state.build().delete(StateElements.HetGroupFocusGroup);
PluginCommands.State.Update.dispatch(this.plugin, { state: this.state, tree: update });
PluginCommands.Camera.Reset.dispatch(this.plugin, { });
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.dispatch(this.plugin, { });
// const asm = (this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure).data;
await PluginCommands.Camera.Reset(this.plugin, { });
const update = this.state.build();
@@ -361,65 +351,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 }
}));
await PluginCommands.State.Update.dispatch(this.plugin, { state: this.state, tree: update });
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 snapshot = this.plugin.canvas3d!.camera.getFocus(sphere.center, radius, radius);
PluginCommands.Camera.SetSnapshot.dispatch(this.plugin, { snapshot, durationMs: 250 });
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 StructureRepresentation3DHelpers.createParams(this.plugin, asm.data, {
repr: BuiltInStructureRepresentations['ball-and-stick'],
color: [BuiltInColorThemes.uniform, () => ({ value: ColorNames.gray })],
size: [BuiltInSizeThemes.uniform, () => ({ value: 0.33 } )]
});
}
private createCoreVisualParams() {
const asm = this.state.select(StateElements.Assembly)[0].obj as PluginStateObject.Molecule.Structure;
return StructureRepresentation3DHelpers.createParams(this.plugin, asm.data, {
repr: BuiltInStructureRepresentations['ball-and-stick'],
// color: [BuiltInColorThemes.uniform, () => ({ value: ColorNames.gray })],
// size: [BuiltInSizeThemes.uniform, () => ({ value: 0.33 } )]
});
}
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: async (url: string) => {
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, type: 'molj' | 'molx' = 'molj') => {
try {
const snapshot = await this.plugin.runTask(this.plugin.fetch({ url, type: 'json' }));
await this.plugin.state.setSnapshot(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

@@ -6,27 +6,13 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { PluginUIComponent } from '../../../mol-plugin-ui/base';
import { CurrentObject, PluginContextContainer } from '../../../mol-plugin-ui/plugin';
import { AnimationControls } from '../../../mol-plugin-ui/state/animation';
import { CameraSnapshots } from '../../../mol-plugin-ui/camera';
import { PluginContext } from '../../../mol-plugin/context';
import { PluginContextContainer } from '../../../mol-plugin-ui/plugin';
import { TransformUpdaterControl } from '../../../mol-plugin-ui/state/update-transform';
import { PluginContext } from '../../../mol-plugin/context';
import { StateElements } from '../helpers';
export class ControlsWrapper extends PluginUIComponent {
render() {
return <div className='msp-scrollable-container msp-right-controls'>
<CurrentObject />
<AnimationControls />
<CameraSnapshots />
</div>;
}
}
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

@@ -0,0 +1,95 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @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 { 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({
id: 'preset-structure-representation-cellpack-packing',
display: { name: 'CellPack Packing' },
params: () => CellpackPackingPresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
if (!structureCell) return {};
const reprProps = {
ignoreHydrogens: true,
traceOnly: params.traceOnly
};
const components = {
polymer: await presetStaticComponent(plugin, structureCell, 'polymer')
};
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 });
}
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 representations = {
polymer: builder.buildRepresentation<any>(update, components.polymer, { type: params.representation, typeParams: { ...typeParams, ...reprProps }, color }, { tag: 'polymer' })
};
await update.commit({ revertOnError: true });
return { components, representations };
}
});
//
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({
id: 'preset-structure-representation-cellpack-membrane',
display: { name: 'CellPack Membrane' },
params: () => CellpackMembranePresetParams,
async apply(ref, params, plugin) {
const structureCell = StateObjectRef.resolveAndCheck(plugin.state.data, ref);
if (!structureCell) return {};
const reprProps = {
ignoreHydrogens: true,
};
const components = {
membrane: await presetStaticComponent(plugin, structureCell, 'all', { label: 'Membrane' })
};
if (params.representation === 'gaussian-surface') {
Object.assign(reprProps, {
quality: 'custom', resolution: 10, radiusOffset: 2, doubleSided: false
});
}
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, {});
const representations = {
membrane: builder.buildRepresentation(update, components.membrane, { type: 'gaussian-surface', typeParams: { ...typeParams, ...reprProps }, color: 'uniform', colorParams: { value: ColorNames.lightgrey } }, { tag: 'all' })
};
await update.commit({ revertOnError: true });
return { components, representations };
}
});

View File

@@ -0,0 +1,37 @@
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
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, colors: undefined }, { isHidden: true })
};
type CellPackInfoParams = PD.Values<typeof CellPackInfoParams>
export const CellPackInfoProvider: CustomStructureProperty.Provider<typeof CellPackInfoParams, CellPackInfoValue> = CustomStructureProperty.createProvider({
label: 'CellPack Info',
descriptor: CustomPropertyDescriptor({ name: 'cellpack-info' }),
type: 'root',
defaultParams: CellPackInfoParams,
getParams: (data: Structure) => CellPackInfoParams,
isApplicable: (data: Structure) => true,
obtain: async (ctx: CustomProperty.Context, data: Structure, props: CellPackInfoParams) => {
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);
}

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