December 23, 2011

Chemdoodle web components tricks #1: scaling molecules

I have played around a bit with chemdoodle web compontents. Very nice GPL licensed javascript library for chemical 2D (and 3D if you have a webGL supporting browser).

However, the standard API still is missing some functionality. But you can fix most things by using standard javascript (at least as long as you're only using a standard viewer canvas, without zoom functionality).

Here I will show how you can scale a molecule to the size of the canvas. The standard viewercanvas will not scale molecules to the size of the canvas. So I added this to my code.

Standard canvas with a caffeine molecule and colored atom labels:

And here, the same canvas with the molecule scaled by the size of the canvas:

The javascript code for the standard canvas:

 
  var testmol = new ChemDoodle.ViewerCanvas('testmol', 300, 300);
  testmol.specs.atoms_useJMOLColors = true;
  var caffeineMolFile = 'Molecule Name\n  CHEMDOOD08070920033D 0   0.00000     0.00000     0\n[Insert Comment Here]\n 14 15  0  0  0  0  0  0  0  0  1 V2000\n   -0.3318    2.0000    0.0000   O 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318    1.0000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -1.1980    0.5000    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    0.5342    0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -1.1980   -0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -2.0640    1.0000    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n    1.4804    0.8047    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    0.5342   -0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -2.0640   -1.0000    0.0000   O 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318   -1.0000    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    2.0640   -0.0000    0.0000   C 0  0  0  2  0  0  0  0  0  0  0  0\n    1.7910    1.7553    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n    1.4804   -0.8047    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318   -2.0000    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n  1  2  2  0  0  0  0\n  3  2  1  0  0  0  0\n  4  2  1  0  0  0  0\n  3  5  1  0  0  0  0\n  3  6  1  0  0  0  0\n  7  4  1  0  0  0  0\n  4  8  2  0  0  0  0\n  9  5  2  0  0  0  0\n 10  5  1  0  0  0  0\n 10  8  1  0  0  0  0\n  7 11  1  0  0  0  0\n  7 12  1  0  0  0  0\n 13  8  1  0  0  0  0\n 13 11  2  0  0  0  0\n 10 14  1  0  0  0  0\nM  END\n> \n07-08-2009\n';
  var caffeine = ChemDoodle.readMOL(caffeineMolFile);
  testmol.loadMolecule(caffeine);

and the javascript code for the canvas with the scaled molecule:

 
  var testmol2 = new ChemDoodle.ViewerCanvas('testmol2', 300, 300);
  testmol2.specs.atoms_useJMOLColors = true;
  var caffeineMolFile = 'Molecule Name\n  CHEMDOOD08070920033D 0   0.00000     0.00000     0\n[Insert Comment Here]\n 14 15  0  0  0  0  0  0  0  0  1 V2000\n   -0.3318    2.0000    0.0000   O 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318    1.0000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -1.1980    0.5000    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    0.5342    0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -1.1980   -0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -2.0640    1.0000    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n    1.4804    0.8047    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    0.5342   -0.5000    0.0000   C 0  0  0  1  0  0  0  0  0  0  0  0\n   -2.0640   -1.0000    0.0000   O 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318   -1.0000    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n    2.0640   -0.0000    0.0000   C 0  0  0  2  0  0  0  0  0  0  0  0\n    1.7910    1.7553    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n    1.4804   -0.8047    0.0000   N 0  0  0  1  0  0  0  0  0  0  0  0\n   -0.3318   -2.0000    0.0000   C 0  0  0  4  0  0  0  0  0  0  0  0\n  1  2  2  0  0  0  0\n  3  2  1  0  0  0  0\n  4  2  1  0  0  0  0\n  3  5  1  0  0  0  0\n  3  6  1  0  0  0  0\n  7  4  1  0  0  0  0\n  4  8  2  0  0  0  0\n  9  5  2  0  0  0  0\n 10  5  1  0  0  0  0\n 10  8  1  0  0  0  0\n  7 11  1  0  0  0  0\n  7 12  1  0  0  0  0\n 13  8  1  0  0  0  0\n 13 11  2  0  0  0  0\n 10 14  1  0  0  0  0\nM  END\n> \n07-08-2009\n';
  var caffeine = ChemDoodle.readMOL(caffeineMolFile);
  // get the dimension of the molecule
  var size = caffeine.getDimension();
  // find the scale by taking the minimum of the canvas/size ratios
  var scale = Math.min(testmol2.width/size.x, testmol2.height/size.y);
  // load the molecule first (this function automatically sets scale, so we need to change specs after)
  testmol2.loadMolecule(caffeine);
  // change the specs.scale value to the scale calculated, shrinking it slightly so that text is not cut off
  testmol2.specs.scale = scale*.9;
  // repaint the canvas
  testmol2.repaint(); 

The code for the scaled figure updated after the comment below from Kevin Theisen. So now the code is simpler, but requires a repaint() command instead. Thanks to Kevin for this.

6 comments:

  1. Hi Patrik, nice post!

    Another way to do this is to change the scale parameter in the VisualSpecifications for the Canvas. This will preserve the styling perspective (bond widths to bond lengths for instance).

    // get the dimension of the molecule
    var size = caffeine.getDimension();
    // find the scale by taking the minimum of the canvas/size ratios
    var scale = Math.min(testmol2.width/size.x, testmol2.height/size.y);
    // load the molecule first (this function automatically sets scale, so we need to change specs after)
    testmol2.loadMolecule(caffeine);
    // change the specs.scale value to the scale calculated, shrinking it slightly so that text is not cut off
    testmol2.specs.scale = scale*.9;
    // repaint the canvas
    testmol2.repaint();

    ReplyDelete
  2. Code updated to use the nicer code in Kevin's comment.

    ReplyDelete
  3. Hello Patrick!
    Thank you very much for this tip! It works very fine (see here http://gmd.mpimp-golm.mpg.de/Analytes/0a2b3536-2245-4c0e-bdbc-495766eeec67.aspx)! Actually, I was looking for something like this since weeks. Do you know that "scaleToAverageBondLength(Number length)" Function of the ChemDoodle molecule which seems to be new since version 4.5.0.
    For me, the scaling to an average bond length improved your code since I have a lot of mol files from different sources.

    Thank you very much!
    Jan

    ReplyDelete
    Replies
    1. Good to hear Jan. If I run into any problems with my scaling I'll try the bond length scaling, currently I generate coordinates myself in CDK so I never had any such problems.

      Delete
  4. It is fascinating to join such a forceful and genuine talk with perusers of this blog and in addition perusers of different web journals or sites who truly thing that they can express more identified with this theme. shack tv

    ReplyDelete