def createSetOfParticles(self, setPartSqliteName, partFn, doCtf=False): # create a set of particles self.partSet = SetOfParticles(filename=setPartSqliteName) self.partSet.setAlignment(ALIGN_PROJ) self.partSet.setAcquisition(Acquisition(voltage=300, sphericalAberration=2, amplitudeContrast=0.1, magnification=60000)) self.partSet.setSamplingRate(samplingRate) self.partSet.setHasCTF(True) aList = [np.array(m) for m in mList] #defocus=15000 + 5000* random.random() for i, a in enumerate(aList): p = Particle() if doCtf: defocusU = defocusList[i]#+500. defocusV = defocusList[i] ctf = CTFModel(defocusU=defocusU, defocusV=defocusV, defocusAngle=defocusAngle[i]) ctf.standardize() p.setCTF(ctf) p.setLocation(i + 1, partFn) p.setTransform(Transform(a)) self.partSet.append(p) self.partSet.write()
def createOutputStep(self): inputVol = self.inputStructure.get() samplingRate = inputVol.getSamplingRate() volume = Volume() volume.setFileName(self._getExtraPath("pseudoatoms_approximation.vol")) volume.setSamplingRate(samplingRate) x, y, z = volume.getDim() xv, yv, zv = inputVol.getOrigin(force=True).getShifts() t = Transform() t.setShifts((x / 2. * samplingRate) - xv, (y / 2. * samplingRate) - yv, (z / 2. * samplingRate) - zv) volume.setOrigin(inputVol.getOrigin()) self._defineOutputs(outputVolume=volume) self._defineSourceRelation(self.inputStructure.get(), volume) pdb = AtomStruct(self._getPath('pseudoatoms.pdb'), pseudoatoms=True) pdb.setVolume(volume) pdb.setOrigin(t) self.createChimeraScript(inputVol, pdb) self._defineOutputs(outputPdb=pdb) self._defineSourceRelation(self.inputStructure, pdb)
def _testInv(matrix): matrix = numpy.array(matrix) a = Transform(matrix) row1 = md.Row() relion.alignmentToRow(a, row1, alignType=ALIGN_2D) # row2 = md.Row() # relion.alignmentToRow(a, row2, alignType=ALIGN_3D) row2 = None row3 = md.Row() relion.alignmentToRow(a, row3, alignType=ALIGN_PROJ) return row1, row2, row3
def alignParticlesStep(self): fhInputTranMat = self._getExtraPath('transformation-matrix.txt') outParticlesFn = self._getExtraPath('outputParticles.xmd') transMatFromFile = np.loadtxt(fhInputTranMat) transformationMat = np.reshape(transMatFromFile, (4, 4)) transform = em.Transform() transform.setMatrix(transformationMat) resultMat = Transform() outputParts = md.MetaData() mdToAlign = md.MetaData(self.imgsInputFn) for row in md.iterRows(mdToAlign): inMat = rowToAlignment(row, ALIGN_PROJ) partTransformMat = inMat.getMatrix() partTransformMatrix = np.matrix(partTransformMat) newTransformMatrix = np.matmul(transformationMat, partTransformMatrix) resultMat.setMatrix(newTransformMatrix) rowOut = md.Row() rowOut.copyFromRow(row) alignmentToRow(resultMat, rowOut, ALIGN_PROJ) rowOut.addToMd(outputParts) outputParts.write(outParticlesFn)
def _particlesFromEmx(protocol, emxData, emxFile, outputDir, acquisition, samplingRate, copyOrLink, alignType=ALIGN_NONE): """ Create the output SetOfCoordinates or SetOfParticles given an EMXData object. Add CTF information to the particles if present. """ emxParticle = emxData.getFirstObject(emxlib.PARTICLE) partDir = dirname(emxFile) micSet = getattr(protocol, 'outputMicrographs', None) if emxParticle is not None: # Check if there are particles or coordinates fn = emxParticle.get(emxlib.FILENAME) if exists(join( partDir, fn)): # if the particles has binary data, means particles case partSet = protocol._createSetOfParticles() partSet.setAcquisition( acquisition) # this adquisition is per project #we need one per particle part = Particle() if _hasCtfLabels(emxParticle) or _hasCtfLabels( emxParticle.getMicrograph()): part.setCTF(CTFModel()) partSet.setHasCTF(True) if emxParticle.has('centerCoord__X'): part.setCoordinate(Coordinate()) #if emxParticle.has('transformationMatrix__t11'): # _particleFromEmx(emxParticle, part) # #partSet.setAlignment3D() # partSet.setAlignment(alignType) #else: # partSet.setAlignment(alignType) partSet.setAlignment(alignType) if not samplingRate: samplingRate = part.getSamplingRate() partSet.setSamplingRate(samplingRate) partSet.setIsPhaseFlipped(protocol.haveDataBeenPhaseFlipped.get()) particles = True else: # if not binary data, the coordinate case if micSet is None: raise Exception( 'Could not import Coordinates from EMX, micrographs not imported.' ) partSet = protocol._createSetOfCoordinates(micSet) part = Coordinate() particles = False copiedFiles = {} # copied or linked for emxParticle in emxData.iterClasses(emxlib.PARTICLE): if particles: _particleFromEmx(emxParticle, part) i, fn = part.getLocation() partFn = join(partDir, fn) newFn = join(outputDir, basename(partFn)) newLoc = (i, newFn) if not partFn in copiedFiles: copyOrLink(partFn, newFn) copiedFiles[partFn] = newFn part.setLocation(newLoc) if partSet.hasAlignment(): transform = Transform() _transformFromEmx(emxParticle, part, transform, alignType) part.setTransform(transform) else: _coordinateFromEmx(emxParticle, part) partSet.append(part) part.cleanObjId() if particles: protocol._defineOutputs(outputParticles=partSet) else: protocol._defineOutputs(outputCoordinates=partSet) if micSet is not None: protocol._defineSourceRelation(protocol.outputMicrographs, partSet)
def _updateItem(self, item, index): item.setLocation(index, self._getFileName('particlesAligned')) item.setTransform(Transform())
def importVolumesStep(self, pattern, samplingRate, setOrigCoord=False): """ Copy images matching the filename pattern Register other parameters. """ self.info("Using pattern: '%s'" % pattern) # Create a Volume template object vol = Volume() vol.setSamplingRate(samplingRate) imgh = ImageHandler() volSet = self._createSetOfVolumes() volSet.setSamplingRate(samplingRate) for fileName, fileId in self.iterFiles(): x, y, z, n = imgh.getDimensions(fileName) if fileName.endswith('.mrc') or fileName.endswith('.map'): fileName += ':mrc' if (z == 1 and n != 1): zDim = n n = 1 else: zDim = z else: zDim = z origin = Transform() if setOrigCoord: origin.setShiftsTuple(self._getOrigCoord()) else: origin.setShifts(x / -2. * samplingRate, y / -2. * samplingRate, zDim / -2. * samplingRate) vol.setOrigin(origin) # read origin from form if self.copyFiles or setOrigCoord: newFileName = abspath(self._getVolumeFileName(fileName, "mrc")) Ccp4Header.fixFile(fileName, newFileName, origin.getShifts(), samplingRate, Ccp4Header.ORIGIN) else: newFileName = abspath(self._getVolumeFileName(fileName)) if fileName.endswith(':mrc'): fileName = fileName[:-4] createAbsLink(fileName, newFileName) # Make newFileName relative # https://github.com/I2PC/scipion/issues/1935 newFileName = relpath(newFileName) if n == 1: vol.cleanObjId() vol.setFileName(newFileName) volSet.append(vol) else: for index in range(1, n + 1): vol.cleanObjId() vol.setLocation(index, newFileName) volSet.append(vol) if volSet.getSize() > 1: self._defineOutputs(outputVolumes=volSet) else: self._defineOutputs(outputVolume=vol)
def realignStep(self): inputMdName = self._getExtraPath('inputClasses.xmd') writeSetOfClasses2D(self.inputClasses.get(), inputMdName, writeParticles=True) centeredStackName = self._getExtraPath('centeredStack.stk') self._params = {'input': inputMdName, 'output': centeredStackName} args = ('-i %(input)s -o %(output)s --save_metadata_transform') self.runJob("xmipp_transform_center_image", args % self._params, numberOfMpi=1) centeredMdName = centeredStackName.replace('stk', 'xmd') centeredMd = md.MetaData(centeredMdName) centeredStack = md.MetaData(centeredStackName) listName = [] listTransform = [] for rowStk in md.iterRows(centeredStack): listName.append(rowStk.getValue(md.MDL_IMAGE)) for rowMd in md.iterRows(centeredMd): listTransform.append(rowToAlignment(rowMd, ALIGN_2D)) mdNewClasses = md.MetaData() for i, row in enumerate(md.iterRows(inputMdName)): newRow = md.Row() newRow.setValue(md.MDL_IMAGE, listName[i]) refNum = row.getValue(md.MDL_REF) newRow.setValue(md.MDL_REF, refNum) classCount = row.getValue(md.MDL_CLASS_COUNT) newRow.setValue(md.MDL_CLASS_COUNT, classCount) newRow.addToMd(mdNewClasses) mdNewClasses.write( 'classes@' + self._getExtraPath('final_classes.xmd'), MD_APPEND) mdImages = md.MetaData() i = 0 mdBlocks = md.getBlocksInMetaDataFile(inputMdName) resultMat = Transform() for block in mdBlocks: if block.startswith('class00'): newMat = listTransform[i] newMatrix = newMat.getMatrix() mdClass = md.MetaData(block + "@" + inputMdName) mdNewClass = md.MetaData() i += 1 for rowIn in md.iterRows(mdClass): #To create the transformation matrix (and its parameters) # for the realigned particles if rowIn.getValue(md.MDL_ANGLE_PSI) != 0: flag_psi = True if rowIn.getValue(md.MDL_ANGLE_ROT) != 0: flag_psi = False inMat = rowToAlignment(rowIn, ALIGN_2D) inMatrix = inMat.getMatrix() resultMatrix = np.dot(newMatrix, inMatrix) resultMat.setMatrix(resultMatrix) rowOut = md.Row() rowOut.copyFromRow(rowIn) alignmentToRow(resultMat, rowOut, ALIGN_2D) if flag_psi == False: newAngle = rowOut.getValue(md.MDL_ANGLE_PSI) rowOut.setValue(md.MDL_ANGLE_PSI, 0.) rowOut.setValue(md.MDL_ANGLE_ROT, newAngle) #To create the new coordinates for the realigned particles inPoint = np.array([[0.], [0.], [0.], [1.]]) invResultMat = np.linalg.inv(resultMatrix) centerPoint = np.dot(invResultMat, inPoint) rowOut.setValue( md.MDL_XCOOR, rowOut.getValue(md.MDL_XCOOR) + int(centerPoint[0])) rowOut.setValue( md.MDL_YCOOR, rowOut.getValue(md.MDL_YCOOR) + int(centerPoint[1])) rowOut.addToMd(mdNewClass) mdNewClass.write( block + "@" + self._getExtraPath('final_classes.xmd'), MD_APPEND) mdImages.unionAll(mdNewClass) mdImages.write(self._getExtraPath('final_images.xmd'))
def test_forward_backwards(self): """convert transformation matrixt to xmipp and back""" mList = [ [ [0.71461016, 0.63371837, -0.29619813, 1.], #a1 [-0.61309201, 0.77128059, 0.17101008, 2.], [0.33682409, 0.059391174, 0.93969262, 3.], [0, 0, 0, 1.] ], [ [0., 0., -1., 0.], #a2 [0., 1., 0., 0.], [1., 0., 0., 0.], [0., 0., 0., 1.] ], [ [0., 1., 0., 0.], #a3 [0., 0., 1., 0.], [1., 0., 0., 0.], [0., 0., 0., 1.] ], [ [0.22612257, 0.82379508, -0.51983678, 0.], #a4 [-0.88564873, 0.39606407, 0.24240388, 0.], [0.40557978, 0.40557978, 0.81915206, 0.], [0., 0., 0., 1.] ], [ [-0.78850311, -0.24329656, -0.56486255, 0.], #a5 [0.22753462, -0.96866286, 0.099600501, 0.], [-0.57139379, -0.049990479, 0.81915206, 0.], [0., 0., 0., 1.] ], [ [1.0, 0.0, 0.0, 0.0], #a6 [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0] ], [ [0., 0., -1., 0.], #a7 [-1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 0., 1.] ] ] aList = [numpy.array(m) for m in mList] rowa = md.Row() rowb = md.Row() rowb1 = md.Row() rowb2 = md.Row() rowb3 = md.Row() labelList = [ md.RLN_ORIENT_ROT, md.RLN_ORIENT_TILT, md.RLN_ORIENT_PSI, md.RLN_ORIENT_ORIGIN_X, md.RLN_ORIENT_ORIGIN_Y, md.RLN_ORIENT_ORIGIN_Z ] for i, a in enumerate(aList): a = Transform(aList[i]) relion.alignmentToRow(a, rowa, ALIGN_PROJ) b = relion.rowToAlignment(rowa, ALIGN_PROJ) relion.alignmentToRow(b, rowb, ALIGN_PROJ) #same two matrices self.assertTrue( numpy.allclose(a.getMatrix(), b.getMatrix(), rtol=1e-2)) for label in labelList: auxBtilt = rowb.getValue(label) auxAtilt = rowa.getValue(label) #same two rows self.assertAlmostEqual(auxBtilt, auxAtilt, places=3, msg=None, delta=None) b = relion.rowToAlignment(rowa, ALIGN_PROJ) relion.alignmentToRow(b, rowb, ALIGN_PROJ) aMatrix = a.getMatrix() # aMatrix[0,:] *= -1; aMatrix[2,:] *= -1; #same two matrices with flip print "aMatrix: \n", aMatrix, "bMatrix: \n", b.getMatrix() self.assertTrue(numpy.allclose(aMatrix, b.getMatrix(), rtol=1e-2))
def launchTest(self, fileKey, mList, alignType=None, **kwargs): """ Helper function to launch similar alignment tests give the EMX transformation matrix. Params: fileKey: the file where to grab the input stack images. mList: the matrix list of transformations (should be the same length of the stack of images) """ print "\n" print "*" * 80 print "* Launching test: ", fileKey print "*" * 80 is2D = alignType == ALIGN_2D stackFn = self.dataset.getFile(fileKey) partFn1 = self.getOutputPath(fileKey + "_particles1.sqlite") mdFn = self.getOutputPath(fileKey + "_particles.star") partFn2 = self.getOutputPath(fileKey + "_particles2.sqlite") if self.IS_ALIGNMENT: outputFn = self.getOutputPath(fileKey + "_output.mrcs") outputFnRelion = self.getOutputPath(fileKey + "_output") goldFn = self.dataset.getFile(fileKey + '_Gold_output_relion.mrcs') else: outputFn = self.getOutputPath(fileKey + "_output.vol") goldFn = self.dataset.getFile(fileKey + '_Gold_output.vol') if PRINT_FILES: print "BINARY DATA: ", stackFn print "SET1: ", partFn1 print " MD: ", mdFn print "SET2: ", partFn2 print "OUTPUT: ", outputFn print "GOLD: ", goldFn if alignType == ALIGN_2D or alignType == ALIGN_PROJ: partSet = SetOfParticles(filename=partFn1) else: partSet = SetOfVolumes(filename=partFn1) partSet.setAlignment(alignType) partSet.setAcquisition( Acquisition(voltage=300, sphericalAberration=2, amplitudeContrast=0.1, magnification=60000)) # Populate the SetOfParticles with images # taken from images.mrc file # and setting the previous alignment parameters aList = [numpy.array(m) for m in mList] for i, a in enumerate(aList): p = Particle() p.setLocation(i + 1, stackFn) p.setTransform(Transform(a)) partSet.append(p) # Write out the .sqlite file and check that are correctly aligned print "Parset", partFn1 partSet.printAll() partSet.write() # Convert to a Xmipp metadata and also check that the images are # aligned correctly if alignType == ALIGN_2D or alignType == ALIGN_PROJ: relion.writeSetOfParticles(partSet, mdFn, "/tmp", alignType=alignType) partSet2 = SetOfParticles(filename=partFn2) else: relion.writeSetOfVolumes(partSet, mdFn, alignType=alignType) partSet2 = SetOfVolumes(filename=partFn2) # Let's create now another SetOfImages reading back the written # Xmipp metadata and check one more time. partSet2.copyInfo(partSet) if alignType == ALIGN_2D or alignType == ALIGN_PROJ: relion.readSetOfParticles(mdFn, partSet2, alignType=alignType) else: relion.readSetOfVolumes(mdFn, partSet2, alignType=alignType) partSet2.write() if PRINT_MATRIX: for i, img in enumerate(partSet2): m1 = aList[i] m2 = img.getTransform().getMatrix() print "-" * 5 print img.getFileName(), img.getIndex() print 'm1:\n', m1, relion.geometryFromMatrix(m1, False) print 'm2:\n', m2, relion.geometryFromMatrix(m2, False) # self.assertTrue(numpy.allclose(m1, m2, rtol=1e-2)) # Launch apply transformation and check result images runRelionProgram(self.CMD % locals()) if SHOW_IMAGES: runRelionProgram('scipion show %(outputFn)s' % locals()) if os.path.exists(goldFn): self.assertTrue( ImageHandler().compareData(goldFn, outputFn, tolerance=0.001), "Different data files:\n>%s\n<%s" % (goldFn, outputFn))
def test_forward_backwards(self): """convert transformation matrixt to xmipp and back""" mList = [[[0.71461016, 0.63371837, -0.29619813, 1.],#a1 [-0.61309201, 0.77128059, 0.17101008, 2.], [0.33682409, 0.059391174, 0.93969262, 3.], [0, 0, 0, 1.]], [[0., 0., -1., 0.],#a2 [0., 1., 0., 0.], [1., 0., 0., 0.], [0., 0., 0., 1.]], [[0., 1., 0., 0.],#a3 [0., 0., 1., 0.], [1., 0., 0., 0.], [0., 0., 0., 1.]], [[ 0.22612257, 0.82379508, -0.51983678, 0.],#a4 [-0.88564873, 0.39606407, 0.24240388, 0.], [ 0.40557978, 0.40557978, 0.81915206, 0.], [ 0., 0., 0., 1.]], [[-0.78850311, -0.24329656,-0.56486255, 0.],#a5 [ 0.22753462, -0.96866286, 0.099600501, 0.], [-0.57139379, -0.049990479, 0.81915206, 0.], [0., 0., 0., 1.]], [[ 1.0, 0.0, 0.0, 0.0],#a6 [ 0.0, 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0, 0.0], [ 0.0, 0.0, 0.0, 1.0]], [[0., 0., -1., 0.],#a7 [-1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 0., 1.]] ] aList = [numpy.array(m) for m in mList] rowa = md.Row() rowb = md.Row() rowb1 = md.Row() rowb2 = md.Row() rowb3 = md.Row() labelList=[md.RLN_ORIENT_ROT ,md.RLN_ORIENT_TILT ,md.RLN_ORIENT_PSI ,md.RLN_ORIENT_ORIGIN_X ,md.RLN_ORIENT_ORIGIN_Y ,md.RLN_ORIENT_ORIGIN_Z ] for i, a in enumerate(aList): a = Transform(aList[i]) relion.alignmentToRow(a, rowa, ALIGN_PROJ) b = relion.rowToAlignment(rowa, ALIGN_PROJ) relion.alignmentToRow(b, rowb, ALIGN_PROJ) #same two matrices self.assertTrue(numpy.allclose(a.getMatrix(), b.getMatrix(), rtol=1e-2)) for label in labelList: auxBtilt = rowb.getValue(label) auxAtilt = rowa.getValue(label) #same two rows self.assertAlmostEqual(auxBtilt, auxAtilt, places=3, msg=None, delta=None) b = relion.rowToAlignment(rowa, ALIGN_PROJ) relion.alignmentToRow(b, rowb, ALIGN_PROJ) aMatrix = a.getMatrix() # aMatrix[0,:] *= -1; aMatrix[2,:] *= -1; #same two matrices with flip print ("aMatrix: \n", aMatrix, "bMatrix: \n", b.getMatrix()) self.assertTrue(numpy.allclose(aMatrix, b.getMatrix(), rtol=1e-2))
def extractunitCell(self, sym, offset=0, cropZ=False): """ extract unit cell from icosahedral phantom using xmipp_i2 symmetry """ # create phantom (3D map) _samplingRate = 1.34 _, outputFile1 = mkstemp(suffix=".mrc") command = "xmipp_phantom_create " args = " -i %s" % self.filename[sym] args += " -o %s" % outputFile1 runJob(None, command, args, env=Plugin.getEnviron()) ccp4header = Ccp4Header(outputFile1, readHeader=True) x, y, z = ccp4header.getDims() t = Transform() if cropZ: _, outputFile2 = mkstemp(suffix=".mrc") args = "-i %s -o %s" % (outputFile1, outputFile2) args += " --corners " args += " %d " % (-x / 2.) args += " %d " % (-y / 2.) args += " %d " % (0.) args += " %d " % (+x / 2.) args += " %d " % (+y / 2.) args += " %d " % (+z / 2.) runJob(None, "xmipp_transform_window", args, env=Plugin.getEnviron()) t.setShifts(0, 0, 0) outputFile = outputFile2 ccp4header = Ccp4Header(outputFile2, readHeader=True) else: t.setShifts(0, 0, 0) outputFile = outputFile1 ccp4header.setSampling(_samplingRate) ccp4header.setOrigin(t.getShifts()) ccp4header.writeHeader() # import volume if cropZ: args = { 'filesPath': outputFile, 'filesPattern': '', 'samplingRate': _samplingRate, 'copyFiles': True, 'setOrigCoord': True, 'x': 90. * _samplingRate, 'y': 90. * _samplingRate, 'z': 0. # x, y, z in Angstroms } else: args = { 'filesPath': outputFile, 'filesPattern': '', 'samplingRate': _samplingRate, 'copyFiles': True, 'setDefaultOrigin': False, } prot = self.newProtocol(ProtImportVolumes, **args) prot.setObjLabel('import volume(%s)' % XMIPP_SYM_NAME[sym]) self.launchProtocol(prot) # execute protocol extract unitCell args = { 'inputVolumes': prot.outputVolume, 'symmetryGroup': sym, 'symmetryOrder': self.symOrder, 'innerRadius': self.innerRadius, 'outerRadius': self.outerRadius, 'expandFactor': .2, 'offset': offset } prot = self.newProtocol(XmippProtExtractUnit, **args) prot.setObjLabel('extract unit cell') self.launchProtocol(prot) # check results ih = ImageHandler() xdim, ydim, zdim, ndim = \ ih.getDimensions(prot.outputVolume.getFileName()) self.assertTrue(abs(xdim - self.box[sym][0]) < 2) self.assertTrue(abs(ydim - self.box[sym][1]) < 2) self.assertTrue(abs(zdim - self.box[sym][2]) < 2) # create pdb fileoutput args = { 'inputStructure': prot.outputVolume, 'maskMode': NMA_MASK_THRE, 'maskThreshold': 0.5, 'pseudoAtomRadius': 1.5 } prot = self.newProtocol(XmippProtConvertToPseudoAtoms, **args) prot.setObjLabel('get pdb') self.launchProtocol(prot) # check results filenamePdb = prot._getPath('pseudoatoms.pdb') self.assertTrue(os.path.isfile(filenamePdb)) # delete temporary files os.remove(self.filename[sym]) os.remove(outputFile)