Commit 346bfbe1 authored by eric pellegrini's avatar eric pellegrini
Browse files

Added a generic ASCII trajectory converter

Many bug fixes related to ud
parent 83a72c1e
......@@ -36,9 +36,10 @@ import os
import wx
import wx.aui as wxaui
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE import LOGGER, REGISTRY
from MDANSE.Core.Error import Error
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser, AtomSelectionParserError
from MDANSE.MolecularDynamics.Trajectory import sorted_atoms
......
......@@ -33,8 +33,9 @@ import os
import wx
from MDANSE import ELEMENTS, LOGGER, REGISTRY, UD_STORE
from MDANSE import ELEMENTS, LOGGER, REGISTRY
from MDANSE.Externals.pubsub import pub as Publisher
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.App.GUI.Framework.Plugins.AtomSelectionPlugin import AtomSelectionPlugin
......
......@@ -35,8 +35,10 @@ import os
import wx
import wx.aui as wxaui
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE import LOGGER, REGISTRY
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict
......
......@@ -35,8 +35,10 @@ import os
import wx
import wx.aui as wxaui
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE import LOGGER, REGISTRY
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict
......@@ -124,7 +126,7 @@ class BasisSelectionPlugin(ComponentPlugin):
self._moleculeNames.SetItems(sorted(self._molecularContents.keys()))
def on_close(self, event):
def on_close(self, event=None):
self.parent.clear_selection()
self.parent.mgr.ClosePane(self.parent.mgr.GetPane(self))
......@@ -138,7 +140,6 @@ class BasisSelectionPlugin(ComponentPlugin):
if (not origin) or (not xAxis) or (not yAxis):
LOGGER("One of the atom selection is empty. Please select some values.", "error", ["dialog"])
return
if (origin == xAxis) or (origin == yAxis) or (xAxis == yAxis):
LOGGER("A basis can not be set from identical atom selections.", "error", ["dialog"])
......
......@@ -33,7 +33,6 @@ Created on Apr 14, 2015
import os
import subprocess
import sys
import tempfile
import time
import wx
......
......@@ -37,9 +37,11 @@ import wx.aui as wxaui
import wx.grid as wxgrid
from wx.lib.delayedresult import startWorker
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE import LOGGER, REGISTRY
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.App.GUI.ComboWidgets.ConfigurationPanel import ConfigurationPanel
from MDANSE.App.GUI.ComboWidgets.ProgressBar import ProgressBar
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
......
......@@ -34,7 +34,7 @@ import os
import wx.combo
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.App.GUI.Framework.Widgets.IWidget import IWidget
from MDANSE.App.GUI.ComboWidgets.ComboCheckbox import ComboCheckbox
......
......@@ -13,7 +13,6 @@ class MainApplication(wx.App):
f.Show()
self.SetTopWindow(f)
return True
class PeriodicTableApplication(wx.App):
......@@ -24,7 +23,6 @@ class PeriodicTableApplication(wx.App):
self.SetTopWindow(f)
return True
class PlotterApplication(wx.App):
def OnInit(self):
......@@ -42,4 +40,9 @@ class UserDefinitionViewerApplication(wx.App):
f.Show()
self.SetTopWindow(f)
return True
if __name__ == "__main__":
app = MainApplication()
app.MainLoop()
\ No newline at end of file
......@@ -57,7 +57,7 @@ class MainFrame(wx.Frame):
# Add some handlers to the loggers
LOGGER.add_handler("console", REGISTRY['handler']['console'](self._panels["controller"].pages["logger"]), level="info")
LOGGER.add_handler("dialog", REGISTRY['handler']['dialog'], level="error")
LOGGER.add_handler("dialog", REGISTRY['handler']['dialog'](), level="error")
LOGGER.start()
def build_dialog(self):
......
......@@ -35,7 +35,7 @@ import operator
import numpy
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE, UserDefinitionError
from MDANSE.Framework.UserDefinitionsStore import UD_STORE, UserDefinitionsStoreError
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser
......@@ -91,7 +91,7 @@ class AtomSelectionConfigurator(IConfigurator):
try:
ud = UD_STORE[trajConfig["basename"],"atom_selection",value]
# The input value is an atom selection string: parse it and update the configuration
except UserDefinitionError:
except UserDefinitionsStoreError:
parser = AtomSelectionParser(trajConfig["instance"].universe)
self["indexes"] = parser.parse(value)
self["expression"] = value
......
......@@ -31,7 +31,7 @@ Created on Mar 30, 2015
'''
from MDANSE import ELEMENTS
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE
from MDANSE.Framework.UserDefinitionsStore import UD_STORE
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser
......
......@@ -30,7 +30,7 @@ Created on Mar 30, 2015
@author: Eric C. Pellegrini and Bachir Aoun
'''
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE
from MDANSE.Framework.UserDefinitionsStore import UD_STORE, UserDefinitionsStoreError
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule
......@@ -73,11 +73,12 @@ class AxisSelection(IConfigurator):
trajConfig = configuration[self._dependencies['trajectory']]
ud = UD_STORE[trajConfig["basename"],"axis_selection",value]
if ud is not None:
self.update(ud)
else:
try:
ud = UD_STORE[trajConfig["basename"],"axis_selection",value]
except UserDefinitionsStoreError:
self.update(value)
else:
self.update(ud)
e1 = find_atoms_in_molecule(trajConfig['instance'].universe,self['molecule'], self['endpoint1'], True)
e2 = find_atoms_in_molecule(trajConfig['instance'].universe,self['molecule'], self['endpoint2'], True)
......
......@@ -30,7 +30,7 @@ Created on Mar 30, 2015
@author: Eric C. Pellegrini and Bachir Aoun
'''
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE
from MDANSE.Framework.UserDefinitionsStore import UD_STORE, UserDefinitionsStoreError
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule
......@@ -74,12 +74,14 @@ class BasisSelection(IConfigurator):
'''
trajConfig = configuration[self._dependencies['trajectory']]
ud = UD_STORE[trajConfig["basename"],"basis_selection",value]
if ud is not None:
self.update(ud)
else:
try:
ud = UD_STORE[trajConfig["basename"],"basis_selection",value]
except UserDefinitionsStoreError:
self.update(value)
else:
self.update(ud)
e1 = find_atoms_in_molecule(trajConfig['instance'].universe,self['molecule'], self['origin'], True)
e2 = find_atoms_in_molecule(trajConfig['instance'].universe,self['molecule'], self['x_axis'], True)
......
......@@ -31,7 +31,7 @@ Created on May 22, 2015
'''
from MDANSE import REGISTRY
from MDANSE.Framework.UserDefinitions.IUserDefinition import UD_STORE
from MDANSE.Framework.UserDefinitionsStore import UD_STORE, UserDefinitionsStoreError
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError
class QVectorsConfigurator(IConfigurator):
......@@ -70,15 +70,11 @@ class QVectorsConfigurator(IConfigurator):
trajConfig = configuration[self._dependencies['trajectory']]
ud = UD_STORE[trajConfig["basename"],"q_vectors",value]
if ud is not None:
try:
ud = UD_STORE[trajConfig["basename"],"q_vectors",value]
self["parameters"] = ud['parameters']
self["type"] = ud['generator']
self["is_lattice"] = ud['is_lattice']
self["q_vectors"] = ud['q_vectors']
else:
except UserDefinitionsStoreError:
generator, parameters = value
generator = REGISTRY["q_vectors"][generator](trajConfig["instance"])
generator.setup(parameters)
......@@ -86,6 +82,12 @@ class QVectorsConfigurator(IConfigurator):
if not data:
raise ConfiguratorError("no Q vectors could be generated", self)
else:
self["parameters"] = ud['parameters']
self["type"] = ud['generator']
self["is_lattice"] = ud['is_lattice']
self["q_vectors"] = ud['q_vectors']
self["parameters"] = parameters
self["type"] = generator.type
......
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
Created on Jun 08, 2015
@author: Eric C. Pellegrini
'''
import collections
import numpy
from MMTK import Atom, AtomCluster
from MMTK.ParticleProperties import Configuration, ParticleVector
from MMTK.Trajectory import Trajectory, SnapshotGenerator, TrajectoryOutput
from MMTK.Universe import InfiniteUniverse, ParallelepipedicPeriodicUniverse
from MDANSE import ELEMENTS
from MDANSE.Core.Error import Error
from MDANSE.Framework.Jobs.Converters.Converter import Converter
class GenericConverterError(Error):
pass
class GenericConverter(Converter):
"""
"""
type = 'generic'
label = "Generic"
category = ('Converters',)
ancestor = None
settings = collections.OrderedDict()
settings['gt_file'] = ('input_file',{'wildcard':"Generic trajectory files|*.gtf|All files|*"})
settings['output_file'] = ('output_files', {'formats':["netcdf"]})
def initialize(self):
'''
Initialize the job.
'''
self._gtFile = open(self.configuration["gt_file"]["filename"], 'rb')
if self._gtFile.readline().strip() != "MOLECULAR_CONTENTS":
raise GenericConverterError("Invalid keyword #1. Must be 'MOLECULAR_CONTENTS'")
# Read the number of molecular types that define the universe
try:
nMolecularTypes=int(self._gtFile.readline())
except ValueError:
raise GenericConverterError("Invalid type for 'MOLECULAR_CONTENTS' keyword. Must be an integer corresponding to the number of molecular types found in the simulation.")
# Blank line
self._gtFile.readline()
self._molecularTypes = collections.OrderedDict()
for _ in range(nMolecularTypes):
molName = self._gtFile.readline().strip()
if self._molecularTypes.has_key(molName):
raise GenericConverterError("Duplicate molecule name.")
self._molecularTypes[molName] = []
line = self._gtFile.readline().strip()
while line:
atomName, atomType = line.split()
if not atomType in ELEMENTS:
raise GenericConverterError("Unknown atom type: %s" % atomType)
self._molecularTypes[molName].append((atomName,atomType))
line = self._gtFile.readline().strip()
if self._gtFile.readline().strip() != "MOLECULES":
raise GenericConverterError("Invalid keyword #2. Must be 'MOLECULES'")
self._molecules = []
line=self._gtFile.readline().strip()
while line:
molName,nMols=line.strip().split()
if not self._molecularTypes.has_key(molName):
raise GenericConverterError("Unknown molecule name: %s" % molName)
try:
nMols = int(nMols)
except ValueError:
raise GenericConverterError("Invalid type for the number of atoms in molecule %s. Must be an integer." % molName);
self._molecules.append((molName,nMols))
line=self._gtFile.readline().strip()
# Read the number of steps
if self._gtFile.readline().strip() != "NSTEPS":
raise GenericConverterError("Invalid keyword#4: must be 'NSTEPS'")
try:
self.numberOfSteps=int(self._gtFile.readline())
except ValueError:
raise GenericConverterError("Invalid type for 'NSTEPS' keyword. Must be an integer corresponding to the number of steps of the simulation.")
# Read a blank line
self._gtFile.readline()
# Read the number of steps
if self._gtFile.readline().strip() != "TIMESTEP":
raise GenericConverterError("Invalid keyword#5: must be 'TIMESTEP'")
# Read the time step
try:
self._timeStep=float(self._gtFile.readline())
except ValueError:
raise GenericConverterError("Invalid type for 'TIMESTEP' keyword. Must be a float corresponding to the actual timestep of the simulation.")
# Read a blank line
self._gtFile.readline()
self._headerBlockSize=self._gtFile.tell()
# Read the first frame to define the size of various data block
# Read the current step number
if self._gtFile.readline().strip() != "STEP":
raise GenericConverterError("Invalid frame block. Must start with 'STEP' keyword.")
try:
_=int(self._gtFile.readline())
except ValueError:
raise GenericConverterError("Invalid type for 'STEP' keyword. Must be a in corresponding to the current step number of the simulation.")
# Read a blank line
self._gtFile.readline()
self._pbc = (self._gtFile.readline().strip() == "CELL")
if self._pbc:
self._universe = ParallelepipedicPeriodicUniverse()
pos = self._gtFile.tell()
self._gtFile.readline()
self._gtFile.readline()
self._gtFile.readline()
self._cellBlockSize=self._gtFile.tell()-pos
else:
self._universe = InfiniteUniverse()
for molName,nMols in self._molecules:
for _ in range(nMols):
molType = self._molecularTypes[molName]
temp = [Atom(atomType,name=atomName) for atomName,atomType in molType]
if len(temp)==1:
self._universe.addObject(temp[0])
else:
self._universe.addObject(AtomCluster(temp,name=molName))
# Read a blank line
self._gtFile.readline()
# Read the current configuration
if self._gtFile.readline().strip() != "CONFIGURATION":
raise GenericConverterError("Invalid frame block. Must contain 'CONFIGURATION' keyword.")
pos = self._gtFile.tell()
for _ in range(self._universe.numberOfAtoms()):
line=self._gtFile.readline()
self._dataBlockSize=self._gtFile.tell()-pos
line=line.split(',')
n=len(line)
if n==3:
self._hasVelocities=False
self._hasForces=False
elif n==6:
self._hasVelocities=True
self._hasForces=False
elif n==9:
self._hasVelocities=True
self._hasForces=True
else:
raise GenericConverterError("Invalid configuration line. Must contain3, 6 0r 9 comma-separated fixed-formatted floats.")
# Read a blank line
self._gtFile.readline()
if (self._hasVelocities or self._hasForces):
self._universe.initializeVelocitiesToTemperature(0.0)
self._velocities = ParticleVector(self._universe)
if self._hasForces:
self._forces = ParticleVector(self._universe)
# A MMTK trajectory is opened for writing.
self._trajectory = Trajectory(self._universe, self.configuration['output_file']['files'][0], mode='w')
# A frame generator is created.
self._snapshot = SnapshotGenerator(self._universe, actions = [TrajectoryOutput(self._trajectory, ["all"], 0, None, 1)])
self._frameBlockSize = self._gtFile.tell() - self._headerBlockSize
def run_step(self, index):
"""Runs a single step of the job.
@param index: the index of the step.
@type index: int.
@note: the argument index is the index of the loop note the index of the frame.
"""
self._gtFile.seek(self._headerBlockSize+index*self._frameBlockSize)
# Read a blank line
self._gtFile.readline()
try:
step=int(self._gtFile.readline())
except ValueError:
raise GenericConverterError('Invalid step number value.')
if self._pbc:
# Read two junk lines
self._gtFile.readline()
self._gtFile.readline()
cell = numpy.array([v.split(",") for v in self._gtFile.read(self._cellBlockSize).splitlines()],dtype=numpy.float64)
if cell.shape != (3,3):
raise GenericConverterError('Invalid cell data.')
self._universe.setShape(cell)
# Read two junk lines
self._gtFile.readline()
self._gtFile.readline()
config = numpy.array([v.split(",") for v in self._gtFile.read(self._dataBlockSize).splitlines()],dtype=numpy.float64)
self._universe.setConfiguration(Configuration(self._universe, config[:,0:3]))
self._universe.foldCoordinatesIntoBox()
data = {"time" : step*self._timeStep}
if self._hasVelocities:
self._velocities.array = config[:,3:6]
self._universe.setVelocities(self._velocities)
if self._hasForces:
self._forces.array = config[:,6:9]
data["forces"] = self._forces
# Store a snapshot of the current configuration in the output trajectory.
self._snapshot(data=data)
return index, None
def combine(self, index, x):
"""
@param index: the index of the step.
@type index: int.
@param x:
@type x: any.
"""
pass
def finalize(self):
"""
Finalize the job.
"""
self._gtFile.close()
# Close the output trajectory.
self._trajectory.close()
......@@ -74,7 +74,7 @@ class JobError(Error):
trace.append("\n%s" % self._message)
trace = '\n'.join(trace)
LOGGER(trace,'error',[job._name])
if job._status is not None:
......@@ -128,7 +128,7 @@ class IJob(Configurable):
return name
def __init__(self, status=None):
def __init__(self, status=False):
"""
The base class constructor.
"""
......@@ -143,7 +143,7 @@ class IJob(Configurable):
self._info = ""
if status is not None:
if status:
self._status = JobStatus(self)
else:
self._status = None
......@@ -467,7 +467,10 @@ class IJob(Configurable):
if getattr(self,'numberOfSteps', 0) <= 0:
raise JobError(self,"Invalid number of steps for job %s" % self._name)
mode = self.configuration['running_mode']['mode']
if self.configuration.has_key('running_mode'):
mode = self.configuration['running_mode']['mode']
else:
mode = 'monoprocessor'