LiteMol icon indicating copy to clipboard operation
LiteMol copied to clipboard

Init from html file

Open gbayarri opened this issue 8 years ago • 14 comments

Hi,

First of all, congratulations for the great job. I'm using this visualization tool and I need to load it automatically from the html page. For instance, to have an input textbox outside the tool where I can put the pdb code and after clicking a button, reload the new pdb code on the tool without reload the page. Is that possible?

On the other hand, I have another doubt: when I load a pdb with several models, I can load them one by one. Is there some way to load all of them the first time I load the molecule? For instance, the '1ARK' has 15 models and I would want to load all at the same time.

Thanks!

gbayarri avatar Sep 29 '16 13:09 gbayarri

Hi,

I've updated the Commands example (source) to show how to do what you need, and then some (like toggling of a model or highlighting i-th model).

If you have further questions, feel free to ask,

David

dsehnal avatar Sep 30 '16 14:09 dsehnal

Thanks David. That's what I needed. Probably in a few days or weeks I will ask you for something more.

Best regards.

gbayarri avatar Oct 07 '16 11:10 gbayarri

The examples are a great way of highlighting how to play with the fine details - not so easy for someone new to the project to get up and running quickly. An event like "load a PDB model" intuitively feels like it should be a relatively simple API call, but there seems to be loads of code associated with each of those buttons. Perhaps I'm reading the code wrong.

It would be really useful to add a FAQ to show the very simplest way to achieve a bunch of tasks (or at least one simple task and a link to the API docs).

e.g. "How do I create a LiteMol instance and load my own custom PDB file?"

<div id="litemol"></div>

_[PSEUDO CODE]_

<script>
litemol = new LiteMol( { target: '#litemol' } );
jQuery.ajax({
  url: '/path/to/1PDB.pdb',
  success: function(data) {
    litemol.clear();
    litemol.loadPdb( data );
  }
});
</script>

Happy to help with documentation (and generally coming up with lists of stupid questions).

sillitoe avatar Nov 09 '16 15:11 sillitoe

@sillitoe

You make a good point.

Currently, you always need to create a spec for the plugin (or at least use the default one but that might not always be what you want) and apply a transform to set up the state of the application.

However your post gave me an idea to create a "basic controller" of sorts that would streamline a lof of the basic operations and allow to do what you ask for.

Could you please expand on what basic functionality would you like to have access to this way?

Thanks.

dsehnal avatar Nov 09 '16 21:11 dsehnal

@dsehnal

Sounds great, thanks.

Common Tasks:

  • create new instance (with default options)
  • load a PDB id (e.g. from PDBe backend)
  • load a custom PDB file (e.g. #3)
  • load an additional structure (pre-superposed)
  • show protein as cartoon
  • colour a particular residue (or region)
  • display a ligand as ball-and-stick
  • add label
  • tie methods to events (e.g. click residue)

One of my expectations was that there would be a simple way of showing how the web component could be recreated with inline code.

e.g. an inline equivalent of...

<pdb-lite-mol pdb-id="'1cbs'" hide-controls="true" load-ed-maps="true"></pdb-lite-mol>

would be something along the lines of ...

<div id="litemol"></div>
<script>
  // new instance
  let viewer = new LiteMol( { target: 'litemol', pdb_id: "1cbs", hide_controls: "true", ... });

then other stuff...

  // inline data
  viewer.loadPdbData( '1pdb', pdbDataAsString );

  // events
  viewer.on( 'residue.click', function(residue) { 
    console.log( "you clicked: ", residue.label ); 
  });

  // styles - e.g. color all Lysine residues red
  viewer.setStyle( { res_type: 'LYS' }, { color: 'red' } );

  // camera control
  let domain1 = viewer.select( { res_range: [ '23A', '140' ] } );
  viewer.centerOn( domain1 );

Note: I'm not suggesting that you should try and replicate an API on which I've spent 5 mins considering - just that this was the sort of thing I was expecting when approaching the project for the first time. If there's a better way of doing things then I'm very happy to learn something new. Probably just needs a bit of documentation that helps part-time (at best) javascript developers get up and running to the point where they can use the API docs.

I wrote up a tutorial for 3Dmol.js which essentially covered the kind of documentation that I would have found helpful as a first time user / developer - happy to do something similar here if that's useful.

As a side note, I think the API that 3Dmol offers for selection and styling is really powerful and intuitive (see "Dynamic Styles")

sillitoe avatar Nov 10 '16 12:11 sillitoe

@sillitoe

Thanks, I will see what I can do about this. I might have some initial version soon.

I understand that the entry barrier for using LiteMol can be somewhat high, mostly because the way the state is described and stored is very different from approaches that are commonly used. I will have to think of some way to wrap this functionality into a simpler API without sacrificing the initial goals of why the representation is the way it is.

One of my main goals with how the state is represented in LiteMol is to be able to reconstruct it effectively (not fully implemented yet). That's what the transforms are meant to do. In LiteMol, you only describe the state you want to arrive at. As a result, the state is uniquely identified by a tree of transforms and not the actual data, resulting in a very compact representation.

I wrote up a tutorial for 3Dmol.js which essentially covered the kind of documentation that I would have found helpful as a first time user / developer - happy to do something similar here if that's useful.

Writing a tutorial would be great.

As a side note, I think the API that 3Dmol offers for selection and styling is really powerful and intuitive (see "Dynamic Styles")

Something similar is present in LiteMol as well, although a bit more difficult to use, because LiteMol does not use objects to store information about atoms. But I suppose a wrapper could be written that creates a temporary object for each object to fill some basic properties.

A query language is a part of LiteMol as well that is based on the ideas used in PatternQuery. But if all goes well, a PyMOL-like version of the language will be available as well.

dsehnal avatar Nov 10 '16 13:11 dsehnal

Thanks - that's a very clear explanation (apologies if this is already written elsewhere)

I can see the advantage of using this kind of approach (avoiding large data objects). Probably not a good idea to force a particular API style on this if that would compromise performance or design goals - documentation and examples could go a long way.

Let me know if / how I can help with testing / documentation.

PatternQuery looks excellent

sillitoe avatar Nov 10 '16 14:11 sillitoe

@sillitoe

I have added the first iteration of the SimpleController class, a corresponding example, and a section to the FAQ.

It wraps the creation of the plugin instance and includes a default spec + some basic methods. It also hopefully makes creating/applying transforms, executing commands, and subscribing to events a bit more straightforward.

Let me know if / how I can help with testing / documentation.

This would be great. I can think of

  • Giving different use cases/suggesting features for the plugin.
  • Saying where the code/API is too complicated.
  • Writing simple tutorial(s) from the perspective of a "casual" user.
  • More questions for FAQ :)

Thanks for the feedback so far.

dsehnal avatar Nov 10 '16 15:11 dsehnal

Great - thanks.

Following the instructions in FAQ I'm getting the error:

TypeError: Plugin.create is not a function

Have I missed something obvious?

I've add screenshot with the 'Plugin' variable highlighted. litemol-bug

sillitoe avatar Nov 10 '16 16:11 sillitoe

No, this is my bad.

It needs to be LiteMol.Plugin.create (I copy-pasted it from the TypeScript code where the LiteMol namespace in implicit), fixed it in the FAQ.

dsehnal avatar Nov 10 '16 16:11 dsehnal

Great - all works.

Possible issue with vertical sizing?

i.e. I'm inserting this into

<div id="molview" style="height: 500px; width: 100%; border: 1px solid #eee"></div>

litemol-bug1

but the plugin renders above and below the target div box

litemol-bug1

shall I add this to a separate ticket?

sillitoe avatar Nov 10 '16 16:11 sillitoe

No, that's the way the controls are rendered when not in the fullscreen mode.

You can add layoutState: { hideControls: true } when creating the plugin to hide them by default.

dsehnal avatar Nov 10 '16 16:11 dsehnal

To expand on the controls a little, for example if you don't want the Log, you can create a custom spec (for example by copying it from one of the examples, or the default spec from here) where you simply delete the Log component from the corresponding array. You set it using customSpecification property when creating the plugin.

Similarly, you can still still use the SimpleController and add "custom controls" only for the entities you care about as shown in the CustomControls example.

dsehnal avatar Nov 10 '16 17:11 dsehnal

Thanks.

Yes, I had accidentally left out the margin-top and margin-bottom (which to be fair is explicitly mentioned in the FAQ)

sillitoe avatar Nov 10 '16 17:11 sillitoe