def growingAverage(particleClassLists,score,angleObject,mask,destinationDirectory,preprocessing,verbose=False): import pytom_mpi if not pytom_mpi.isInitialised(): pytom_mpi.init() if pytom_mpi.size() > 1: mpi_myid = pytom_mpi.rank() if mpi_myid == 0: manager = GAManager(particleClassLists,score,angleObject,mask,destinationDirectory,preprocessing) manager.parallelGA(verbose) manager.parallelEnd() else: w = GAWorker(mpi_myid) w.run() else: print('Processing in sequential mode') manager = GAManager(particleClassLists,score,angleObject,mask,destinationDirectory,preprocessing) manager.sequentialGA(verbose) pytom_mpi.finalise()
def run(self, verbose=False): from sh_alignment.frm import frm_align from pytom.basic.structures import Shift, Rotation from pytom.tools.ProgressBar import FixedProgBar while True: # get the job try: job = self.get_job() except: if verbose: print(self.node_name + ': end') break # get some non-job message, break it if verbose: prog = FixedProgBar(0, len(job.particleList) - 1, self.node_name + ':') i = 0 ref = job.reference[0].getVolume() # run the job for p in job.particleList: if verbose: prog.update(i) i += 1 v = p.getVolume() pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume()) p.setShift( Shift([ pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2, pos[2] - v.sizeZ() / 2 ])) p.setRotation(Rotation(angle)) p.setScore(FRMScore(score)) # average the particle list name_prefix = os.path.join( self.destination, self.node_name + '_' + str(job.max_iter)) self.average_sub_pl(job.particleList, name_prefix, job.weighting) # send back the result self.send_result( FRMResult(name_prefix, job.particleList, self.mpi_id)) pytom_mpi.finalise()
def end(self, verbose=False): if verbose == True: print(self.node_name + ': sending end messages to others') from pytom.parallel.messages import StatusMessage mpi_numberNodes = pytom_mpi.size() mpi_myid = pytom_mpi.rank() for i in range(1, mpi_numberNodes): msg = StatusMessage(str(mpi_myid),str(i)) msg.setStatus("End") pytom_mpi.send(str(msg),i) pytom_mpi.finalise()
def run(self, verbose=False): from sh_alignment.frm import frm_align from sh_alignment.constrained_frm import frm_constrained_align, AngularConstraint from pytom.basic.structures import Shift, Rotation from pytom.tools.ProgressBar import FixedProgBar from pytom.basic.transformations import resize, resizeFourier binningType = 'Fourier' while True: # get the job try: job = self.get_job() except: if verbose: print(self.node_name + ': end') break # get some non-job message, break it if verbose: prog = FixedProgBar(0, len(job.particleList) - 1, self.node_name + ':') i = 0 ref = job.reference.getVolume() if job.binning > 1: ref = resize(volume=ref, factor=1. / job.binning, interpolation=binningType) if type(ref) == tuple: ref = ref[0] # re-set max frequency in case it exceeds Nyquist - a bit brute force job.freq = min(job.freq, ref.sizeX() // 2 - 1) # run the job for p in job.particleList: if verbose: prog.update(i) i += 1 v = p.getVolume() if job.binning > 1: v = resize(volume=v, factor=1. / job.binning, interpolation=binningType) if type(v) == tuple: v = v[0] mask = job.mask.getVolume() if job.binning > 1: mask = resize(volume=mask, factor=1. / job.binning, interpolation='Spline') if type(mask) == tuple: mask = mask[0] if job.constraint: constraint = job.constraint if job.constraint.type == AngularConstraint.ADP_ANGLE: # set the constraint around certain angle rot = p.getRotation() constraint.setAngle(rot.getPhi(), rot.getPsi(), rot.getTheta()) #pos, angle, score = frm_constrained_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume(), constraint) if job.binning > 1: pos, angle, score = frm_constrained_align( v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset / job.binning, mask, constraint) else: pos, angle, score = frm_constrained_align( v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, mask, constraint) else: #pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume()) #if job.binning >1: # print(job.peak_offset) # print(type(job.peak_offset)) # print(job.peak_offset/job.binning) # print(type(job.binning)) # pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, # job.peak_offset/job.binning, mask) #else: pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, mask) if job.binning > 1: pos[0] = job.binning * (pos[0] - v.sizeX() / 2) pos[1] = job.binning * (pos[1] - v.sizeY() / 2) pos[2] = job.binning * (pos[2] - v.sizeZ() / 2) p.setShift(Shift([pos[0], pos[1], pos[2]])) else: p.setShift( Shift([ pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2, pos[2] - v.sizeZ() / 2 ])) p.setRotation(Rotation(angle)) p.setScore(FRMScore(score)) # average the particle list name_prefix = os.path.join( job.destination, self.node_name + '_' + str(job.max_iter)) self.average_sub_pl(job.particleList, name_prefix, job.weighting) # send back the result self.send_result( FRMResult(name_prefix, job.particleList, self.mpi_id)) pytom_mpi.finalise()
def parallelStart_splitVol(self, job, splitX, splitY, splitZ, verbose=True): """ """ self.parallelInit() import pytom_mpi mpi_myid = pytom_mpi.rank() if mpi_myid == 0: # manager # distribute the job to the workers and get the original size of the volume self.splitVolumes(job, splitX, splitY, splitZ, verbose) [vsizeX, vsizeY, vsizeZ] = self.jobInfo["originalSize"] # gather results and post processing from pytom_volume import vol volume = vol(vsizeX, vsizeY, vsizeZ) volume.setAll(0) orient = vol(vsizeX, vsizeY, vsizeZ) orient.setAll(0) i = 0 while i < splitX * splitY * splitZ: mpi_msgString = getMsgStr() msg = self.getResMsg(mpi_msgString) resFromWorker = self.resFromMsg(msg) if verbose == True: print("Manager: processing result from worker " + msg.getSender()) resV = resFromWorker.result.getVolume() resO = resFromWorker.orient.getVolume() jobID = resFromWorker.jobID [sizeX, sizeY, sizeZ] = self.jobInfo["splitSize"] [sub_start, start] = self.jobInfo[jobID] from pytom_volume import subvolume, putSubVolume sub_resV = subvolume(resV, sub_start[0], sub_start[1], sub_start[2], sizeX, sizeY, sizeZ) sub_resO = subvolume(resO, sub_start[0], sub_start[1], sub_start[2], sizeX, sizeY, sizeZ) putSubVolume(sub_resV, volume, start[0], start[1], start[2]) putSubVolume(sub_resO, orient, start[0], start[1], start[2]) i = i + 1 # write the final result back to the disk volume.write(self.name + '_res.em') orient.write(self.name + '_orient.em') # delete the temporary files on the disk import os files = os.listdir('.') for name in files: if 'job' in name and '.em' in name and not 'sum' in name and not 'sqr' in name: os.remove(name) # rename the result files name os.rename('node_0_res.em', 'scores{}{}.em'.format(suffix)) os.rename('node_0_orient.em', 'angles{}{}.em'.format(suffix)) # finishing, stop all workers self.parallelEnd(verbose) if verbose == True: print("Manager: end") else: # worker worker = PeakWorker() worker.parallelRun(verbose) pytom_mpi.finalise()
def parallelRun(self, job, splitX=0, splitY=0, splitZ=0, verbose=True, gpuID=-1): """ parallelRun: Parallel run the job on the computer cluster. @param job: job @type job: L{pytom.localization.peak_job.PeakJob} @param splitX: split part along the x dimension @type splitX: integer @param splitY: split part along the y dimension @type splitY: integer @param splitZ: split part along the z dimension @type splitZ: integer """ import pytom_mpi if self.mpi_id == 0: # send the first message # if not pytom_mpi.isInitialised(): # pytom_mpi.init() job.members = pytom_mpi.size() print('job members', job.members) job.send(0, 0) print("\n") self.gpuID = gpuID end = False while not end: # get the message string mpi_msgString = getMsgStr() msgType = self.getMsgType(mpi_msgString) if msgType == 2: # Job msg msg = self.getJobMsg(mpi_msgString) job = self.jobFromMsg(msg) # set members if self.mpi_id == 0: self.distributeJobs(job, splitX, splitY, splitZ) else: self.distributeJobs(job) result = self.run(verbose, gpuID=gpuID) self.summarize(result, self.jobID) elif msgType == 1: # Result msg msg = self.getResMsg(mpi_msgString) res = self.resFromMsg(msg) if verbose == True: print(self.name + ": processing result from worker " + msg.getSender()) resV = res.result.getVolume() resO = res.orient.getVolume() jobID = res.jobID self.summarize([resV, resO], jobID) elif msgType == 0: # Status msg # get the message as StatusMessage and finish from pytom.parallel.messages import StatusMessage msg = StatusMessage('', '') msg.fromStr(mpi_msgString) if msg.getStatus() == 'End': end = True if verbose == True: print(self.name + ': end') else: # Error raise RuntimeError("False message type!") if self.mpi_id == 0: # delete the temporary files on the disk import os files = os.listdir(self.dstDir) for name in files: if 'job' in name and '.em' in name and not 'sum' in name and not 'sqr' in name: os.remove(self.dstDir + '/' + name) if self.gpuID: gpuflag = '' else: gpuflag = '' # rename the result files name os.rename( self.dstDir + '/' + 'node_0_res.em', self.dstDir + '/' + 'scores_{}{}.em'.format(self.suffix, gpuflag)) os.rename( self.dstDir + '/' + 'node_0_orient.em', self.dstDir + '/' + 'angles_{}{}.em'.format(self.suffix, gpuflag)) self.clean() # clean itself pytom_mpi.finalise()
def parallelReconstruction(particleList, projectionList, cubeSize, binning, applyWeighting,verbose=False): """ parallelReconstruction """ import pytom_mpi from pytom.parallel.messages import StatusMessage if not pytom_mpi.isInitialised(): pytom_mpi.init() mpi_id = pytom_mpi.rank() if mpi_id == 0: firstDistribute = False numberWorkers = pytom_mpi.size() -1 #split particleList by number nodes splitSize = len(particleList) / numberWorkers pl = [] for i in range(0,len(particleList),splitSize): pl.append(particleList[i:i+splitSize]) for i in range(0,numberWorkers): msg = ReconstructionMessage(0,i+1,pl[i],projectionList,cubeSize, binning,applyWeighting) pytom_mpi.send(str(msg),i+1) finished = False msgCounter = 0 while not finished: mpi_msgString = pytom_mpi.receive() msg = StatusMessage(1,'0') msg.fromStr(mpi_msgString) if not msg.getStatus() == 'Finished': print('Worker ' + str(msg.getSender()) + ' sent status: ' + str(msg.getStatus())) msgCounter += 1 finished = msgCounter == numberWorkers for i in range(0,numberWorkers): msg = StatusMessage(mpi_id,'0') msg.setStatus('End') pytom_mpi.send(str(msg),i+1) else: worker = ReconstructionWorker() worker.parallelRun(verbose) pytom_mpi.finalise()
def run(self, verbose=False): from sh_alignment.frm import frm_align from pytom.basic.structures import Shift, Rotation from pytom.tools.ProgressBar import FixedProgBar from pytom.basic.fourier import convolute from pytom_volume import read, power while True: # get the job try: job = self.get_job() except: if verbose: print(self.node_name + ': end') break # get some non-job message, break it if verbose: prog = FixedProgBar(0, len(job.particleList) - 1, self.node_name + ':') i = 0 ref = [] ref.append(job.reference[0].getVolume()) ref.append(job.reference[1].getVolume()) # convolute with the approximation of the CTF if job.sum_ctf_sqr: ctf = read(job.sum_ctf_sqr) power(ctf, 0.5) # the number of CTFs should not matter, should it? ref0 = ref[0] ref1 = ref[1] ref0 = convolute(ref0, ctf, True) ref1 = convolute(ref1, ctf, True) ref = [ref0, ref1] if job.bfactor and job.bfactor != 'None': # restore_kernel = create_bfactor_restore_vol(ref.sizeX(), job.sampleInformation.getPixelSize(), job.bfactor) from pytom_volume import vol, read bfactor_kernel = read(job.bfactor) unit = vol(bfactor_kernel) unit.setAll(1) restore_kernel = unit / bfactor_kernel # run the job for p in job.particleList: if verbose: prog.update(i) i += 1 v = p.getVolume() # if weights is None: # create the weights according to the bfactor # if job.bfactor == 0: # weights = [1 for k in xrange(job.freq)] # else: # restore_fnc = create_bfactor_restore_fnc(ref.sizeX(), job.sampleInformation.getPixelSize(), job.bfactor) # # cut out the corresponding part and square it to get the weights! # weights = restore_fnc[1:job.freq+1]**2 if job.bfactor and job.bfactor != 'None': v = convolute(v, restore_kernel, True) # if bfactor is set, restore it pos, angle, score = frm_align(v, p.getWedge(), ref[int(p.getClass())], None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume()) p.setShift( Shift([ pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2, pos[2] - v.sizeZ() / 2 ])) p.setRotation(Rotation(angle)) p.setScore(FRMScore(score)) # average the particle list name_prefix = self.node_name + '_' + str(job.max_iter) pair = ParticleListPair('', job.ctf_conv_pl, None, None) pair.set_phase_flip_pl(job.particleList) self.average_sub_pl( pair.get_ctf_conv_pl(), name_prefix) # operate on the CTF convoluted projection! # send back the result self.send_result( FRMResult(name_prefix, job.particleList, self.mpi_id)) pytom_mpi.finalise()
def distributedCorrelationMatrix(job, verbose=False): """ distributedCorrelationMatrix: Performs calculation of correlation matrix either on multiple processes or sequentially. """ import pytom_mpi pytom_mpi.init() if pytom_mpi.size() > 1: mpi_myid = pytom_mpi.rank() if mpi_myid == 0: manager = CMManager(job) manager.distributeCalculation(mpi_myid, verbose) manager.parallelEnd() manager.saveMatrix() else: from pytom.parallel.clusterMessages import CorrelationVectorMessage, CorrelationVectorJobMessage from pytom.parallel.messages import StatusMessage, MessageError end = False while not end: mpi_msg = pytom_mpi.receive() if verbose: print(mpi_msg) try: msg = CorrelationVectorJobMessage() msg.fromStr(mpi_msg) worker = CMWorker(msg.getJob()) #worker.dumpMsg2Log('node'+str(mpi_myid)+'.log', msg.__str__()) resultVector = worker.run() resultMessage = CorrelationVectorMessage(mpi_myid, 0) resultMessage.setVector(resultVector) #worker.dumpMsg2Log('node'+mpi_myid.__str__()+'.log', resultMessage.__str__()) if verbose and False: print(resultMessage) pytom_mpi.send(resultMessage.__str__(), 0) except (MessageError, RuntimeError, IndexError): msg = StatusMessage('', '') msg.fromStr(mpi_msg) if msg.getStatus() == 'End': end = True print('Node ' + mpi_myid.__str__() + ' finished') else: print('Sequential Processing! Running on one machine only!') manager = CMManager(job) manager.calculateMatrix() manager.saveMatrix() pytom_mpi.finalise()
def run(self, verbose=False): from pytom.gui.additional.frm import frm_align from sh_alignment.constrained_frm import frm_constrained_align, AngularConstraint from pytom.basic.structures import Shift, Rotation from pytom.tools.ProgressBar import FixedProgBar while True: # get the job try: job = self.get_job() except: if verbose: print self.node_name + ': end' break # get some non-job message, break it if verbose: prog = FixedProgBar(0, len(job.particleList) - 1, self.node_name + ':') i = 0 ref = job.reference.getVolume() # run the job for p in job.particleList: if verbose: prog.update(i) i += 1 v = p.getVolume() if job.constraint: constraint = job.constraint if job.constraint.type == AngularConstraint.ADP_ANGLE: # set the constraint around certain angle rot = p.getRotation() constraint.setAngle(rot.getPhi(), rot.getPsi(), rot.getTheta()) pos, angle, score = frm_constrained_align( v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume(), constraint) else: pos, angle, score = frm_align(v, p.getWedge(), ref, None, job.bw_range, job.freq, job.peak_offset, job.mask.getVolume()) p.setShift( Shift([ pos[0] - v.sizeX() / 2, pos[1] - v.sizeY() / 2, pos[2] - v.sizeZ() / 2 ])) p.setRotation(Rotation(angle)) p.setScore(FRMScore(score)) # average the particle list name_prefix = self.node_name + '_' + str(job.max_iter) self.average_sub_pl(job.particleList, name_prefix, job.weighting) # send back the result self.send_result( FRMResult(name_prefix, job.particleList, self.mpi_id)) pytom_mpi.finalise()
def parallelWork(self, verbose=False, doFinalize=True): """ parallelWork: Distribute joblist to workers. Leave as it is. @param verbose: @param doFinalize: """ import pytom_mpi from pytom.parallel.messages import Message, StatusMessage, MessageError from pytom.basic.exceptions import ParameterError from pytom.basic.structures import PyTomClassError if not pytom_mpi.isInitialised(): pytom_mpi.init() if self._mpi_id == 0: #if current node == 0, be the master node numberJobs = len(self._jobList) if self._numberWorkers <= numberJobs: numberJobsToSend = self._numberWorkers else: numberJobsToSend = numberJobs for i in range(0, numberJobsToSend): #send out all first numberJobsToSend jobs pytom_mpi.send(str(self._jobList[i]), i + 1) numberFinishedJobs = 0 numberSentJobs = numberJobsToSend finished = numberSentJobs == numberJobs and numberFinishedJobs == numberJobs while not finished: #distribute remaining jobs to finished workers mpi_msgString = pytom_mpi.receive() msg = Message('1', '0') msg.fromStr(mpi_msgString) numberFinishedJobs += 1 if numberSentJobs < numberJobs: pytom_mpi.send(str(self._jobList[numberSentJobs]), int(msg.getSender())) numberSentJobs += 1 finished = numberSentJobs == numberJobs and numberFinishedJobs == numberJobs if doFinalize: for i in range(0, self._numberWorkers): msg = StatusMessage('0', i + 1) msg.setStatus('End') pytom_mpi.send(str(msg), i + 1) print('Sending end msg to:', i + 1) else: #if any other node id, be a worker node end = False while not end: #listen for messages mpi_msgString = pytom_mpi.receive() if verbose: print(mpi_msgString) try: #wait for job and start processing msg = self.getMsgObject(mpi_msgString) self.setJob(msg) self.run() resultMsg = StatusMessage(self._mpi_id, '0') resultMsg.setStatus('Finished') pytom_mpi.send(str(resultMsg), 0) except (MessageError, PyTomClassError, ParameterError): try: #message is a StatusMessage #if message status is End, finish this worker. #You can also add other statuses msg = StatusMessage('', '') msg.fromStr(mpi_msgString) if msg.getStatus() == 'End': end = True except (MessageError, PyTomClassError, ParameterError): #print mpi_msgString #raise MessageError('Message unknown!') raise RuntimeError( 'Error parsing message. Message either unknown or invalid.' ) except: raise RuntimeError( 'Something went terribly wrong. Aborting.') if doFinalize: pytom_mpi.finalise()
def multiRef_EXMXAlign(multiRefJob, doFinalize=True, verbose=False): """ multiRef_EXMXAlign: Performs multi reference alignment on a particle list @param multiRefJob: The multi reference alignment job @param doFinalize: Send finalize msgs to workers or not. Default is true @param verbose: Default is false """ import pytom_mpi if doFinalize: pytom_mpi.init() if pytom_mpi.rank() == 0: from pytom.alignment.ExMaxAlignment import ExMaxManager from pytom.tools.files import checkDirExists from os import mkdir from pytom.basic.resolution import bandToAngstrom, angstromToBand, angleFromResolution particleList = multiRefJob.getParticleList() initialParticleList = particleList previousParticleList = initialParticleList destinationDirectory = multiRefJob.getDestinationDirectory() numberIterations = multiRefJob.getNumberIterations() numberClasses = multiRefJob.getNumberClasses() exMaxJob = multiRefJob.getExMaxJob() p = particleList[0] pVol = p.getVolume() cubeSize = pVol.sizeX() preprocessing = exMaxJob.getPreprocessing() sampleInfo = exMaxJob.getSampleInformation() if verbose: print(multiRefJob) if not checkDirExists(destinationDirectory): raise IOError('Destination directory ' + destinationDirectory + ' not found!') try: particleLists = particleList.splitByClass() if len(particleLists) <= 1: raise Exception() except Exception: from pytom.cluster.clusterFunctions import randomiseParticleListClasses if numberClasses: if verbose: print('Randomizing particle list') particleList = randomiseParticleListClasses( particleList, numberClasses) particleList.toXMLFile(destinationDirectory + '/RandomisedParticleList.xml') particleLists = particleList.splitByClass() else: raise RuntimeError( 'The particle list provided is not pre-classified and you did not set numberClasses for a random seed!' ) iteration = 0 converged = False while iteration < numberIterations and (not converged): if verbose: print('Running iteration ' + str(iteration) + ' of ' + str(numberIterations)) iterationDirectory = destinationDirectory + '/' + str( iteration) + '/' if not checkDirExists(iterationDirectory): mkdir(iterationDirectory) #determine resolution of all classes maxRes = 0 minRes = 1000000 if not checkDirExists(iterationDirectory + 'resolution/'): mkdir(iterationDirectory + 'resolution/') for classIterator in range(len(particleLists)): currentParticleList = particleLists[classIterator] if len(currentParticleList) > 1: [resNyquist, resolutionBand, numberBands] = currentParticleList.determineResolution( criterion=exMaxJob.getFSCCriterion(), numberBands=cubeSize / 2, mask=exMaxJob.getMask(), keepHalfsetAverages=False, halfsetPrefix=iterationDirectory + 'resolution/' + 'class' + str(classIterator) + '_fsc-', verbose=verbose) else: continue resolutionAngstrom = bandToAngstrom(resolutionBand, sampleInfo.getPixelSize(), numberBands, 1) #resolutionAngstrom = bandToAngstrom(resolutionBand,sampleInfo.getPixelSize(),numberBands,exMaxJob.getBinning() ) if resolutionBand > maxRes: maxRes = resolutionBand if resolutionBand < minRes: minRes = resolutionBand if verbose: print( 'Class ', classIterator, ' - current resolution :' + str(resolutionAngstrom) + ' Angstrom') #set highest frequency according to user specification band = maxRes if not multiRefJob.getUseMaxResolution(): band = minRes if band == numberBands: #determineResolution returns numberBands for filter if fsc result is invalid. in that case, use nyquist /2 as filter setting print('Warning MultiRefAlignment.py: LL 114') print( 'Warning: Resolution determined for all classes was invalid. Will use Nyquist/2 for current iteration' ) band = numberBands / 2 preprocessing.setHighestFrequency(band) exMaxJob.setPreprocessing(preprocessing) alignmentLists = [None] * len(particleLists) #generate cluster centers referenceList = distributeExpectation( particleLists, iterationDirectory, 'clusterCenter' + str(iteration), verbose, exMaxJob.getSymmetry()) for classIterator in range(len(particleLists)): classDirectory = iterationDirectory + 'class' + str( classIterator) + '/' #determine distance for all particles refinementDirectory = classDirectory + 'refinement/' if verbose: print(refinementDirectory) if not checkDirExists(refinementDirectory): mkdir(refinementDirectory) exMaxJob.setParticleList(particleList) exMaxJob.setReference(referenceList[classIterator]) exMaxJob.setDestination(refinementDirectory) #run refinement manager = ExMaxManager(exMaxJob) manager.distributeAlignment(verbose) alignmentLists[classIterator] = manager.getAlignmentList() alignmentLists[classIterator].toXMLFile(iterationDirectory + 'AlignmentList' + str(classIterator) + '.xml') #perform classification here if verbose: print('Classifying after iteration ' + str(iteration)) particleList = classifyParticleList(initialParticleList, alignmentLists, verbose) particleList.toXMLFile(iterationDirectory + 'classifiedParticles.xml') particleLists = particleList.splitByClass() difference = previousParticleList.classDifference(particleList) converged = multiRefJob.getEndThreshold() >= difference[3] #set up for next round! previousParticleList = particleList iteration = iteration + 1 if doFinalize: manager.parallelEnd() pytom_mpi.finalise() return [particleList, alignmentLists] else: from pytom.alignment.ExMaxAlignment import ExMaxWorker worker = ExMaxWorker() worker.parallelRun() pytom_mpi.finalise()
def run(self, verbose=False): from pytom_volume import read, sum from pytom.basic.filter import lowpassFilter from pytom.basic.correlation import nxcc from pytom.basic.structures import Rotation from pytom.tools.ProgressBar import FixedProgBar from pytom.tompy.transform import fourier_reduced2full from pytom.tompy.io import read from pytom.tompy.tools import create_sphere from pytom.gpu.gpuStructures import CCCPlan while True: # get the job job = self.get_job() try: pl_filename = job["ParticleList"] maskname = job["Mask"] slists = job["Pairs"] nlists = job["NeededParticles"] freq = job["Frequency"] max_num_load = job["MaxNumPartPerGPU"] device = f'gpu:{job["GpuID"]}' binning = job['Binning'] except: if verbose: print(self.node_name + ': end') break # get some non-job message, break it from pytom.basic.structures import ParticleList pl = ParticleList('.') pl.fromXMLFile(pl_filename) plan = CCCPlan(pl, maskname, freq, cp=xp, device=device, max_num_part=max_num_load, profile=verbose, binning=binning) import time num_jobs = len(nlists) for nn, (subparts, needed) in enumerate(zip(slists, nlists)): tt = time.time() m = 0 for n, curr in enumerate(plan.currently_loaded): if curr in sorted(needed): plan.currently_loaded[m] = plan.currently_loaded[n] plan.formatting[m] = plan.formatting[n] m += 1 plan.currently_loaded[m:] = -1 for id in needed: if id in plan.currently_loaded: continue plan.currently_loaded[m] = int(id) plan.store_particle(m, pl[int(id)].getFilename()) m += 1 elapsed = (time.time() - tt) * 1000 print( f'finished reading for job {nn+1}/{num_jobs} on {device} in \t\t{elapsed/1000:10.3f} sec ({elapsed/max(1,len(subparts)):7.3f})' ) tt = time.time() plan.ccc_go(subparts) elapsed2 = (time.time() - tt) * 1000 elapsed += elapsed2 # print(f'finished {len(subparts)} comparisons for job {nn+1}/{num_jobs} on {device} in {elapsed2/1000:10.3f} sec ({elapsed2/max(1,len(subparts)):7.3f})') print( f'finished {len(subparts)} comparisons for job {nn+1}/{num_jobs} on {device} in {elapsed/1000:10.3f} sec ({elapsed/max(1,len(subparts)):7.3f})' ) # send back the result self.send_result(plan.results.get().tolist()) del plan pytom_mpi.finalise()
def mcoAC(annealingJob, doFinalize=True, verbose=False): """ mcoAC: Performs mcoAC clustering on particleList @param annealingJob: @param doFinalize: Send finalize messages to workers or not. Default is true. Should be false when this process is integrated into another parallel process. @param verbose: Default is false """ import pytom_mpi if doFinalize: pytom_mpi.init() if pytom_mpi.rank() == 0: from pytom.cluster.mcoEXMX import mcoEXMX from pytom.tools.files import checkDirExists from os import mkdir, system particleList = annealingJob.getParticleList() if len(particleList) == 0: raise RuntimeError('Particle list is empty! Abort!') initialParticleList = particleList previousParticleList = initialParticleList destinationDirectory = annealingJob.getDestinationDirectory() numberIterations = annealingJob.getNumberIterations() numberClasses = annealingJob.getNumberClasses() if verbose: print(annealingJob) if not checkDirExists(destinationDirectory): raise IOError('Destination directory ' + destinationDirectory + ' not found!') try: particleLists = particleList.splitByClass() if len(particleLists) <= 1 or (len(particleLists) == 1 and len( particleLists[0]) == len(particleList)): raise Exception() except Exception: from pytom.cluster.clusterFunctions import randomiseParticleListClasses if numberClasses: if verbose: print('Randomizing particle list') particleList = randomiseParticleListClasses( particleList, numberClasses) particleList.toXMLFile(destinationDirectory + '/RandomisedParticleList.xml') particleLists = particleList.splitByClass() else: raise RuntimeError( 'The particle list provided is not pre-classified and you did not set numberClasses for a random seed!' ) iteration = 0 converged = False bestScoreSum = None bestParticleList = None while (not annealingJob.cooledDown()) and (not converged): if verbose: print('Running iteration ' + str(iteration) + ' of ' + str(numberIterations)) iterationDirectory = destinationDirectory + '/' + str( iteration) + '/' mcoEXMXDirectory = iterationDirectory + 'mcoEXMX/' if not checkDirExists(iterationDirectory): mkdir(iterationDirectory) annealingJob.setDestinationDirectory(mcoEXMXDirectory) annealingJob.setParticleList(previousParticleList) annealingJob.setNumberIterations(annealingJob.getLocalIncrement()) annealingJob.toXMLFile(iterationDirectory + 'annealingJob.xml') #run local refinement [pl, alignmentLists] = mcoEXMX(annealingJob, doFinalize=False, verbose=verbose) annealingJob.setNumberIterations(numberIterations) #store currently best solution if iteration == 0 or (bestScoreSum < pl.sumOfScores() and len(pl.splitByClass()) > 1): bestScoreSum = pl.sumOfScores() bestParticleList = pl bestParticleList.toXMLFile(iterationDirectory + 'currentBestParticleList.xml') #perform classification here [particleList, swapList ] = classifyParticleList(initialParticleList, alignmentLists, annealingJob.getCriterion(), annealingJob.getTemperature().copy(), verbose) #save iteration results to disk particleList.toXMLFile(iterationDirectory + 'classifiedParticles.xml') swapList.toXMLFile(iterationDirectory + 'swapList.xml') #if not verbose mode, delete mcoEXMX files if not verbose: system('rm -rf ' + mcoEXMXDirectory) #print number class swaps difference = previousParticleList.classDifference(particleList) converged = annealingJob.getEndThreshold() >= difference[3] previousParticleList = particleList #set up for new round annealingJob.decreaseTemperature() particleLists = particleList.splitByClass() iteration = iteration + 1 print('Annealing iteration ' + str(iteration) + ' finished!') if doFinalize: from pytom.alignment.ExMaxAlignment import ExMaxManager manager = ExMaxManager(annealingJob.getExMaxJob()) manager.parallelEnd() pytom_mpi.finalise() return bestParticleList else: from pytom.cluster.mcoEXMXStructures import MCOEXMXWorker worker = MCOEXMXWorker() worker.setDoAlignment(annealingJob.getDoAlignment()) worker.setFRMBandwidth(annealingJob.getFRMBandwidth()) worker.parallelRun(verbose=verbose) pytom_mpi.finalise()
def run(self, verbose=False): from pytom_volume import read, sum from pytom.basic.filter import lowpassFilter from pytom.basic.correlation import nxcc from pytom.basic.structures import Rotation from pytom.tools.ProgressBar import FixedProgBar while True: # get the job job = self.get_job() try: pairs = job["Pairs"] pl_filename = job["ParticleList"] except: if verbose: print(self.node_name + ': end') break # get some non-job message, break it from pytom.basic.structures import ParticleList pl = ParticleList('.') pl.fromXMLFile(pl_filename) if verbose: prog = FixedProgBar(0, len(pairs)-1, self.node_name+':') i = 0 # run the job result = {} last_filename = None binning = int(job["Binning"]) mask = read(job["Mask"], 0, 0, 0, 0, 0, 0, 0, 0, 0, binning, binning, binning) for pair in pairs: if verbose: prog.update(i) i += 1 g = pl[pair[0]] f = pl[pair[1]] vf = f.getTransformedVolume(binning) wf = f.getWedge().getWedgeObject() wf_rotation = f.getRotation().invert() # wf.setRotation(Rotation(-rotation[1],-rotation[0],-rotation[2])) # wf_vol = wf.returnWedgeVolume(vf.sizeX(), vf.sizeY(), vf.sizeZ(), True, -rotation[1],-rotation[0],-rotation[2]) vf = lowpassFilter(vf, job["Frequency"], 0)[0] if g.getFilename() != last_filename: vg = g.getTransformedVolume(binning) wg = g.getWedge().getWedgeObject() wg_rotation = g.getRotation().invert() # wg.setRotation(Rotation(-rotation[1],-rotation[0],-rotation[2])) # wg_vol = wg.returnWedgeVolume(vg.sizeX(), vg.sizeY(), vg.sizeZ(), True, -rotation[1],-rotation[0],-rotation[2]) vg = lowpassFilter(vg, job["Frequency"], 0)[0] last_filename = g.getFilename() score = nxcc( wg.apply(vf, wg_rotation), wf.apply(vg, wf_rotation), mask) # overlapped_wedge_vol = wf_vol * wg_vol # scaling = float(overlapped_wedge_vol.numelem())/sum(overlapped_wedge_vol) # score *= scaling result[pair] = score # send back the result self.send_result(result) pytom_mpi.finalise()
def mcoEXMX(mcoEMJob, doFinalize=True, verbose=False): """ mcoEXMX: Perfomrs kmeans clustering on particleList @param mcoEMJob: The clustering job @param doFinalize: Send finalize msgs to workers or not. Default is true @param verbose: Default is false """ import pytom_mpi if doFinalize: pytom_mpi.init() if pytom_mpi.rank() == 0: from pytom.alignment.ExMaxAlignment import ExMaxManager from pytom.tools.files import checkDirExists from os import mkdir from pytom.basic.plot import plotClassSizes from builtins import min as minList particleList = mcoEMJob.getParticleList() if len(particleList) == 0: raise RuntimeError('Particle list is empty! Abort!') destinationDirectory = mcoEMJob.getDestinationDirectory() numberIterations = mcoEMJob.getNumberIterations() numberClasses = mcoEMJob.getNumberClasses() exMaxJob = mcoEMJob.getExMaxJob() if verbose: print(mcoEMJob) if not checkDirExists(destinationDirectory): raise IOError('Destination directory ' + destinationDirectory + ' not found!') try: particleLists = particleList.splitByClass() if len(particleLists) < 1 or (len(particleLists) == 1 and len( particleLists[0]) == len(particleList)): raise Exception() except Exception: from pytom.cluster.clusterFunctions import randomiseParticleListClasses if numberClasses: if verbose: print('Randomising particle list') particleList = randomiseParticleListClasses( particleList, numberClasses) particleList.toXMLFile(destinationDirectory + '/RandomisedParticleList.xml') particleLists = particleList.splitByClass() else: raise RuntimeError( 'The particle list provided is not pre-classified and you did not set numberClasses for a random seed!' ) initialParticleList = particleList previousParticleList = initialParticleList iteration = 0 converged = False doAdaptiveResolution = mcoEMJob.getAdaptiveResolution() if doAdaptiveResolution: preProcessing = exMaxJob.getPreprocessing() highestFrequency = preProcessing.getHighestFrequency() resolutionList = [highestFrequency] * len(particleLists) while iteration < numberIterations and (not converged): if verbose: print('Running iteration ' + str(iteration) + ' of ' + str(numberIterations)) iterationDirectory = destinationDirectory + '/' + str( iteration) + '/' if not checkDirExists(iterationDirectory): mkdir(iterationDirectory) #referenceList = ReferenceList() alignmentLists = [None] * len(particleLists) #generate cluster centers referenceList = distributeExpectation( particleLists, iterationDirectory, 'clusterCenter' + str(iteration), verbose, exMaxJob.getSymmetry()) for classIterator in range(len(particleLists)): classDirectory = iterationDirectory + 'class' + str( classIterator) + '/' #determine distance for all particles refinementDirectory = classDirectory + 'refinement/' if verbose: print(refinementDirectory) if not checkDirExists(refinementDirectory): mkdir(refinementDirectory) exMaxJob.setParticleList(particleList) exMaxJob.setReference(referenceList[classIterator]) exMaxJob.setDestination(refinementDirectory) #use adaptive resolution -> update lowpass filter if doAdaptiveResolution and len( resolutionList ) > 0 and resolutionList[classIterator] > 0: # preProcessing = exMaxJob.getPreprocessing() # resolution = resolutionList[classIterator] # preProcessing.setHighestFrequency(resolution) # exMaxJob.setPreprocessing(preProcessing) preProcessing = exMaxJob.getPreprocessing() resolution = minList(resolutionList) * 1.1 preProcessing.setHighestFrequency(resolution) exMaxJob.setPreprocessing(preProcessing) #run refinement manager = ExMaxManager(exMaxJob) exMaxJob.toXMLFile(classDirectory + 'Job.xml') manager.distributeAlignment(verbose) alignmentLists[classIterator] = manager.getAlignmentList() alignmentLists[classIterator].toXMLFile(iterationDirectory + 'AlignmentList' + str(classIterator) + '.xml') #perform classification here if verbose: print('Classifying after iteration ' + str(iteration)) particleList = classifyParticleList(initialParticleList, alignmentLists, verbose) particleList.toXMLFile(iterationDirectory + 'classifiedParticles.xml') particleLists = particleList.splitByClass() difference = previousParticleList.classDifference(particleList) converged = mcoEMJob.getEndThreshold() >= difference[3] #determine resolution in each class if doAdaptiveResolution: resolutionList = [-1] * len(particleLists) for classIterator in range(len(particleLists)): classList = particleLists[classIterator] if len(classList) == 1: #if there is only one particle in that class, override resolution print( 'Class ', classIterator, ' has only 1 particle! Will be assigned the lowest resolution determined.' ) continue className = classList[0].getClass() v = classList[0].getVolume() cubeSize = v.sizeX() resolution = classList.determineResolution( criterion=0.5, numberBands=cubeSize / 2, mask=exMaxJob.getMask(), verbose=False, plot='', keepHalfsetAverages=False, halfsetPrefix='class' + str(className), parallel=True) #resolution = [Resolution in Nyquist , resolution in band, numberBands] resolutionList[classIterator] = resolution[1] print('Resolution for class ', classIterator, ' determined to ', resolution[1], ' pixels. Class size is ', len(classList), ' particles') #get lowest resolution determined for classes with more than 1 particle min = 999999999999999 for classIterator in range(len(particleLists)): if min >= resolutionList[classIterator] and resolutionList[ classIterator] >= 0: min = resolutionList[classIterator] #set resolution for all classes with only 1 particle to lowest resolution for classIterator in range(len(particleLists)): if resolutionList[classIterator] < 0: resolutionList[classIterator] = min #set up for next round! previousParticleList = particleList iteration = iteration + 1 if doFinalize: manager.parallelEnd() pytom_mpi.finalise() return [particleList, alignmentLists] else: from pytom.cluster.mcoEXMXStructures import MCOEXMXWorker worker = MCOEXMXWorker() worker.setDoAlignment(mcoEMJob.getDoAlignment()) worker.setFRMBandwidth(mcoEMJob.getFRMBandwidth()) worker.parallelRun() pytom_mpi.finalise()
ScriptOption(['-h', '--help'], 'Help.', False, False) ]) verbose = False if len(sys.argv) == 1: print helper sys.exit() try: jobFile, verbose, helpme = parse_script_options(sys.argv[1:], helper) except Exception: #print e sys.exit() if helpme is True: print helper sys.exit() job = MCOACJob(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) job.fromXMLFile(jobFile) verbose = verbose is True try: mcoAC(job, True, verbose) except: if pytom_mpi.rank() == 0: from pytom.alignment.ExMaxAlignment import ExMaxManager manager = ExMaxManager(annealingJob.getExMaxJob()) manager.parallelEnd() pytom_mpi.finalise()