Skip to content

Commit

Permalink
Merge branch 'master' into add-selection-callback-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
nlarusstone committed Dec 16, 2023
2 parents 5d7e783 + 2d121ec commit 14235d1
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 13 deletions.
4 changes: 4 additions & 0 deletions docs/data-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## State Tree, Selectors, Transforms

## State Snapshots

## Structure, Trajectory, Cell

## Ref, Representation
36 changes: 33 additions & 3 deletions docs/plugin.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Creating Plugin Instance


## Intro

What is a plugin? A plugin is a collection of modules that provide functionality to the `Mol*` UI. The plugin is responsible for managing the state of the viewer, internal and user interactions. It has been a previous point of confusion for new users of `Mol*` to associate the __viewer__ part of the library with what is further referred to as the __plugin__. These two are closely connected in the `molstar-plugin-ui` module, which is the user-facing part of the library and ultimately provides the viewer, but they are ultimately distinct.


It is recommended that you inspect the general class structure of [`PluginInitWrapper`](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin-ui/plugin.tsx#L41), [`PluginUIContext`](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin/context.ts#L71) and [`PluginUIComponent`](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin-ui/base.tsx#L16) to better understand the flow of data and events in the plugin.
A passing analogy is that a [ `PluginContext` ](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin/context.ts#L71) is the engine that powers computation, rendering, events and subscriptions inside the molstar UI. All UI components depend on `PluginContext`.



There are 4 basic ways of instantiating the Mol* plugin.

## ``Viewer`` wrapper
Expand Down Expand Up @@ -45,8 +56,8 @@ Example usage without using WebPack:
pdbProvider: 'rcsb',
emdbProvider: 'rcsb',
}).then(viewer => {
viewer.loadPdb('7bv2');
viewer.loadEmdb('EMD-30210', { detail: 6 });
viewer.loadPdb('7bv2');
viewer.loadEmdb('EMD-30210', { detail: 6 });
});
</script>
```
Expand Down Expand Up @@ -146,6 +157,23 @@ export function MolStarWrapper() {

```


Furthermore, if it is desirable in your project to use the `molstar`'s React UI components, but you wish to alter or rearrange the layout, you should take a look at the signatures of [ `PluginUIComponent` ](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin-ui/base.tsx#L16) which every "control" subclasses.


[ `SequenceView` ](https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin-ui/sequence.tsx#L221C4-L221C4), for example, can be used separately from the `PluginUI`. Yet you would need to pass the `PluginUIContext` to it in order for it to observe the changes in the state of the plugin. This can be done via a `PluginContextContainer`:
```typescript
// your_app.plugin: PluginUIContext
...
<div className="your_custom_ui">
<PluginContextContainer plugin={your_app.plugin}>
<SequenceView />
</PluginContextContainer>
</div>
```



## ``PluginContext`` without built-in React UI

- The [``PluginContext``](https://github.com/molstar/molstar/blob/master/src/mol-plugin/context.ts) can be instantiated without using the default React UI.
Expand Down Expand Up @@ -180,8 +208,10 @@ async function init() {
return;
}

// Example url:"https://files.rcsb.org/download/3j7z.pdb"
// Example url:"https://files.rcsb.org/download/5AFI.cif"
const data = await plugin.builders.data.download({ url: '...' }, { state: { isGhost: true } });
const trajectory = await plugin.builders.structure.parseTrajectory(data, format);
const trajectory = await plugin.builders.structure.parseTrajectory(data, format); //format is 'mmcif' or 'pdb' etc.
await plugin.builders.structure.hierarchy.applyPreset(trajectory, 'default');
}

Expand Down
73 changes: 69 additions & 4 deletions docs/selections.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Selections

## Selection from data
Programmatically select with the structures data

```typescript
Assuming you have a model already loaded into the plugin (see [initiation](./plugin.md)), these are some of the following method you can select structural data.

### Selecting directly from the `hierarchy` manager

One can select a subcomponent's data directly from the plugin manager.

```typescript
import { Structure } from '../mol-model/structure';

const ligandData = plugin.managers.structure.hierarchy.selection.structures[0]?.components[0]?.cell.obj?.data;
const ligandLoci = Structure.toStructureElementLoci(ligandData as any);

plugin.managers.camera.focusLoci(ligandLoci);
plugin.managers.interactivity.lociSelects.select({ loci: ligandLoci });
```
Expand Down Expand Up @@ -42,4 +47,64 @@ plugin.behaviors.interaction.click.subscribe(
setSelected(localSelected);
}
)
```
```

### `Molscript` language

Molscript is a language for addressing crystallographic structures and is a part of the Mol* library found at `https://github.com/molstar/molstar/tree/master/src/mol-script`. It can be used against the Molstar plugin as a query language and traspiled against multiple external molecular visualization libraries(see [here](https://github.com/molstar/molstar/tree/master/src/mol-script/transpilers)).

### Querying a structure for a specific chain and residue range (select residues with 12<res_id<200 of chain with auth_asym_id==A) :

```typescript
import { compileIdListSelection } from 'molstar/lib/mol-script/util/id-list'

const query = compileIdListSelection('A 12-200', 'auth');
window.molstar?.managers.structure.selection.fromCompiledQuery('add',query);
```

## Selection Queries

Another way to create a selection is via a `SelectionQuery` object. This is a more programmatic way to create a selection. The following example shows how to select a chain and a residue range using a `SelectionQuery` object.
This relies on the concept of `Expression` which is basically a intermediate representation between a Molscript statement and a selection query.

### Select residues 10-15 of chains A and F in a structure using a `SelectionQuery` object:

```typescript

import { MolScriptBuilder as MS, MolScriptBuilder } from 'molstar/lib/mol-script/language/builder';
import { Expression } from 'molstar/lib/mol-script/language/expression';
import { StructureSelectionQuery } from 'molstar/lib/mol-plugin-state/helpers/structure-selection-query'


export function select_multiple() {

const args = [['A', 10, 15], ['F', 10, 15]]
const groups: Expression[] = [];
for (var chain of args) {
groups.push(MS.struct.generator.atomGroups({
"chain-test": MS.core.rel.eq([MolScriptBuilder.struct.atomProperty.macromolecular.auth_asym_id(), chain[0]]),
"residue-test": MS.core.rel.inRange([MolScriptBuilder.struct.atomProperty.macromolecular.label_seq_id(), chain[1], chain[2]])
}));
}
var sq = StructureSelectionQuery('residue_range_10_15_in_A_and_F', MS.struct.combinator.merge(groups))
mstar.managers.structure.selection.fromSelectionQuery('set', sq)
}
```

Complex queries can be constructed by combining primitive queries at the level of [`chain-test`, `residue-test`, `entity-test`, etc] (https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-script/language/symbol-table/structure-query.ts#L88C4-L94C112) by combining them via logical connectives provided in the `MolscriptBuilder.core.rel` as above.

Inspect these examples to get a better feeling for this syntax: `https://github.com/molstar/molstar/blob/6edbae80db340134341631f669eec86543a0f1a8/src/mol-plugin-state/helpers/structure-selection-query.ts#L88-L580`


Furthermore, a query made this way can be converted to a `Loci` object which is important in many parts of the libary:
```typescript

// Select residue 124 of chain A and convert to Loci
const Q = MolScriptBuilder;
var sel = Script.getStructureSelection(Q => Q.struct.generator.atomGroups({
'chain-test' : Q.core.rel.eq([Q.struct.atomProperty.macromolecular.auth_asym_id(), A]),
"residue-test": Q.core.rel.eq([Q.struct.atomProperty.macromolecular.label_seq_id(), 124]),
}), objdata)

let loci = StructureSelection.toLociWithSourceUnits(sel);
```
15 changes: 9 additions & 6 deletions docs/viewer-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ PluginCommands.Toast.Show(plugin, {

## Behaviors

The state of the Mol* plugin is usually governed by dynamics behaviors which can be set up in initial plugin specification or updated during the plugin runtime. This allows for high modularity and customizability of individual plugin instances.
The state of the Mol* plugin is usually governed by dynamic behaviors which can be set up in initial plugin specification or updated during the plugin runtime. This allows for high modularity and customizability of individual plugin instances.


### Highlight ``Loci``
Highlighting adds a transient overpaint to a representation that will linger until the mouse enters hovers over another
object. Highlights can be applied to a previously defined ``Loci`` by:
```ts
plugin.managers.interactivity.lociHighlights.highlightOnly({ loci });
plugin.managers.interactivity.lociHighlights.highlightOnly({ loci }); // loci: Loci
```
Reset all highlights by:
```ts
Expand All @@ -74,15 +74,17 @@ plugin.managers.interactivity.clearHighlights();


### Select ``Loci``

Selected elements will appear with distinct visuals and, if applicable, the corresponding sequence positions will be
shown in the Sequence Viewer panel. Selections persist until removed, for example by clicking the background. A ``Loci``
is selected by:
```ts
plugin.managers.interactivity.lociSelects.select({ loci });
plugin.managers.interactivity.lociSelects.select({ loci }); // loci: Loci
```

Deselect a specific ``Loci`` by:
```ts
plugin.managers.interactivity.lociSelects.deselect({ loci });
plugin.managers.interactivity.lociSelects.deselect({ loci }); // loci: Loci
```
To deselect everything:
```ts
Expand All @@ -98,7 +100,7 @@ plugin.managers.structure.focus.setFromLoci(loci);
```
Extend an existing focus representation by:
```ts
plugin.managers.structure.focus.addFromLoci(loci);
plugin.managers.structure.focus.addFromLoci(loci); // loci: Loci
```
Reset by:
```ts
Expand All @@ -109,8 +111,9 @@ plugin.managers.structure.focus.clear();
### Zoom ``Loci``
A ``Loci`` can also be used to manipulate the camera. Zoom in by:
```ts
plugin.managers.camera.focusLoci(loci);
plugin.managers.camera.focusLoci(loci); // loci: Loci
```

Restore the default camera position by:
```ts
plugin.managers.camera.reset();
Expand Down

0 comments on commit 14235d1

Please sign in to comment.