class RowMetaData(): """ This class is a wrapper for MetaData in row mode. Where only one object is used. """ def __init__(self, filename=None): self._md = MetaData() self._md.setColumnFormat(False) self._id = self._md.addObject() if filename: self.read(filename) def setValue(self, label, value): self._md.setValue(label, value, self._id) def getValue(self, label): return self._md.getValue(label, self._id) def write(self, filename, mode=MD_APPEND): self._md.write(filename, mode) def read(self, filename): self._md.read(filename) self._md.setColumnFormat(False) self._id = self._md.firstObject() def containsLabel(self, label): return self._md.containsLabel(label) def __str__(self): return str(self._md)
def projMatchStep(self, volume, angularSampling, symmetryGroup, images, fnAngles, Xdim): from pyworkflow.utils.path import cleanPath # Generate gallery of projections fnGallery = self._getExtraPath('gallery.stk') if volume.endswith('.mrc'): volume += ":mrc" self.runJob("xmipp_angular_project_library", "-i %s -o %s --sampling_rate %f --sym %s --method fourier 1 0.25 bspline --compute_neighbors --angular_distance -1 --experimental_images %s"\ % (volume, fnGallery, angularSampling, symmetryGroup, images)) # Assign angles self.runJob("xmipp_angular_projection_matching", "-i %s -o %s --ref %s --Ri 0 --Ro %s --max_shift 1000 --search5d_shift %s --search5d_step %s --append"\ % (images, fnAngles, fnGallery, str(Xdim/2), str(int(Xdim/10)), str(int(Xdim/25)))) cleanPath(self._getExtraPath('gallery_sampling.xmd')) cleanPath(self._getExtraPath('gallery_angles.doc')) cleanPath(self._getExtraPath('gallery.doc')) # Write angles in the original file and sort MD = MetaData(fnAngles) for id in MD: galleryReference = MD.getValue(xmippLib.MDL_REF, id) MD.setValue(xmippLib.MDL_IMAGE_REF, "%05d@%s" % (galleryReference + 1, fnGallery), id) MD.write(fnAngles)
def evaluateDeformationsStep(self): N = self.inputStructures.get().getSize() import numpy distances = numpy.zeros([N, N]) for volCounter in range(1, N + 1): pdb1 = open( self._getPath('pseudoatoms_%02d.pdb' % volCounter)).readlines() for volCounter2 in range(1, N + 1): if volCounter != volCounter2: davg = 0. Navg = 0. pdb2 = open(self._getExtraPath('alignment_%02d_%02d.pdb' % ( volCounter, volCounter2))).readlines() for i in range(len(pdb1)): line1 = pdb1[i] if line1.startswith("ATOM"): line2 = pdb2[i] x1 = float(line1[30:37]) y1 = float(line1[38:45]) z1 = float(line1[46:53]) x2 = float(line2[30:37]) y2 = float(line2[38:45]) z2 = float(line2[46:53]) dx = x1 - x2 dy = y1 - y2 dz = z1 - z2 d = math.sqrt(dx * dx + dy * dy + dz * dz) davg += d Navg += 1 if Navg > 0: davg /= Navg distances[volCounter - 1, volCounter2 - 1] = davg distances = 0.5 * (distances + numpy.transpose(distances)) numpy.savetxt(self._getPath('distances.txt'), distances) distances1D = numpy.mean(distances, axis=0) print("Average distance to rest of volumes=", distances1D) imin = numpy.argmin(distances1D) print("The volume in the middle is pseudoatoms_%02d.pdb" % (imin + 1)) createLink(self._getPath("pseudoatoms_%02d.pdb" % (imin + 1)), self._getPath("pseudoatoms.pdb")) createLink(self._getPath("modes_%02d.xmd" % (imin + 1)), self._getPath("modes.xmd")) createLink( self._getExtraPath("pseudoatoms_%02d_distance.hist" % (imin + 1)), self._getExtraPath("pseudoatoms_distance.hist")) # Measure range minDisplacement = 1e38 * numpy.ones([self.numberOfModes.get(), 1]) maxDisplacement = -1e38 * numpy.ones([self.numberOfModes.get(), 1]) mdNMA = MetaData(self._getPath("modes.xmd")) for volCounter in range(1, N + 1): if volCounter != imin + 1: md = MetaData(self._getExtraPath( "alignment_%02d_%02d.xmd" % (imin + 1, volCounter))) displacements = md.getValue(MDL_NMA, md.firstObject()) idx1 = 0 idx2 = 0 for idRow in mdNMA: if mdNMA.getValue(MDL_ENABLED, idRow) == 1: minDisplacement[idx2] = min(minDisplacement[idx2], displacements[idx1]) maxDisplacement[idx2] = max(maxDisplacement[idx2], displacements[idx1]) idx1 += 1 else: minDisplacement[idx2] = 0 maxDisplacement[idx2] = 0 idx2 += 1 idx2 = 0 for idRow in mdNMA: mdNMA.setValue(MDL_NMA_MINRANGE, float(minDisplacement[idx2]), idRow) mdNMA.setValue(MDL_NMA_MAXRANGE, float(maxDisplacement[idx2]), idRow) idx2 += 1 mdNMA.write(self._getPath("modes.xmd")) # Create output volCounter = 0 for inputStructure in self.inputStructures.get(): if volCounter == imin: print("The corresponding volume is %s" % ( getImageLocation(inputStructure))) finalStructure = inputStructure break volCounter += 1 pdb = AtomStruct(self._getPath('pseudoatoms.pdb'), pseudoatoms=True) self._defineOutputs(outputPdb=pdb) modes = NormalModes(filename=self._getPath('modes.xmd')) self._defineOutputs(outputModes=modes) self._defineSourceRelation(self.inputStructures, self.outputPdb)
def produceAlignedImagesStep(self, volumeIsCTFCorrected, fn, images): from numpy import array, dot fnOut = 'classes_aligned@' + fn MDin = MetaData(images) MDout = MetaData() n = 1 hasCTF = MDin.containsLabel(xmippLib.MDL_CTF_MODEL) for i in MDin: fnImg = MDin.getValue(xmippLib.MDL_IMAGE, i) fnImgRef = MDin.getValue(xmippLib.MDL_IMAGE_REF, i) maxCC = MDin.getValue(xmippLib.MDL_MAXCC, i) rot = MDin.getValue(xmippLib.MDL_ANGLE_ROT, i) tilt = MDin.getValue(xmippLib.MDL_ANGLE_TILT, i) psi = -1. * MDin.getValue(xmippLib.MDL_ANGLE_PSI, i) flip = MDin.getValue(xmippLib.MDL_FLIP, i) if flip: psi = -psi eulerMatrix = Euler_angles2matrix(0., 0., psi) x = MDin.getValue(xmippLib.MDL_SHIFT_X, i) y = MDin.getValue(xmippLib.MDL_SHIFT_Y, i) shift = array([x, y, 0]) shiftOut = dot(eulerMatrix, shift) [x, y, z] = shiftOut if flip: x = -x id = MDout.addObject() MDout.setValue(xmippLib.MDL_IMAGE, fnImg, id) MDout.setValue(xmippLib.MDL_IMAGE_REF, fnImgRef, id) MDout.setValue(xmippLib.MDL_IMAGE1, "%05d@%s" % (n, self._getExtraPath("diff.stk")), id) if hasCTF: fnCTF = MDin.getValue(xmippLib.MDL_CTF_MODEL, i) MDout.setValue(xmippLib.MDL_CTF_MODEL, fnCTF, id) MDout.setValue(xmippLib.MDL_MAXCC, maxCC, id) MDout.setValue(xmippLib.MDL_ANGLE_ROT, rot, id) MDout.setValue(xmippLib.MDL_ANGLE_TILT, tilt, id) MDout.setValue(xmippLib.MDL_ANGLE_PSI, psi, id) MDout.setValue(xmippLib.MDL_SHIFT_X, x, id) MDout.setValue(xmippLib.MDL_SHIFT_Y, y, id) MDout.setValue(xmippLib.MDL_FLIP, flip, id) MDout.setValue(xmippLib.MDL_ENABLED, 1, id) n += 1 MDout.write(fnOut, xmippLib.MD_APPEND) # Actually create the differences img = Image() imgRef = Image() if hasCTF and volumeIsCTFCorrected: Ts = MDin.getValue(xmippLib.MDL_SAMPLINGRATE, MDin.firstObject()) for i in MDout: img.readApplyGeo(MDout, i) imgRef.read(MDout.getValue(xmippLib.MDL_IMAGE_REF, i)) if hasCTF and volumeIsCTFCorrected: fnCTF = MDout.getValue(xmippLib.MDL_CTF_MODEL, i) applyCTF(imgRef, fnCTF, Ts) img.convert2DataType(DT_DOUBLE) imgDiff = img - imgRef imgDiff.write(MDout.getValue(xmippLib.MDL_IMAGE1, i))