Commit 9e9c7fe1 authored by eric pellegrini's avatar eric pellegrini
Browse files

Added new PDB examples

Improved the ClassRegistry import mechanism (avoid conflict with distro
module with the same name)
Improved the performance of the molecular viewer
Removed unused import
Bug fix in QVectors widgets
parent 88a4aae3
This diff is collapsed.
This diff is collapsed.
......@@ -32,6 +32,7 @@ Created on Mar 30, 2015
import abc
import glob
import imp
import inspect
import os
import sys
......@@ -112,7 +113,7 @@ class ClassRegistry(abc.ABCMeta):
'''
Update the classes registry by importing all the modules contained in a given package.
Only the classes that are metaclassed by ClassRegistry will be registered.
Only the classes metaclassed by :py:class:`~MDANSE.Core.ClassRegistry.ClassRegistry` will be registered.
:param packageDir: the package for which all modules should be imported
:type packageDir: str
......@@ -125,16 +126,22 @@ class ClassRegistry(abc.ABCMeta):
if moduleFile == '__init__.py':
continue
moduleName, moduleExt = os.path.splitext(moduleFile)
moduleName, _ = os.path.splitext(moduleFile)
if moduleDir not in sys.path:
sys.path.append(moduleDir)
# Any error that may occur here has to be caught. In such case the module is skipped.
try:
__import__(moduleName, locals(), globals())
filehandler,path,description = imp.find_module(moduleName, [moduleDir])
mod = imp.load_module(moduleName,filehandler,path,description)
except:
continue
else:
if not os.path.samefile(os.path.dirname(mod.__file__),moduleDir):
print "A module with name %s is already present in your distribution with %s path." % (moduleName,)
@classmethod
def info(cls, interface):
......
......@@ -32,7 +32,7 @@ Created on Mar 30, 2015
class Error(Exception):
'''
Base class for handling exception occuring in MDANSE.
Base class for handling exception occurring in MDANSE.
Any exception defined in MDANSE should derive from it in order to be properly handled
in the GUI application.
......
......@@ -39,7 +39,6 @@ import os
import re
import subprocess
import tempfile
import types
from MDANSE.Core.Error import Error
......
......@@ -56,7 +56,7 @@ class Configurable(object):
settings = collections.OrderedDict()
def __init__(self):
def __init__(self,settings=None):
'''
Constructor
'''
......@@ -65,6 +65,9 @@ class Configurable(object):
self._configured=False
if settings is not None:
self.settings = settings
self.build_configuration()
def build_configuration(self):
......
......@@ -66,11 +66,11 @@ class PDBConverter(Converter):
self.numberOfSteps = self.configuration['nb_frame']["number"]
# Create all objects from the PDB file.
pdb_config = PDBFile(self.configuration['pdb_file']['filename'], model = 0)
pdb_config = PDBFile(self.configuration['pdb_file']['filename'], model=0)
# Create the universe.
self._universe = pdb_config.createUnitCellUniverse()
# Construct system
self._universe.addObject(pdb_config.createAll(None, 1))
......@@ -95,7 +95,7 @@ class PDBConverter(Converter):
pdb_config = PDBFile(self.configuration['pdb_file']['filename'], model=frame)
uni = pdb_config.createUnitCellUniverse()
uni.addObject(pdb_config.createAll(None, 1))
univ_config = Configuration(self._universe, uni.configuration().array)
self._universe.setConfiguration(univ_config)
......
......@@ -106,6 +106,8 @@ class IJob(Configurable):
type = "job"
section = "job"
ancestor = 'molecular_viewer'
@staticmethod
def define_unique_name():
......@@ -294,7 +296,7 @@ class IJob(Configurable):
f.write('\n')
f.write('job = REGISTRY[%r][%r]()\n' % ('job',cls.type))
f.write('job.run(parameters,status=False)')
f.write('job.run(parameters,status=True)')
f.close()
......
......@@ -27,12 +27,13 @@
'''
Created on Apr 14, 2015
:author: Eric C. ellegrini
:author: Eric C. Pellegrini
'''
import os
import subprocess
import sys
import tempfile
import time
import wx
......@@ -40,8 +41,9 @@ import wx.aui as aui
from MDANSE import PLATFORM,REGISTRY
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.GUI import DATA_CONTROLLER
from MDANSE.GUI.WorkingPanel import WorkingPanel
from MDANSE.GUI.ComboWidgets.ConfigurationPanel import ConfigurationPanel
from MDANSE.GUI.ComboWidgets.JobHelpFrame import JobHelpFrame
......@@ -106,10 +108,11 @@ class JobPlugin(ComponentPlugin):
return
name = self._job.define_unique_name()
script = os.path.join(PLATFORM.jobscripts_directory(),name)+'.py'
self._job.save(script, parameters)
handle,filename = tempfile.mkstemp(prefix="MDANSE_%s.py" % name, text=True)
os.close(handle)
self._job.save(filename, parameters)
if PLATFORM.name == "windows":
startupinfo = subprocess.STARTUPINFO()
......@@ -118,7 +121,7 @@ class JobPlugin(ComponentPlugin):
else:
startupinfo = None
subprocess.Popen([sys.executable, script], startupinfo=startupinfo, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.Popen([sys.executable, filename], startupinfo=startupinfo, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(1)
......@@ -159,7 +162,7 @@ class JobPlugin(ComponentPlugin):
class JobFrame(wx.Frame):
def __init__(self, parent, jobType, datakey):
def __init__(self, parent, jobType, datakey=None):
wx.Frame.__init__(self, parent, wx.ID_ANY, size = (800,400), style=wx.DEFAULT_DIALOG_STYLE|wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX|wx.RESIZE_BORDER)
......@@ -167,9 +170,10 @@ class JobFrame(wx.Frame):
self._datakey = datakey
data = REGISTRY['input_data']['mmtk_trajectory'](self._datakey)
DATA_CONTROLLER[filename] = data
if self._datakey is not None:
data = REGISTRY['input_data']['mmtk_trajectory'](self._datakey)
DATA_CONTROLLER[filename] = data
self.build_dialog()
......@@ -196,13 +200,10 @@ class JobFrame(wx.Frame):
self.Destroy()
if __name__ == "__main__":
from MDANSE.GUI import DATA_CONTROLLER
from MDANSE.GUI.WorkingPanel import WorkingPanel
filename = os.path.join(os.path.dirname(PLATFORM.package_directory()),'Data','Trajectories','MMTK','protein_in_periodic_universe.nc')
app = wx.App(False)
f = JobFrame(None,'mvi',filename)
f = JobFrame(None,'msd',filename)
f.Show()
app.MainLoop()
\ No newline at end of file
......@@ -94,7 +94,7 @@ class SelectionBox(vtk.vtkBoxWidget):
outlineMapper = vtk.vtkPolyDataMapper()
outlineMapper.SetInputConnection(outline.GetOutputPort())
self.box=vtk.vtkActor()
self.box=vtk.vtkLODActor()
self.box.SetMapper( outlineMapper )
self.box.GetProperty().SetColor(1,1,1)
self.box.PickableOff()
......@@ -159,7 +159,7 @@ class MolecularViewerPanel(ComponentPlugin):
category = ("Viewer",)
# 0 line / 1 sphere / 2 tube / 3 sphere + tube / 4 sphere + line
_rendmod = 3
_rendmod = 0
def __init__(self, parent, *args, **kwargs):
......@@ -290,21 +290,41 @@ class MolecularViewerPanel(ComponentPlugin):
# The number of atoms of the universe stored by the trajectory.
self._nAtoms = trajectory.universe.numberOfAtoms()
self.coords = trajectory.universe.contiguousObjectConfiguration().array
self._resolution = int(numpy.sqrt(300000.0 / self._nAtoms))
if self._resolution > 10:
self._resolution = 10
if self._resolution < 4:
self._resolution = 4
# The array that will store the color and alpha scale for all the atoms.
self._atomsColours , self._lut= self.build_ColorTransferFunction()
self.atomsColours = numpy.copy(self._atomsColours)
# The array that will store the scale for all the atoms.
self._atomsScales = numpy.array([ELEMENTS[at.symbol,'vdw_radius'] for at in self._atoms]).astype(numpy.float32)
scalars = ndarray_to_vtkarray(self.atomsColours, self._atomsScales, self._nAtoms)
bonds = vtk.vtkCellArray()
for at in self._atoms:
idx1 = at.index
for bat in at.bondedTo():
idx2 = bat.index
line = vtk.vtkLine()
line.GetPointIds().SetId(0,idx1)
line.GetPointIds().SetId(1,idx2)
bonds.InsertNextCell(line)
self._polydata = vtk.vtkPolyData()
self._polydata.GetPointData().SetScalars(scalars)
self._polydata.SetLines(bonds)
self.clear_universe()
self._trajectory = trajectory
# Set the configuration and display it.
self.set_configuration(frame)
self.enable_info_picking()
......@@ -803,7 +823,7 @@ class MolecularViewerPanel(ComponentPlugin):
outline_mapper = vtk.vtkPolyDataMapper()
outline_mapper.SetInputConnection(outline.GetOutputPort())
outline_actor = vtk.vtkActor()
outline_actor = vtk.vtkLODActor()
outline_actor.SetMapper(outline_mapper)
outline_actor.GetProperty().SetColor(1,0,0)
outline_actor.GetProperty().SetLineWidth(3)
......@@ -834,45 +854,25 @@ class MolecularViewerPanel(ComponentPlugin):
outline_mapper = vtk.vtkPolyDataMapper()
outline_mapper.SetInputConnection(outline.GetOutputPort())
outline_actor = vtk.vtkActor()
outline_actor = vtk.vtkLODActor()
outline_actor.SetMapper(outline_mapper)
outline_actor.GetProperty().SetColor(1,1,1)
outline_actor.GetProperty().SetLineWidth(3)
return outline_actor
def build_polydata(self):
def build_scene(self):
'''
build a vtkPolyData object for a given frame of the trajectory
'''
self._polydata = vtk.vtkPolyData()
# Converts the numpy coordinates into a vtk array
coords, self.vtkids = ndarray_to_vtkpoints(self.coords)
self._polydata.SetPoints(coords)
del coords
scalars = ndarray_to_vtkarray(self.atomsColours, self._atomsScales, self._nAtoms)
self._polydata.GetPointData().SetScalars(scalars)
del scalars
bonds = []
for at in self._atoms:
for bat in at.bondedTo():
if set([at.index,bat.index]) not in bonds:
bonds.append([at.index,bat.index])
bonds = ndarray_to_vtkcellarray(bonds)
self._polydata.SetLines(bonds)
del bonds
rendmod = self._rendmod
actor_list = []
line_acteur=None
ball_acteur=None
tube_acteur=None
actorList = []
lineActor=None
ballActor=None
tubeActor=None
if rendmod in [0,4] :
line_mapper = vtk.vtkPolyDataMapper()
if vtk.vtkVersion.GetVTKMajorVersion()<6:
......@@ -883,15 +883,17 @@ class MolecularViewerPanel(ComponentPlugin):
line_mapper.SetLookupTable(self._lut)
line_mapper.ScalarVisibilityOn()
line_mapper.ColorByArrayComponent("scalars", 1)
line_acteur = vtk.vtkActor()
line_acteur.GetProperty().SetLineWidth(3)
line_acteur.SetMapper(line_mapper)
actor_list.append(line_acteur)
lineActor = vtk.vtkLODActor()
lineActor.GetProperty().SetLineWidth(3)
lineActor.SetMapper(line_mapper)
actorList.append(lineActor)
if rendmod in [1,3,4]:
sphere = vtk.vtkSphereSource()
sphere.SetCenter(0, 0, 0)
sphere.SetRadius(0.2)
sphere.SetThetaResolution(self._resolution)
sphere.SetPhiResolution(self._resolution)
glyph = vtk.vtkGlyph3D()
if vtk.vtkVersion.GetVTKMajorVersion()<6:
glyph.SetInput(self._polydata)
......@@ -909,13 +911,15 @@ class MolecularViewerPanel(ComponentPlugin):
sphere_mapper.SetInputConnection(glyph.GetOutputPort())
sphere_mapper.ScalarVisibilityOn()
sphere_mapper.ColorByArrayComponent("scalars", 1)
ball_acteur = vtk.vtkActor()
ball_acteur.SetMapper(sphere_mapper)
ball_acteur.GetProperty().SetAmbient(0.2)
ball_acteur.GetProperty().SetDiffuse(0.5)
ball_acteur.GetProperty().SetSpecular(0.3)
actor_list.append(ball_acteur)
ballActor = vtk.vtkLODActor()
ballActor.SetMapper(sphere_mapper)
ballActor.GetProperty().SetAmbient(0.2)
ballActor.GetProperty().SetDiffuse(0.5)
ballActor.GetProperty().SetSpecular(0.3)
ballActor.SetNumberOfCloudPoints(30000)
actorList.append(ballActor)
self.glyph = glyph
if rendmod in [2,3] :
tubes = vtk.vtkTubeFilter()
if vtk.vtkVersion.GetVTKMajorVersion()<6:
......@@ -930,46 +934,45 @@ class MolecularViewerPanel(ComponentPlugin):
else:
tubes.SetCapping(0)
tubes.SetRadius(0.01)
tubes.SetNumberOfSides(self._resolution)
tube_mapper = vtk.vtkPolyDataMapper()
tube_mapper.SetLookupTable(self._lut)
tube_mapper.SetInputConnection(tubes.GetOutputPort())
tube_mapper.ScalarVisibilityOn()
tube_mapper.ColorByArrayComponent("scalars", 1)
tube_acteur = vtk.vtkActor()
tube_acteur.SetMapper(tube_mapper)
tube_acteur.GetProperty().SetAmbient(0.2)
tube_acteur.GetProperty().SetDiffuse(0.5)
tube_acteur.GetProperty().SetSpecular(0.3)
actor_list.append(tube_acteur)
tubeActor = vtk.vtkLODActor()
tubeActor.SetMapper(tube_mapper)
tubeActor.GetProperty().SetAmbient(0.2)
tubeActor.GetProperty().SetDiffuse(0.5)
tubeActor.GetProperty().SetSpecular(0.3)
actorList.append(tubeActor)
self.tubes = tubes
self.picking_domain = {0:line_acteur,1:ball_acteur,2:tube_acteur,3:ball_acteur,4:ball_acteur}[rendmod]
self.picking_domain = [lineActor,ballActor,tubeActor,ballActor,ballActor][rendmod]
basis_vector = self._trajectory.universe.basisVectors()
if not basis_vector is None:
self.bbox = self.build_bbox(basis_vector)
if not self.display_bbox:
self.bbox.VisibilityOff()
actor_list.append(self.bbox)
actorList.append(self.bbox)
assembly = vtk.vtkAssembly()
for actor in actor_list:
for actor in actorList:
assembly.AddPart(actor)
#self.build_real_bbox(assembly)
return assembly
def clear_universe(self):
if not hasattr(self, "molecule"):
if not hasattr(self, "_actors"):
return
self.molecule.VisibilityOff()
self.molecule.ReleaseGraphicsResources(self.get_renwin())
self._renderer.RemoveActor(self.molecule)
self._actors.VisibilityOff()
self._actors.ReleaseGraphicsResources(self.get_renwin())
self._renderer.RemoveActor(self._actors)
del self.molecule
del self._actors
def show_universe(self):
'''
......@@ -979,10 +982,10 @@ class MolecularViewerPanel(ComponentPlugin):
self.clear_universe()
# creating new polydata
self.molecule = self.build_polydata()
self._actors = self.build_scene()
# adding polydata to renderer
self._renderer.AddActor(self.molecule)
self._renderer.AddActor(self._actors)
# rendering
self._iren.Render()
......@@ -997,8 +1000,17 @@ class MolecularViewerPanel(ComponentPlugin):
self._currentFrame = frame % len(self._trajectory)
self._trajectory.universe.setConfiguration(self._trajectory.configuration[self._currentFrame])
self.coords = self._trajectory.universe.contiguousObjectConfiguration().array
coords = self._trajectory.universe.contiguousObjectConfiguration().array
points = vtk.vtkPoints()
points.SetNumberOfPoints(self._nAtoms)
for i in range(self._nAtoms):
x,y,z = coords[i]
points.SetPoint(i,x,y,z)
self._polydata.SetPoints(points)
# Reset the view.
self.show_universe()
......@@ -1018,7 +1030,7 @@ def ndarray_to_vtkarray(colors, radius, nbat):
color_scalars = vtk.vtkFloatArray()
color_scalars.SetNumberOfValues(colors.shape[0])
for i,c in enumerate(colors):
color_scalars.SetValue(i,c)
color_scalars.SetValue(i,c)
color_scalars.SetName("colors")
# some radii
......
......@@ -245,7 +245,7 @@ if __name__ == "__main__":
app = wx.App(False)
p = AtomsListDialog(None,t,3)
p = AtomsListDialog(None,t,10)
p.ShowModal()
......
......@@ -222,6 +222,7 @@ class QVectorsDialog(UserDefinitionsDialog):
return
self._ud['parameters'] = (qPanel.generator.type,qPanel.parameters)
self._ud['generator'] = qPanel.generator.type
self._ud['q_vectors'] = qPanel.grid.GetTable().data
self._ud['is_lattice'] = qPanel.generator.is_lattice
......
......@@ -47,7 +47,7 @@ class Logger(object):
def __call__(self,message,level="info",loggers=None):
lvl = Logger.levels.get(level,None)
# If the logging level is unkwnown, skip that log
if lvl is None:
return
......
......@@ -44,7 +44,8 @@ def build_connectivity(universe ,tolerance=0.05):
scannedObjects = [obj for obj in universe.objectList() if isinstance(obj,AtomCluster)]
singleAtomsObjects = [obj for obj in universe.objectList() if isinstance(obj,Atom) or obj.numberOfAtoms()==1]
scannedObjects.append(Collection(singleAtomsObjects))
if singleAtomsObjects:
scannedObjects.append(Collection(singleAtomsObjects))
for obj in scannedObjects:
......
......@@ -32,13 +32,13 @@ Created on Mar 26, 2015
from __pkginfo__ import __version__, __author__, __date__
from MDANSE.Logging.Logger import LOGGER
from MDANSE.Core.Platform import PLATFORM
from MDANSE.Core.ClassRegistry import ClassRegistry as REGISTRY
from MDANSE.Data.ElementsDatabase import ELEMENTS
from MDANSE.Logging.Logger import LOGGER
from MDANSE.Core.Preferences import PREFERENCES
import Framework
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment