molstar / molstar

A comprehensive macromolecular library
https://molstar.org
MIT License
651 stars 148 forks source link

Update representation type / opacity using API #68

Closed IsmailM closed 4 years ago

IsmailM commented 4 years ago

Hi,

I am loading my PDB file using the following, which works very nicely:

var viewer = new molstar.Viewer('app', options)
viewer.loadStructureFromUrl("url_to_pdb_file", format='pdb')

I would like to do the following:

This can be done easily using the left side panel - however, I would like to do this using an API if possible.

Looking at the code, I see that loadStructureFromUrl() function returns a promise but I can't seem to access any objects. e.g.

viewer.loadStructureFromUrl("url_to_pdb_file", format='pdb').then(function(obj) {
    console.log('Finished Loading');
    console.log(obj);
});

I would appreciate any help with regards to this.

Many Thanks, Ismail

dsehnal commented 4 years ago

Hi Ismail,

if you want to change the parameters, you have to build the representation yourself.

You can start with this example https://github.com/molstar/molstar/blob/master/src/examples/basic-wrapper/index.ts#L52

Essentially you want something along these lines:

const data = await this.plugin.builders.data.download({ url });
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);

const components = {
    polymer: await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer'),
    ligand: await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'ligand'),
    water: await this.plugin.builders.structure.tryCreateComponentStatic(structure, 'water'),
};

const builder = this.plugin.builders.structure.representation;
const update = this.plugin.build();
if (components.polymer) builder.buildRepresentation(update, components.polymer, { type: 'gaussian-surface', typeParams: { alpha: 0.51 } }, { tag: 'polymer' });
if (components.ligand) builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick' }, { tag: 'ligand' });
if (components.water) builder.buildRepresentation(update, components.water, { type: 'ball-and-stick', typeParams: { alpha: 0.6 } }, { tag: 'water' });
await update.commit();

You can have a look at https://github.com/molstar/molstar/blob/master/src/mol-plugin-state/builder/structure/representation-preset.ts#L129 for how the code for the default preset looks like (the code above is a modification of that code, for example it would be required to show carbohydrates separately).

David

IsmailM commented 4 years ago

Hi David,

Thanks for the swift reply.

This looks like exactly what I needed.

And thank you for the exemplar code - this will make implementing this a lot easier 😃

Ismail Moghul

IsmailM commented 4 years ago

Hi David,

Once again thank you for all your help last time.

I have another very quick question.

I am trying to change the surface colour of the PDB file I am importing (e.g. to bright yellow).

Is it possible to pass a colour hex id (0xFFFF00) directly to buildRepresentation()?

Looking at the basic-wrapper example, I have tried using the new theme object created and passing this to the buildRepresentation(); however, this has not worked:

import { StripedResidues } from './coloring';

...

if (components.polymer) builder.buildRepresentation(update, components.polymer, { type: 'gaussian-surface', typeParams: { alpha: 0.51 }, StripedResidues }, { tag: 'polymer' });

However, the colour surface file of the polymer is still randomly assigned (to green) and does not use the colour id in the StripedResidue object.

Many Thanks, Ismail Moghul

dsehnal commented 4 years ago

Yeah, just add { type: ..., color: 'uniform', colorParams: Color(0xFFFFF00) }.

If you want to use the custom theme, you need to provide it's string id (available in the definition of the theme; and possibly use as any if in typescript).

David