Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nbmolviz3d

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nbmolviz3d - npm Package Compare versions

Comparing version 0.0.2 to 0.1.0

example/css/home.css

38

example/js/main.js

@@ -0,16 +1,44 @@

import 'babel-polyfill';
import Backbone from 'backbone';
import { MolWidget3DModel, MolWidget3DView } from '../../src/main.js';
const bipyridine = require('raw!./bipyridine.sdf');
import ExampleSettingsView from './example_settings_view';
// import modelData from './3aid_model_data';
// import styles from './3aid_styles';
import modelData from './bipyridine_model_data';
import styles from './bipyridine_styles';
import orbital from './orbital';
import selectionTypesConstants from '../../src/constants/selection_types_constants';
Backbone.sync = () => {};
// Set up nbmolviz3d
const model = new MolWidget3DModel({
model_data: bipyridine,
model_data_format: 'sdf',
model_data: modelData,
styles,
shape: {
type: 'Arrow',
start: {
x: 0,
y: 0,
z: -2.5,
},
end: {
x: 0,
y: 0,
z: 3,
},
},
selection_type: selectionTypesConstants.ATOM,
orbital,
});
const view = new MolWidget3DView({
model,
el: document.querySelector('.app'),
el: document.querySelector('.nbmolviz3d'),
});
view.render();
view.render();
// Set up example settings controls
const settingsView = new ExampleSettingsView({
model,
});
document.querySelector('.data').appendChild(settingsView.render().el);

12

package.json
{
"name": "nbmolviz3d",
"version": "0.0.2",
"version": "0.1.0",
"description": "3D molecule visualization",

@@ -13,3 +13,4 @@ "main": "dist/bundle.js",

"backbone": "^1.3.3",
"jquery": "^3.1.0"
"jquery": "^3.1.0",
"keymirror": "^0.1.1"
},

@@ -19,2 +20,3 @@ "devDependencies": {

"babel-loader": "^6.2.4",
"babel-polyfill": "^6.13.0",
"babel-preset-es2015": "^6.6.0",

@@ -27,2 +29,3 @@ "chai": "^3.5.0",

"eslint-plugin-import": "^1.6.1",
"inline-environment-variables-webpack-plugin": "^1.1.0",
"karma": "^0.13.22",

@@ -33,2 +36,3 @@ "karma-mocha": "^0.2.2",

"mocha": "^2.4.5",
"nightwatch": "^0.9.8",
"node-sass": "^3.6.0",

@@ -38,2 +42,3 @@ "phantomjs-prebuilt": "^2.1.7",

"sass-loader": "^3.2.0",
"selenium-binaries": "0.8.0",
"sinon": "^2.0.0-pre.2",

@@ -48,3 +53,4 @@ "style-loader": "^0.13.1",

"watch": "webpack -p --config webpack.config.js --watch",
"example": "webpack-dev-server --content-base example/ --config example/webpack.config.js --progress --colors",
"example": "NODE_ENV=DEVELOPMENT webpack-dev-server --content-base example/ --config example/webpack.config.js --progress --colors",
"e2e": "./node_modules/nightwatch/bin/nightwatch",
"prepublish": "npm run build"

@@ -51,0 +57,0 @@ },

@@ -29,2 +29,24 @@ # nbmolviz3d

### model_data {Object}
JSON data representing the actual molecular input. Of the form:
{
atoms: [{
serial,
name,
elem,
mass_magnitude,
residue_index,
esidue_name,
chain,
positions,
momenta,
}, ... ],
bonds: [{
atom1_index,
atom2_index,
bond_order,
}, ... ],
}
### background_color {String} ['#73757C']

@@ -36,8 +58,40 @@ The background color of the visualization.

### model_data {String}
The actual text of the molecule input file.
### atom_labels_shown {Boolean} [false]
Indicates whether or not to show text labels on all atoms.
### model_data_format {String}
The file format of `model_data`, for example `sdf`.
### styles {Array of Objects} [[]]
An array indicating how to style individual atoms. Atoms are indicated by index, so the first style in this array corresponds to the first atom in `model_data.atoms`. Of the form:
[
{
visualization_type: 'stick'|'sphere'|'cartoon',
color: '#abcdef',
}, ...
]
### selected_atom_indices {Array of Numbers} [[]]
An array of atom indices indicating which atoms should be visually selected.
### selection_type {String} ['Atom']
A string indicating whether clicks select atoms ('Atom'), residues ('Residue'), or chains ('Chain').
### shape {Object} [{}]
Indicates a shape to display in the visualization using 3Dmol.js's [addShape method](http://3dmol.csb.pitt.edu/doc/$3Dmol.GLViewer.html#addShape). For example:
{
type: 'Sphere',
x: 0,
y: 0,
z: 0,
}
### orbital {Object} [{}]
Indicates an orbital to display using 3Dmol.js's [addIsosurface method](http://3dmol.csb.pitt.edu/doc/$3Dmol.GLViewer.html#addIsosurface). Of the type:
{
cube_file,
iso_val,
opacity,
}
## Development

@@ -44,0 +98,0 @@ A typical development flow might be to run the example while editing the code, where you'll want any changes to be immediately reflected in the example running in the browser. In that case you should run:

@@ -17,26 +17,26 @@ /**

import Backbone from 'backbone';
import selectionTypesConstants from '../constants/selection_types_constants';
const MolWidget3DModel = Backbone.Model.extend({
defaults: {
_model_name: 'MolWidget3DModel',
_view_name: 'MolWidget3DView',
_model_module: 'nbmolviz-js',
_view_module: 'nbmolviz-js',
_width: '500px',
_height: '500px',
viewerId: '',
click_selection: -1,
background_color: '0x73757C',
atom_labels_shown: false,
background_color: '#73757C',
background_opacity: 1.0,
color: null,
font_family: '',
font_size: '',
font_style: '',
font_weight: '',
layout: undefined,
msg_throttle: 3,
visible: true,
model_data: '',
model_data_format: '',
visualization_style: 'stick',
height: '500px',
model_data: { atoms: [], bonds: [] },
orbital: {
cube_file: '',
iso_val: null,
opacity: null,
},
styles: [],
selected_atom_indices: [],
selection_type: selectionTypesConstants.ATOM,
shape: {
type: '',
x: null,
y: null,
z: null,
},
width: '500px',
},

@@ -43,0 +43,0 @@ });

@@ -20,184 +20,33 @@ /**

const $3Dmol = require('../vendor/3Dmol');
import environmentConstants from '../constants/environment_constants';
import libUtils from '../utils/lib_utils';
import moleculeUtils from '../utils/molecule_utils';
function processCubeFile(cubeData, uuid) {
const volumeData = new $3Dmol.VolumeData(cubeData, 'cube');
this.pyObjects[uuid] = volumeData;
}
const DEFAULT_VISUALIZATION_TYPE = 'stick';
const DEFAULT_FONT_SIZE = 14;
const ORBITAL_COLOR_POSITIVE = 0xff0000;
const ORBITAL_COLOR_NEGATIVE = 0x0000ff;
function batchCommands(commands) {
const results = [];
const viewer = this;
commands.forEach((cmd) => {
const fn = viewer[cmd[0]];
const args = cmd[1];
fn.apply(viewer, args);
// results.push( fn.apply(viewer, args));
});
return results; // results are disabled because they sometimes lead to recursive JSON.
}
const MolWidget3DView = Backbone.View.extend({
initialize() {
if (process.env.NODE_ENV === environmentConstants.DEVELOPMENT) {
if (!window.nbmolviz3d) {
window.nbmolviz3d = [];
}
function renderPyShape(shape, spec, uuid, clickable) {
const newSpec = spec;
if (clickable === true) {
newSpec.clickable = true;
newSpec.callback = this.widget.setSelectionTrait;
}
const newShape = this[`add${shape}`](newSpec);
newShape.pyid = uuid;
this.pyObjects[uuid] = newShape;
}
function removePyShape(shapeId) {
const shape = this.pyObjects[shapeId];
this.removeShape(shape);
}
/*
function drawBond(atom1, atom2, order, spec) {
const newSpec = spec;
newSpec.start = {
x: atom1.x,
y: atom1.y,
z: atom1.z,
};
newSpec.end = {
x: atom1.x,
y: atom1.y,
z: atom1.z,
};
}
*/
function adjustClipping(minimum) {
const slab = this.getSlab();
if (slab.near > -minimum) slab.near = -minimum;
if (slab.far < minimum) slab.far = minimum;
this.setSlab(slab.near, slab.far);
}
function setAtomColor(atomJson, color) {
const atoms = this.selectedAtoms(atomJson);
atoms.map((atom) => {
const newAtom = atom;
for (const s of Object.keys(newAtom.style)) {
newAtom.style[s].color = color;
window.nbmolviz3d.push(this);
}
return newAtom;
});
this.forceRedraw();
}
function unsetAtomColor(atomJSON) {
const atoms = this.selectedAtoms(atomJSON);
atoms.map((atom) => {
const newAtom = atom;
for (const s of Object.keys(newAtom.style)) {
newAtom.style[s].color = undefined;
}
return newAtom;
});
this.forceRedraw();
}
function setColorArray(mapping) {
const atoms = this.selectedAtoms();
for (const color of Object.keys(mapping)) {
if (!mapping.hasOwnProperty(color)) continue;
mapping[color].index.forEach((ind) => { // this is probably fragile
const atom = atoms[ind];
if (atom.index !== ind) {
throw new Error(`selectedAtoms()[${ind}].index != ${ind}`);
}
const style = atom.style;
for (const s of Object.keys(style)) {
if (style.hasOwnProperty(s)) {
style[s].color = color;
}
}
});
}
this.forceRedraw();
}
function renderPyLabel(text, spec, uuid) {
const label = this.addLabel(text, spec);
this.pyObjects[uuid] = label;
}
function removePyLabel(labelId) {
const label = this.pyObjects[labelId];
this.removeLabel(label);
}
function drawIsosurface(dataId, shapeId, spec) {
const data = this.pyObjects[dataId];
const shape = this.addIsosurface(data, spec);
this.pyObjects[shapeId] = shape;
}
function addFrameFromList(positionList) {
const oldatoms = this.selectedAtoms({});
const newatoms = [];
for (let i = 0; i < oldatoms.length; i++) {
const atom = jQuery.extend({}, oldatoms[i]);
atom.x = positionList[i][0];
atom.y = positionList[i][1];
atom.z = positionList[i][2];
newatoms.push(atom);
}
const model = this.getModel(0);
return model.addFrame(newatoms);
}
function setPositions(positionList) {
const atoms = this.selectedAtoms();
for (let i = 0; i < atoms.length; i++) {
const atom = atoms[i];
atom.x = positionList[i][0];
atom.y = positionList[i][1];
atom.z = positionList[i][2];
}
this.forceRedraw();
}
function forceRedraw() {
// relies on adding the forceRedraw method
this.getModel().forceRedraw();
}
function makeAtomsClickable() {
this.setClickable({}, true, this.widget.setSelectionTrait);
}
function setBonds(bonds) {
const atoms = this.selectedAtoms();
bonds.forEach((bond) => {
const a = atoms[bond.index];
a.bonds = bond.nbr;
a.bondOrder = bond.order;
});
}
const MolWidget3DView = Backbone.View.extend({
initialize() {
this.model.on('change', this.render.bind(this));
window.nbmolviz3d = this;
},
render() {
document.last_3d_widget = this;
render(event) {
const modelDataChanged = !event || Object.keys(event.changed).indexOf('model_data') !== -1;
this.messages = [];
this.viewerId = this.model.get('viewerId');
this.mydiv = this.mydiv || document.createElement('div');
this.mydiv.classList.add('nbmolviz3d');
this.mydiv.style.width = this.model.get('_width');
this.mydiv.style.height = this.model.get('_height');
this.mydiv.style.width = this.model.get('width');
this.mydiv.style.height = this.model.get('height');
this.mydiv.style.position = 'relative';

@@ -209,3 +58,3 @@

this.viewer = this.renderViewer();
this.glviewer = this.renderViewer(modelDataChanged);

@@ -217,64 +66,111 @@ if (this.send) {

renderViewer() {
const glviewer = $3Dmol.viewers[this.viewerId] ||$3Dmol.createViewer(jQuery(this.mydiv), {
renderViewer(modelDataChanged) {
const glviewer = this.glviewer || $3Dmol.createViewer(jQuery(this.mydiv), {
defaultcolors: $3Dmol.rasmolElementColors,
});
if (typeof($3Dmol.widgets) === 'undefined') {
$3Dmol.widgets = {};
}
$3Dmol.viewers[this.viewerId] = glviewer;
$3Dmol.widgets[this.viewerId] = this;
$3Dmol.last_viewer = glviewer;
$3Dmol.last_widget = this;
// Maybe want to remove this monkeypatching some day ...
glviewer.setColorArray = setColorArray;
glviewer.processCubeFile = processCubeFile;
glviewer.pyObjects = {};
glviewer.addFrameFromList = addFrameFromList;
glviewer.drawIsosurface = drawIsosurface;
glviewer.widget = this;
glviewer.makeAtomsClickable = makeAtomsClickable;
glviewer.renderPyShape = renderPyShape;
glviewer.renderPyLabel = renderPyLabel;
glviewer.removePyShape = removePyShape;
glviewer.removePyLabel = removePyLabel;
glviewer.setAtomColor = setAtomColor;
glviewer.setPositions = setPositions;
glviewer.forceRedraw = forceRedraw;
glviewer.unsetAtomColor = unsetAtomColor;
glviewer.batchCommands = batchCommands;
glviewer.setBonds = setBonds;
glviewer.adjustClipping = adjustClipping;
document.last_3dmol_viewer = glviewer; // for debugging
glviewer.clear();
const modelData = this.model.get('model_data');
if (!modelData) {
// If no model data, just show a green sphere (the main 3dmol example)
glviewer.addSphere({ radius: 10, color: 'green' });
} else {
glviewer.addModel(modelData, this.model.get('model_data_format'), {
if (modelData) {
glviewer.addModel(moleculeUtils.modelDataToCDJSON(modelData), 'json', {
keepH: true,
});
// Hack in chain and residue data, since it's not supported by chemdoodle json
glviewer.getModel().selectedAtoms().forEach((atom) => {
const modifiedAtom = atom;
modifiedAtom.atom = modelData.atoms[atom.serial].name;
modifiedAtom.chain = modelData.atoms[atom.serial].chain;
modifiedAtom.resi = modelData.atoms[atom.serial].residue_index;
modifiedAtom.resn = modelData.atoms[atom.serial].residue_name;
});
}
glviewer.setStyle({}, { [this.model.get('visualization_style')]: {} });
glviewer.setBackgroundColor(this.model.get('background_color'), this.model.get('background_opacity'));
glviewer.zoomTo();
glviewer.makeAtomsClickable();
const styles = this.model.get('styles');
modelData.atoms.forEach((atom, i) => {
const style = styles[i] || {};
const libStyle = {};
const visualizationType = style.visualization_type || DEFAULT_VISUALIZATION_TYPE;
libStyle[visualizationType] = {};
Object.keys(style).forEach((styleKey) => {
libStyle[visualizationType][styleKey] = style[styleKey];
});
if (this.model.get('selected_atom_indices').indexOf(atom.serial) !== -1) {
libStyle[visualizationType].color = 0x1FF3FE;
}
if (typeof libStyle[visualizationType].color === 'string') {
libStyle[visualizationType].color = libUtils.colorStringToNumber(
libStyle[visualizationType].color
);
}
if (this.model.get('atom_labels_shown')) {
glviewer.addLabel(atom.name, {
fontSize: DEFAULT_FONT_SIZE,
position: {
x: atom.positions[0],
y: atom.positions[1],
z: atom.positions[2],
},
});
}
glviewer.setStyle({ serial: atom.serial }, libStyle);
});
// Shape
const shape = this.model.get('shape');
if (shape.type) {
glviewer[`add${shape.type}`](libUtils.getShapeSpec(shape, this.setSelectionTrait));
}
// Orbital
const orbital = this.model.get('orbital');
if (orbital.cube_file) {
const volumeData = new $3Dmol.VolumeData(orbital.cube_file, 'cube');
glviewer.addIsosurface(volumeData, {
isoVal: orbital.iso_val,
color: ORBITAL_COLOR_POSITIVE,
opacity: orbital.opacity,
});
glviewer.addIsosurface(volumeData, {
isoVal: -orbital.iso_val,
color: ORBITAL_COLOR_NEGATIVE,
opacity: orbital.opacity,
});
}
glviewer.setBackgroundColor(
libUtils.colorStringToNumber(this.model.get('background_color')),
this.model.get('background_opacity')
);
glviewer.setClickable({}, true, this.onClick.bind(this));
glviewer.render();
glviewer.zoom(0.8, 2000);
if (modelDataChanged) {
glviewer.zoomTo();
glviewer.zoom(0.8, 2000);
}
return glviewer;
},
setSelectionTrait() {
const result = {
model: this.model,
index: this.index,
serial: this.serial,
pyid: this.pyid,
};
this.model.set('_click_selection', result);
onClick(glAtom) {
const atoms = this.model.get('model_data').atoms;
const atom = atoms[glAtom.serial];
const selectionType = this.model.get('selection_type');
const selectedAtomIndices = this.model.get('selected_atom_indices');
const newSelectedAtomIndices = moleculeUtils.addSelection(
atoms,
selectedAtomIndices,
atom,
selectionType
);
this.model.set('selected_atom_indices', newSelectedAtomIndices);
this.model.save();

@@ -281,0 +177,0 @@ },

@@ -0,1 +1,2 @@

const InlineEnvironmentVariablesPlugin = require('inline-environment-variables-webpack-plugin');
const path = require('path');

@@ -34,3 +35,6 @@

},
plugins: [
new InlineEnvironmentVariablesPlugin(),
],
devtool: 'source-map',
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc