Commit 77edb103 authored by Remi Perenon's avatar Remi Perenon

Merge branch 'bugfix-rbt_job_fixing' into 'develop'

Bugfix rbt job fixing

See merge request !37
parents 3b57bc91 46bb6ad4
Pipeline #4367 passed with stages
in 30 minutes and 42 seconds
...@@ -2,6 +2,7 @@ version 1.2.0 ...@@ -2,6 +2,7 @@ version 1.2.0
-------------- --------------
* ADDED issue #27 Better error handling when an error occurs when running an analysis from the GUI * ADDED issue #27 Better error handling when an error occurs when running an analysis from the GUI
* ADDED issue #10 Implemented Gromacs trajectory converter * ADDED issue #10 Implemented Gromacs trajectory converter
* FIXED issue #35 Result of RBT was incorrect /!\ Modifies job behavior
* FIXED issue #32 Result of DCSF was incorrect (the QVectors changed over frames) /!\ Modifies job behavior * FIXED issue #32 Result of DCSF was incorrect (the QVectors changed over frames) /!\ Modifies job behavior
* FIXED issue #31 Result of RMSD was incorrect (the sqrt was not applied) /!\ Modifies job behavior * FIXED issue #31 Result of RMSD was incorrect (the sqrt was not applied) /!\ Modifies job behavior
* FIXED issue #30 Normalization of VACF total value was incorrect /!\ Modifies job behavior * FIXED issue #30 Normalization of VACF total value was incorrect /!\ Modifies job behavior
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
''' '''
Created on Jun 9, 2015 Created on Jun 9, 2015
:author: Erc C. Pellegrini :author: Eric C. Pellegrini
''' '''
import collections import collections
...@@ -60,8 +60,7 @@ class RigidBodyTrajectory(IJob): ...@@ -60,8 +60,7 @@ class RigidBodyTrajectory(IJob):
settings['trajectory']=('mmtk_trajectory',{}) settings['trajectory']=('mmtk_trajectory',{})
settings['frames']=('frames', {"dependencies":{'trajectory':'trajectory'}}) settings['frames']=('frames', {"dependencies":{'trajectory':'trajectory'}})
settings['atom_selection']=('atom_selection',{"dependencies":{'trajectory':'trajectory'}}) settings['atom_selection']=('atom_selection',{"dependencies":{'trajectory':'trajectory'}})
settings['grouping_level']=('grouping_level',{"dependencies":{'trajectory':'trajectory','atom_selection':'atom_selection'}}) settings['grouping_level']=('grouping_level',{"default" : "atom","dependencies":{'trajectory':'trajectory','atom_selection':'atom_selection'}})
settings['stepwise']=('boolean',{'default':True})
settings['reference']=('integer',{"mini":0}) settings['reference']=('integer',{"mini":0})
settings['remove_translation']=('boolean',{'default':False}) settings['remove_translation']=('boolean',{'default':False})
settings['output_files']=('output_files', {"formats":["netcdf"]}) settings['output_files']=('output_files', {"formats":["netcdf"]})
...@@ -69,183 +68,128 @@ class RigidBodyTrajectory(IJob): ...@@ -69,183 +68,128 @@ class RigidBodyTrajectory(IJob):
def initialize(self): def initialize(self):
""" """
""" """
self.numberOfSteps = self.configuration['atom_selection']['selection_length'] self.numberOfSteps = self.configuration['frames']['number']
if (self.configuration['reference']['value'] >= self.configuration['trajectory']['length']): if (self.configuration['reference']['value'] >= self.configuration['trajectory']['length']):
raise JobError(self,'Invalid reference frame. Must be an integer in [%d,%d[' % (0,self.configuration['trajectory']['length'])) raise JobError(self,'Invalid reference frame. Must be an integer in [%d,%d[' % (0,self.configuration['trajectory']['length']))
self.nFrames = self.configuration['frames']['number']
self._rbt = {'trajectory':{}}
self._quaternions = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number'], 4),dtype=numpy.float64) self._quaternions = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number'], 4),dtype=numpy.float64)
self._coms = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number'], 3),dtype=numpy.float64) self._coms = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number'], 3),dtype=numpy.float64)
self._fits = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number']),dtype=numpy.float64) self._fits = numpy.zeros((self.configuration['atom_selection']['selection_length'],self.configuration['frames']['number']),dtype=numpy.float64)
atoms = sorted(self.configuration['trajectory']['universe'].atomList(), key=operator.attrgetter('index'))
self._groups = []
for i in range(self.configuration['atom_selection']['selection_length']):
indexes = self.configuration['atom_selection']["indexes"][i]
self._groups.append(Collection([atoms[idx] for idx in indexes]))
self.referenceFrame = self.configuration['reference']['value']
trajectory = self.configuration['trajectory']['instance']
self.referenceConfiguration = trajectory.universe.contiguousObjectConfiguration(conf = trajectory.configuration[self.referenceFrame])
selectedAtoms = Collection()
for indexes in self.configuration['atom_selection']['indexes']:
for idx in indexes:
selectedAtoms.addObject(atoms[idx])
# Create trajectory
self.outputFile = Trajectory(selectedAtoms, self.configuration['output_files']['files'][0], 'w')
# Create the snapshot generator
self.snapshot = SnapshotGenerator(self.configuration['trajectory']['universe'], actions = [TrajectoryOutput(self.outputFile, ["configuration","time"], 0, None, 1)])
def run_step(self, index): def run_step(self, index):
''' '''
''' '''
atoms = sorted(self.configuration['trajectory']['universe'].atomList(), key=operator.attrgetter('index')) trajectory = self.configuration['trajectory']['instance']
indexes = self.configuration['atom_selection']["indexes"][index] currentFrame = self.configuration['frames']['value'][index]
group = Collection([atoms[idx] for idx in indexes]) for group_id, group in enumerate(self._groups):
rbtPerGroup = {}
# Those matrix will store the quaternions and the CMS coming from the RBT trajectory.
rbtPerGroup['quaternions'] = numpy.zeros((self.configuration['frames']['number'], 4), dtype=numpy.float64)
rbtPerGroup['com'] = numpy.zeros((self.configuration['frames']['number'], 3), dtype=numpy.float64)
rbtPerGroup['fit'] = numpy.zeros((self.configuration['frames']['number'],), dtype=numpy.float64)
rbtPerGroup['trajectory'] = {}
# Case of a moving reference.
if self.configuration['stepwise']['value']:
# The reference configuration is always the one of the previous frame excepted for the first frame
# where it is set by definition to the first frame (could we think about a cyclic alternative way ?).
for comp in range(self.configuration['frames']['number']):
if comp == 0:
previousFrame = self.configuration['frames']['value'][0]
else:
previousFrame = self.configuration['frames']['value'][comp-1]
currentFrame = self.configuration['frames']['value'][comp]
refConfig = self.configuration['trajectory']['instance'].configuration[previousFrame]
# The RBT is created just for the current step.
rbt = self.configuration['trajectory']['instance'].readRigidBodyTrajectory(group,
first=currentFrame,
last=currentFrame+1,
skip=1,
reference=refConfig)
# The corresponding quaternions and cms are stored in their corresponding matrix.
rbtPerGroup['quaternions'][comp,:] = rbt.quaternions
rbtPerGroup['com'][comp,:] = rbt.cms
rbtPerGroup['fit'][comp] = rbt.fit
# The simplest case, the reference frame is fixed.
# A unique RBT is performed from first to last skipping skip steps and using refConfig as the reference.
else:
# If a fixed reference has been set. We can already set the reference configuration here. rbt = trajectory.readRigidBodyTrajectory(group,
refConfig = self.configuration['trajectory']['instance'].configuration[self.configuration['reference']['value']] first = currentFrame,
last = currentFrame+1,
# The RBT is created for the whole frame selection skip = 1,
rbt = self.configuration['trajectory']['instance'].readRigidBodyTrajectory(group, reference = self.referenceConfiguration)
first=self.configuration['frames']['first'],
last=self.configuration['frames']['last']+1, centerOfMass = group.centerOfMass(self.referenceConfiguration)
skip=self.configuration['frames']['step'],
reference=refConfig) # The rotation matrix corresponding to the selected frame in the RBT.
transfo = Quaternion(rbt.quaternions[0]).asRotation()
# The corresponding quaternions and cms are stored in their corresponding matrix.
rbtPerGroup['quaternions'] = rbt.quaternions
rbtPerGroup['com'] = rbt.cms if self.configuration['remove_translation']['value']:
rbtPerGroup['fit'] = rbt.fit # The transformation matrix corresponding to the selected frame in the RBT.
transfo = Translation(centerOfMass)*transfo
# Can not use the centers of mass defined by rbt.cms because the reference frame selected can be out of the selected frames for the Rigid Body Trajectory.
centerOfMass = group.centerOfMass(refConfig) # Compose with the CMS translation if the removeTranslation flag is set off.
else:
# Loop over the atoms of the group to set the RBT trajectory. # The transformation matrix corresponding to the selected frame in the RBT.
for atom in group: transfo = Translation(Vector(self._coms[group_id,index,:]))*transfo
rbtPerGroup['trajectory'][atom.index] = numpy.zeros((self.configuration['frames']['number'],3), dtype=numpy.float64)
# Loop over the atoms of the group to set the RBT trajectory.
# The coordinates of the atoms are centered around the center of mass of the group. for atom in group:
xyz = refConfig[atom] - centerOfMass
# The coordinates of the atoms are centered around the center of mass of the group.
# Loop over the selected frames. xyz = self.referenceConfiguration[atom] - centerOfMass
for comp in range(self.configuration['frames']['number']):
atom.setPosition(transfo(Vector(xyz)))
# The rotation matrix corresponding to the selected frame in the RBT.
transfo = Quaternion(rbtPerGroup['quaternions'][comp,:]).asRotation() self._quaternions[group_id,index,:] = rbt.quaternions[0]
self._coms[group_id,index,:] = rbt.cms[0]
if self.configuration['remove_translation']['value']: self._fits[group_id,index] = rbt.fit[0]
# The transformation matrix corresponding to the selected frame in the RBT.
transfo = Translation(centerOfMass)*transfo self.snapshot(data = {'time' : self.configuration['frames']['time'][currentFrame]})
# Compose with the CMS translation if the removeTranslation flag is set off. return index, None
else:
# The transformation matrix corresponding to the selected frame in the RBT.
transfo = Translation(Vector(rbtPerGroup['com'][comp,:]))*transfo
# The RBT is performed on the CMS centered coordinates of atom at.
rbtPerGroup['trajectory'][atom.index][comp,:] = transfo(Vector(xyz))
return index, rbtPerGroup
def combine(self, index, x): def combine(self, index, x):
""" """
""" """
self._quaternions[index] = x['quaternions'] pass
self._coms[index] = x['com']
self._fits[index] = x['fit']
self._rbt['trajectory'].update(x['trajectory'])
def finalize(self): def finalize(self):
''' '''
''' '''
atoms = sorted(self.configuration['trajectory']['universe'].atomList(), key=operator.attrgetter('index'))
selectedAtoms = Collection()
for indexes in self.configuration['atom_selection']['indexes']:
for idx in indexes:
selectedAtoms.addObject(atoms[idx])
# Create trajectory
outputFile = Trajectory(selectedAtoms, self.configuration['output_files']['files'][0], 'w')
# Create the snapshot generator
snapshot = SnapshotGenerator(self.configuration['trajectory']['universe'], actions = [TrajectoryOutput(outputFile, ["configuration","time"], 0, None, 1)])
# The output is written
for comp in range(self.configuration['frames']['number']):
currentFrame = self.configuration['frames']['value'][comp]
self.configuration['trajectory']['instance'].universe.setFromTrajectory(self.configuration['trajectory']['instance'], currentFrame)
for atom in selectedAtoms:
atom.setPosition(self._rbt['trajectory'][atom.index][comp,:])
snapshot(data = {'time' : self.configuration['frames']['time'][comp]})
outputFile.close()
outputFile = NetCDFFile(self.configuration['output_files']['files'][0], 'a') outputFile = NetCDFFile(self.configuration['output_files']['files'][0], 'a')
outputFile.createDimension('NFRAMES', self.configuration['frames']['number'])
outputFile.createDimension('NGROUPS', self.configuration['atom_selection']['selection_length']) outputFile.createDimension('NGROUPS', self.configuration['atom_selection']['selection_length'])
outputFile.createDimension('NFRAMES', self.configuration['frames']['number'])
outputFile.createDimension('QUATERNIONLENGTH',4) outputFile.createDimension('QUATERNIONLENGTH',4)
outputFile.createDimension('XYZ',3) outputFile.createDimension('XYZ',3)
# The NetCDF variable that stores the quaternions. # The NetCDF variable that stores the quaternions.
QUATERNIONS = outputFile.createVariable('quaternion', numpy.dtype(numpy.float64).char, ('NGROUPS', 'NFRAMES','QUATERNIONLENGTH')) QUATERNIONS = outputFile.createVariable('quaternions', numpy.dtype(numpy.float64).char, ('NGROUPS','NFRAMES','QUATERNIONLENGTH'))
# The NetCDF variable that stores the centers of mass. # The NetCDF variable that stores the centers of mass.
COM = outputFile.createVariable('com', numpy.dtype(numpy.float64).char, ('NGROUPS','NFRAMES','XYZ')) COM = outputFile.createVariable('coms', numpy.dtype(numpy.float64).char, ('NGROUPS','NFRAMES','XYZ'))
# The NetCDF variable that stores the rigid-body fit. # The NetCDF variable that stores the rigid-body fit.
FIT = outputFile.createVariable('fit', numpy.dtype(numpy.float64).char, ('NGROUPS','NFRAMES')) FIT = outputFile.createVariable('fits', numpy.dtype(numpy.float64).char, ('NGROUPS','NFRAMES'))
outputFile.info = str(self) outputFile.info = str(self)
# Loop over the groups. # Loop over the groups.
for comp in range(self.configuration['atom_selection']['selection_length']): for comp in range(self.configuration['atom_selection']['selection_length']):
aIndexes = self.configuration['atom_selection']['indexes'][comp] aIndexes = self.configuration['atom_selection']['indexes'][comp]
outputFile.info += 'Group %s: %s\n' % (comp, [index for index in aIndexes]) outputFile.info += 'Group %s: %s\n' % (comp, [index for index in aIndexes])
QUATERNIONS[comp,:,:] = self._quaternions[comp][:,:] QUATERNIONS.assignValue(self._quaternions[comp,:,:])
COM[comp,:,:] = self._coms[comp][:,:] COM.assignValue(self._coms[comp,:,:])
FIT[comp,:] = self._fits[comp][:] FIT.assignValue(self._fits[comp,:])
outputFile.close() outputFile.close()
REGISTRY['rbt'] = RigidBodyTrajectory REGISTRY['rbt'] = RigidBodyTrajectory
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