3Dmol.js icon indicating copy to clipboard operation
3Dmol.js copied to clipboard

examples for isosurface coloring

Open gpwood opened this issue 3 years ago • 7 comments

Hello, in the release for 1.6.2 it mentions:

[1.6.2]
(https://github.com/3dmol/3Dmol.js/releases/tag/1.6.2)
Implement coloring an isosurface by a different volume data (e.g. isosurface drawn from electron density, colored by electrostatic potential).
setCameraParameters from @Luthaf. Several bug fixes, documentation tweaks, and added tests.

Are there any examples of how to do this in python? I have two cube files one of the ESP and one of the density.

Thanks

gpwood avatar Feb 03 '22 21:02 gpwood

Just following up on this suggestion, I did find this in the tests:

 $.get('data/chem/esp.cub', function(esp) {
     let densvol = new $3Dmol.VolumeData(density, 'cube');
     let espvol = new $3Dmol.VolumeData(esp, 'cube');
     viewer.addIsosurface(densvol, {isoval: 0.001, opacity: 0.9,
            smoothness: 4, voldata: espvol,
            volscheme: {gradient:'rwb', min:-.025, max:.025}});
     viewer.render();

but I'm unable to see how

 'densvol = new $3Dmol.VolumeData(density, 'cube');' 

can be called through py3dmol?

The documentation suggests this is not the case:

 addIsosurface(data, spec) → {[$3Dmol.GLShape](https://3dmol.csb.pitt.edu/doc/$3Dmol.GLShape.html)}
Construct isosurface from volumetric data. This is more flexible
than addVolumetricData, but can not be used with py3Dmol.

Thanks.

gpwood avatar Feb 04 '22 13:02 gpwood

Would you be willing to share your files so I can make a test case?

You should be able to use addVolumetricData. You will provide two sets of volumetric data, one for defining the isosurface and one for coloring it. Something like this (which I haven't tested):

      viewer.addVolumetricData(data, "cube", {isoval: -0.01, opacity:0.9, voldata: colordata, volformat: 'ccp4.gz', 
          volscheme: {gradient:'rwb', min:-.25, max:.25}});

dkoes avatar Feb 04 '22 21:02 dkoes

Hi!

Certainly, this is for water. Dt.cube.txt ESP.cube.txt

gpwood avatar Feb 07 '22 20:02 gpwood

Here's the actual example: https://3dmol.org/tests/auto/generate_test.cgi?test=testisovol

dkoes avatar Feb 08 '22 00:02 dkoes

Hello that looks great! I tried your code snippet above like this:

v = py3Dmol.view()
v.addVolumetricData(iso_density, "cube", {'isoval': -0.01, 'opacity':0.9, 'voldata': esp_file, 'volformat': 'ccp4.gz', 
      'volscheme': {'gradient':'rwb', min:-.25, max:.25}})
v.addModel(Chem.MolToMolBlock(pk.mol), 'mol')
v.setStyle({'stick':{}})
v.zoomTo()
v.show()

but I get this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/opt/anaconda3/envs/psi4/lib/python3.9/site-packages/py3Dmol/__init__.py:37, in tostr(arg)
     36 try:
---> 37     return json.dumps(arg)
 38 except TypeError:
File ~/opt/anaconda3/envs/psi4/lib/python3.9/json/__init__.py:231, in dumps(obj, skipkeys, ensure_ascii, check_circular, 
allow_nan, cls, indent, separators, default, sort_keys, **kw)
227 if (not skipkeys and ensure_ascii and
228     check_circular and allow_nan and
229     cls is None and indent is None and separators is None and
    230     default is None and not sort_keys and not kw):
--> 231     return _default_encoder.encode(obj)
    232 if cls is None:
File ~/opt/anaconda3/envs/psi4/lib/python3.9/json/encoder.py:199, in JSONEncoder.encode(self, o)
196 # This doesn't pass the iterator directly to ''.join() because the
197 # exceptions aren't as detailed.  The list call should be roughly
198 # equivalent to the PySequence_Fast that ''.join() would do.
 --> 199 chunks = self.iterencode(o, _one_shot=True)
200 if not isinstance(chunks, (list, tuple)):
 File ~/opt/anaconda3/envs/psi4/lib/python3.9/json/encoder.py:257, in JSONEncoder.iterencode(self, o, _one_shot)
253     _iterencode = _make_iterencode(
254         markers, self.default, _encoder, self.indent, floatstr,
255         self.key_separator, self.item_separator, self.sort_keys,
256         self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)
TypeError: keys must be str, int, float, bool or None, not builtin_function_or_method
 During handling of the above exception, another exception occurred:
 AttributeError                            Traceback (most recent call last)
  I.    nput In [28], in <module>
      1 v = py3Dmol.view()
----> 4 v.addVolumetricData(iso_density, "cube", {'isoval': -0.01, 'opacity':0.9, 'voldata': esp_file, 'volformat': 'ccp4.gz', 
      5           'volscheme': {'gradient':'rwb', min:-.25, max:.25}})
      6 v.addModel(Chem.MolToMolBlock(pk.mol), 'mol')
      7 v.setStyle({'stick':{}})
    File ~/opt/anaconda3/envs/psi4/lib/python3.9/site-packages/py3Dmol/__init__.py:293, in view.__getattr__. 
   <locals>.makejs(*args, **kwargs)
    291 cmd = '\tviewer_UNIQUEID.%s(' % name;
    292 for arg in args:
 --> 293     cmd += '%s,' % tostr(arg)
    294 cmd = cmd.rstrip(',')
    295 cmd += ');\n';
 File ~/opt/anaconda3/envs/psi4/lib/python3.9/site-packages/py3Dmol/__init__.py:39, in tostr(arg)
      37     return json.dumps(arg)
     38 except TypeError:
  ---> 39     return json.dumps(arg.tolist()
 AttributeError: 'dict' object has no attribute 'tolist'

gpwood avatar Feb 08 '22 01:02 gpwood

I forgot the quotes around min/max, which are required in python. Here's a py3Dmol example: https://colab.research.google.com/drive/1wJvyPMfBugpCOVesKEf2UMDm-q7iIK4Y?usp=sharing

dkoes avatar Feb 08 '22 01:02 dkoes

That's great, thank you!

gpwood avatar Feb 08 '22 03:02 gpwood