Source code for multiprocessing_sasmol

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
#from __future__ import unicode_literals

'''
    SASMOL: Copyright (C) 2011 Joseph E. Curtis, Ph.D. 

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''
import sys
import numpy
import math
import copy
import multiprocessing
import sasmol.system as system

#	MULTIPROCESSING_SASMOL
#
#	08/16/2015	--	initial coding			        :	jc
#
#	 1         2         3         4         5         6         7
# LC4567890123456789012345678901234567890123456789012345678901234567890123456789
#								       *      **
'''
    Multiprocessing_sasmol contains methods to manage the creation and combination
    of sasmol.system objects and to manage multiprocessing jobs using
    these objects.
'''

[docs]class Multiprocessing_SasMol(): """ Class containing methods to manage the creation and combination of sasmol.system objects and to manage multiprocessing jobs using these objects. Examples ======== First example shows how to use class methods from system object: >>> import sasmol.system as system >>> molecule = system.Molecule('hiv1_gag.pdb') >>> molecule.read_dcd('hiv1_gag_200_frames.dcd') >>> number_of_batches = 10 >>> test = Multiprocessing_SasMol() >>> molecules = test.divide_molecule(number_of_batches) >>> test.submit_jobs(molecules, test.example_worker, number_of_batches) >>> molecules = molecule.divide_molecule(number_of_batches) >>> test = Multiprocessing_SasMol() >>> test.submit_jobs(molecules, test.example_worker, number_of_batches) Note ---- THIS CLASS IS NEW AND IS UNDER ACTIVE DEVELOPMENT AND MAY CHANGE DRAMATICALLY ### LAST THREE LINES OF EXAMPLE ARE FOR CONSIDERATION FOR POTENTIAL WOULD REQUIRE CLASS TO INHERIT FROM SASMOL.SYSTEM.ATOM `self` parameter is not shown in the ``Parameters`` section in the documentation """ def __init__(self): pass
[docs] def get_frame_lists(self, number_of_frames, number_of_batches, **kwargs): ''' Utility method to determine individual frame lists for each of the total number_of_frames divided into number_of_batches Parameters ---------- number_of_frames integer : number of frames in complete molecule number_of_batches integer : number of frame groups to create kwargs optional future arguments Returns ------- frames integer list of frame lists Examples ------- >>> frames = self.get_frame_lists(molecule.number_of_frames(), number_of_batches) ''' remainder = number_of_frames%number_of_batches fpb = int(math.floor(float(number_of_frames)/float(number_of_batches))) frames = [] for batch in xrange(number_of_batches-1): starting_frame = fpb*batch ending_frame = fpb*batch + fpb - 1 frames.append([x for x in xrange(starting_frame, ending_frame+1)]) frames.append([x for x in xrange(ending_frame + 1, ending_frame + fpb + remainder +1)]) return frames
[docs] def example_worker(self, i, molecule, **kwargs): ''' Example method to execute in parallel using multiprocessing Parameters ---------- i integer : job number molecule sasmol object kwargs optional future arguments Returns ------- com list of float center_of_mass values ''' com = [molecule.calculate_center_of_mass(frame) for frame in xrange(molecule.number_of_frames())] return com
[docs] def divide_molecule(self, molecule, number_of_batches, **kwargs): ''' Method makes a deep copy of frame 0 of the input molecule into a set of new molecules indicated by the number_of_batches input variable. After duplicating the molecule, the coordinates are assigned to the duplicate molecules. The number of frames per duplicate is the same, except perhaps when the number of frames is not an equal divisor of number_of_batches which leads to the remainder frames assigned to the last duplicate molecule. Parameters ---------- molecule system object : number_of_batches integer : number of duplicate molecules to generate kwargs optional future arguments Returns ------- None updated self._coor Examples ------- >>> import sasmol.system as system >>> molecule = system.Molecule('hiv1_gag.pdb') >>> molecule.read_dcd('hiv1_gag_200_frames.dcd') >>> number_of_batches = 10 >>> test = Multiprocessing_SasMol() >>> molecules = test.divide_molecule(number_of_batches) >>> molecules = molecule.divide_molecule(number_of_batches) Note ------- Last line in the examples is an alternative use case to explore yet not implemented. ''' frames = self.get_frame_lists(molecule.number_of_frames(), number_of_batches) molecules = [copy.deepcopy(molecule) for x in xrange(number_of_batches)] for i in xrange(number_of_batches): dum_coor = numpy.zeros((len(frames[i]), molecule.natoms(), 3), numpy.float) molecules[i].setCoor(dum_coor) count = 0 for frame in frames[i]: molecules[i].coor()[count] = molecule.coor()[frame] count += 1 return molecules
[docs] def submit_jobs(self, molecules, target_method, number_of_jobs, **kwargs): ''' Utility method to start a set of multiprocessing jobs Parameters ---------- molecules list : system objects target_method string : name of method to call number_of_jobs int : number of job / processes to run kwargs optional future arguments Returns ------- None Examples ------- >>> test.submit_jobs(molecules, test.example_worker, number_of_batches) ''' jobs = [] for i in range(number_of_jobs): p = multiprocessing.Process(target=target_method, args=(i,molecules[i])) jobs.append(p) p.start()
if __name__ == "__main__" : pdbfilename = 'dum.pdb' dcdfilename = 'dum.dcd' mol = system.Molecule(pdbfilename) mol.read_dcd(dcdfilename) ''' number_of_batches = 10 test = Multiprocessing_SasMol() molecules = test.divide_molecule(mol, number_of_batches) com = [molecules[0].calculate_center_of_mass(frame) for frame in xrange(molecules[0].number_of_frames())] print ; print ; print print molecules[0].number_of_frames() st = '' for i in xrange(len(com)): print com[i].tolist() print ; print ; print test.submit_jobs(molecules, test.example_worker, number_of_batches) #for j in xrange(mol.number_of_frames()): # print com[j] '''