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 _createClasses(self, partSet): self._classesDict = {} # store classes info, indexed by class id pathDict = {} self.protocol.info('Loading classes info from: %s' % self._modelStarFile) modelMd = md.MetaData('model_classes@' + self._modelStarFile) for classNumber, objId in enumerate(modelMd): row = md.Row() row.readFromMd(modelMd, objId) index, fn = relionToLocation(row.getValue('rlnReferenceImage')) if fn in pathDict: newFn = pathDict.get(fn) else: clsPath = findRootFrom(self._modelStarFile, fn) if clsPath is None: newFn = fn else: newFn = self.protocol._getExtraPath(os.path.basename(fn)) self.copyOrLink(os.path.join(clsPath, fn), newFn) pathDict[fn] = newFn self._classesDict[classNumber + 1] = (index, newFn, row) clsSet = self._classesFunc(partSet) clsSet.classifyItems(updateClassCallback=self._updateClass) self.protocol._defineOutputs(outputClasses=clsSet) self.protocol._defineSourceRelation(partSet, clsSet)
def createAngDistributionSqlite(self, sqliteFn, numberOfParticles, itemDataIterator): import pyworkflow.em.metadata as md if not os.path.exists(sqliteFn): # List of list of 3 elements containing angleTilt, anglePsi, weight projectionList = [] def getCloseProjection(angleRot, angleTilt): """ Get an existing projection close to angleRot, angleTilt. Return None if not found close enough. """ for projection in projectionList: if (abs(projection[0] - angleRot) <= 0.5 and abs(projection[1] - angleTilt) <= 0.5): return projection return None weight = 1. / numberOfParticles for angleRot, angleTilt in itemDataIterator: projection = getCloseProjection(angleRot, angleTilt) if projection is None: projectionList.append([angleRot, angleTilt, weight]) else: projection[2] = projection[2] + weight mdProj = md.MetaData() for projection in projectionList: mdRow = md.Row() mdRow.setValue(md.MDL_ANGLE_ROT, projection[0]) mdRow.setValue(md.MDL_ANGLE_TILT, projection[1]) mdRow.setValue(md.MDL_WEIGHT, projection[2]) mdRow.writeToMd(mdProj, mdProj.addObject()) mdProj.write(sqliteFn)
def _pickMicrograph(self, mic, *args): """ This method should be invoked only when working in streaming mode. """ micRow = md.Row() self._preprocessMicrographRow(mic, micRow) micrographToRow(mic, micRow) self._postprocessMicrographRow(mic, micRow) self._pickMicrographsFromStar(self._getMicStarFile(mic), *args)
def _pickMicrograph(self, mic, params, threshold, minDistance, fom): """ This method should be invoked only when working in streaming mode. """ micRow = md.Row() self._preprocessMicrographRow(mic, micRow) micrographToRow(mic, micRow) self._postprocessMicrographRow(mic, micRow) self._pickMicrographsFromStar(self._getMicStarFile(mic), params, threshold, minDistance, fom)
def createRefMd(self, vols): refVols = self._getExtraPath('ref_volumes.xmd') mdFn = md.MetaData() if self.isSetOfVolumes(): for vol in vols: imgId = vol.getObjId() row = md.Row() row.setValue(md.MDL_ITEM_ID, long(imgId)) row.setValue(md.MDL_IMAGE, getImageLocation(vol)) row.setValue(md.MDL_ENABLED, 1) row.addToMd(mdFn) else: imgId = vols.getObjId() row = md.Row() row.setValue(md.MDL_ITEM_ID, long(imgId)) row.setValue(md.MDL_IMAGE, getImageLocation(vols)) row.setValue(md.MDL_ENABLED, 1) row.addToMd(mdFn) mdFn.write(refVols, md.MD_APPEND)
def _preprocessParticleRow(self, img, imgRow): if self._imgPath: # Create a link or copy files to extraPath # and update the Row properly index, fn = xmippToLocation(imgRow.getValue(md.MDL_IMAGE)) imgBase = basename(fn) imgDst = self.protocol._getExtraPath(imgBase) if not exists(imgDst): self.copyOrLink(join(self._imgPath, fn), imgDst) imgRow.setValue(md.MDL_IMAGE, locationToXmipp(index, imgDst)) if self._micIdOrName: micId = imgRow.getValue(md.MDL_MICROGRAPH_ID, None) micName = imgRow.getValue(md.MDL_MICROGRAPH, None) # Check which is the key to identify micrographs (id or name) if micId is not None: micKey = micId else: micKey = micName mic = self.micDict.get(micKey, None) # First time I found this micrograph (either by id or name) if mic is None: mic = Micrograph() mic.setObjId(micId) if micName is None: micName = self.protocol._getExtraPath( 'fake_micrograph%6d' % micId) mic.setFileName(micName) self.micSet.append(mic) # Update dict with new Micrograph self.micDict[micKey] = mic # Update the row to set a MDL_MICROGRAPH_ID imgRow.setValue(md.MDL_MICROGRAPH_ID, long(mic.getObjId())) # JMRT: This means that the metadata contains MDL_CTF_MODEL # and the files path were found from some root # In Xmipp 3.1 the ctfparam metadata in particles # was replaced with directly seeting the CTF values # so we need to fill those in the particle row if self._ctfPath: ctfModel = imgRow.getValue(md.MDL_CTF_MODEL) if ctfModel in self._ctfDict: ctfRow = self._ctfDict[ctfModel] else: ctfRow = md.Row() ctfRow.readFromFile(join(self._ctfPath, ctfModel)) self._ctfDict[ctfModel] = ctfRow imgRow.copyFromRow(ctfRow)
def _pickMicrograph(self, mic, params, threshold, minDistance, fom): """ This method should be invoked only when working in streaming mode. """ # We need to write the needed star files # TODO: We need to check when working in real streaming, not all # TODO: CTF will be available and this needs to be taken into account micRow = md.Row() self._preprocessMicrographRow(mic, micRow) micrographToRow(mic, micRow) self._postprocessMicrographRow(mic, micRow) print micRow self._pickMicrographsFromStar(self._getMicStarFile(mic), params, threshold, minDistance, fom)
def createInputMd(self, vols): fnVols = self._getExtraPath('input_volumes.xmd') if self.copyAlignment: alignType = vols.getAlignment() else: alignType = ALIGN_NONE writeSetOfVolumes(vols, fnVols, postprocessImageRow=self._postprocessVolumeRow, alignType=alignType) if not vols.hasAlignment() or not self.copyAlignment: mdFn = md.MetaData(fnVols) mdFn.fillConstant(md.MDL_ANGLE_ROT, 0.) mdFn.fillConstant(md.MDL_ANGLE_TILT, 0.) mdFn.fillConstant(md.MDL_ANGLE_PSI, 0.) mdFn.fillConstant(md.MDL_SHIFT_X, 0.) mdFn.fillConstant(md.MDL_SHIFT_Y, 0.) mdFn.fillConstant(md.MDL_SHIFT_Z, 0.) mdFn.write(fnVols, md.MD_OVERWRITE) # set missing angles missType = ['wedge_y', 'wedge_x', 'pyramid', 'cone'] missNum = self.missingDataType.get() missAng = self.missingAng.get() missDataFn = self._getExtraPath('wedges.xmd') missAngValues = str(missAng).strip().split() thetaY0, thetaYF, thetaX0, thetaXF = 0, 0, 0, 0 mdFn = md.MetaData() if missNum == MISSING_WEDGE_X: thetaX0, thetaXF = missAngValues elif missNum == MISSING_WEDGE_Y: thetaY0, thetaYF = missAngValues elif missNum == MISSING_PYRAMID: thetaY0, thetaYF, thetaX0, thetaXF = missAngValues else: # MISSING_CONE thetaY0 = missAngValues[0] for i in range(1, vols.getSize() + 1): row = md.Row() row.setValue(md.MDL_MISSINGREGION_NR, missNum + 1) row.setValue(md.MDL_MISSINGREGION_TYPE, missType[missNum]) row.setValue(md.MDL_MISSINGREGION_THX0, float(thetaX0)) row.setValue(md.MDL_MISSINGREGION_THXF, float(thetaXF)) row.setValue(md.MDL_MISSINGREGION_THY0, float(thetaY0)) row.setValue(md.MDL_MISSINGREGION_THYF, float(thetaYF)) row.addToMd(mdFn) mdFn.write(missDataFn, md.MD_APPEND)
def setOfImagesToMd(imgSet, imgMd, imgToFunc, **kwargs): """ This function will fill Relion metadata from a SetOfMicrographs Params: imgSet: the set of images to be converted to metadata md: metadata to be filled rowFunc: this function can be used to setup the row before adding to meta """ if 'alignType' not in kwargs: kwargs['alignType'] = imgSet.getAlignment() for img in imgSet: objId = imgMd.addObject() imgRow = md.Row() imgToFunc(img, imgRow, **kwargs) imgRow.writeToMd(imgMd, objId)
def generateOutputClasses(self, classesOut, firstTime): if firstTime: self._saveFileDataClasses(classesOut, self._getExtraPath('last_classes.xmd')) # Add the two new classes for i in range(1, 3): mdImgsInClass = md.MetaData('class%06d_images@%s' % (i, classesOut)) mdImgsInClass.write(self._getExtraPath('dataClass%06d.xmd' % i)) return finalMetadata = self._getExtraPath('aux_classes.stk') lastMetadata = self._getExtraPath('last_classes.xmd') newMetadata = classesOut total = self.averageClasses(finalMetadata, lastMetadata, newMetadata, False) copy(self._getExtraPath('aux_classes.stk'), self._getExtraPath('last_classes.stk')) mdAll = md.MetaData() newRef = 1 for i in total: if i != 0: row = md.Row() row.setValue(md.MDL_REF, newRef) row.setValue(md.MDL_IMAGE, '%06d@' % newRef + finalMetadata) row.setValue(md.MDL_CLASS_COUNT, i) row.addToMd(mdAll) newRef += 1 mdAll.write('classes@' + finalMetadata[:-3] + 'xmd', MD_APPEND) copy(self._getExtraPath('aux_classes.xmd'), self._getExtraPath('last_classes.xmd')) newRef = 1 for i, val in enumerate(total): if val != 0: self._unionDataClass(classesOut, i + 1, newRef) newRef += 1
def writeReferences(inputSet, outputRoot, useBasename=False, **kwargs): """ Write references star and stack files from SetOfAverages or SetOfClasses2D/3D. Params: inputSet: the input SetOfParticles to be converted outputRoot: where to write the output files. basename: If True, use the basename of the stack for setting path. """ refsMd = md.MetaData() stackFile = outputRoot + '.stk' stackName = basename(stackFile) if useBasename else stackFile starFile = outputRoot + '.star' ih = em.ImageHandler() row = md.Row() def _convert(item, i, convertFunc): index = i + 1 ih.convert(item, (index, stackFile)) item.setLocation(index, stackName) convertFunc(item, row, **kwargs) row.writeToMd(refsMd, refsMd.addObject()) if isinstance(inputSet, em.SetOfAverages): for i, img in enumerate(inputSet): _convert(img, i, particleToRow) elif isinstance(inputSet, em.SetOfClasses2D): for i, rep in enumerate(inputSet.iterRepresentatives()): _convert(rep, i, particleToRow) elif isinstance(inputSet, em.SetOfClasses3D): for i, rep in enumerate(inputSet.iterRepresentatives()): _convert(rep, i, imageToRow) elif isinstance(inputSet, em.SetOfVolumes): for i, vol in enumerate(inputSet): _convert(vol, i, imageToRow) else: raise Exception('Invalid object type: %s' % type(inputSet)) refsMd.write(starFile)
def writeSetOfMicrographs(micSet, filename): """ Simplified function borrowed from xmipp. """ mdata = md.MetaData() for img in micSet: objId = mdata.addObject() imgRow = md.Row() imgRow.setValue(md.MDL_ITEM_ID, long(objId)) index, fname = img.getLocation() fn = ImageHandler.locationToXmipp((index, fname)) imgRow.setValue(md.MDL_MICROGRAPH, fn) if img.isEnabled(): enabled = 1 else: enabled = -1 imgRow.setValue(md.MDL_ENABLED, enabled) imgRow.writeToMd(mdata, objId) mdata.write('Micrographs@%s' % filename)
def prepareMetadata(self, metadata, image, initItem): newRow = md.Row() for i, img in enumerate(self.predict): image.setData(np.squeeze(img)) path = '%06d@' % (i + initItem) + self._getExtraPath( 'particlesDenoised.stk') image.write(path) pathNoise = '%06d@' % (i + initItem) + self._getExtraPath( 'resizedParticles.stk') newRow.setValue(md.MDL_IMAGE, path) newRow.setValue(md.MDL_IMAGE_ORIGINAL, pathNoise) if self.model.get() == ITER_TRAIN: from scipy.stats import pearsonr pathProj = '%06d@' % (i + initItem) + self._getExtraPath( 'resizedProjections.stk') newRow.setValue(md.MDL_IMAGE_REF, pathProj) correlations1, _ = pearsonr(img.ravel(), self.projections[i].ravel()) newRow.setValue(md.MDL_CORR_DENOISED_PROJECTION, correlations1) newRow.addToMd(metadata)
def particleToRow(part, partItem, **kwargs): """ Set labels values from Particle to md row. """ partRow = md.Row() coord = part.getCoordinate() if coord is not None: coordinateToRow(coord, partRow, md.RLN_MICROGRAPH_ID, copyId=False) if part.hasMicId(): partRow.setValue(md.RLN_MICROGRAPH_ID, long(part.getMicId())) # If the row does not contains the micrgraphs name # use a fake micrograph name using id to relion # could at least group for CTF using that if not partRow.hasLabel(md.RLN_MICROGRAPH_NAME): partRow.setValue(md.RLN_MICROGRAPH_NAME, 'fake_micrograph_%06d.mrc' % part.getMicId()) if part.hasAttribute('_rlnParticleId'): partRow.setValue(md.RLN_PARTICLE_ID, long(part._rlnParticleId.get())) imageToRow(part, partRow, md.RLN_IMAGE_NAME, **kwargs) for label, value in partRow._labelDict.iteritems(): labelStr = md.label2Str(label) setattr(partItem, labelStr, value)
def _preprocessMicrographRow(self, img, imgRow): if self._imgPath: # Create a link or copy files to extraPath # and update the Row properly micFile = imgRow.getValue(md.MDL_MICROGRAPH) micBase = basename(micFile) micDst = self.protocol._getExtraPath(micBase) self.copyOrLink(join(self._imgPath, micFile), micDst) imgRow.setValue(md.MDL_MICROGRAPH, micDst) self._fillMicName(img, micBase) if self._ctfPath: # Read Xmipp ctfModel parameters and add # to the original micrograph row ctfFile = imgRow.getValue(md.MDL_CTF_MODEL) ctfPath = join(self._imgPath, ctfFile) ctfRow = md.Row() ctfRow.readFromFile(ctfPath) imgRow.copyFromRow(ctfRow) # Also copy or link to the result micrograph # folder output by Xmipp containing the PSD and other images ctfSrcDir = dirname(ctfPath) ctfBaseDir = basename(ctfSrcDir) ctfDstDir = self.protocol._getExtraPath(ctfBaseDir) if self.copyOrLink == createLink: createLink(ctfSrcDir, ctfDstDir) else: # use copyTree instead of copyFile copyTree(ctfSrcDir, ctfDstDir) # Fix the path to psd files for label in CTF_PSD_DICT.values(): filePath = imgRow.getValue(label) # Take the last part of the path including # the filename and the folder up to that fileName = basename(filePath) newFilePath = join(ctfDstDir, fileName) imgRow.setValue(label, newFilePath)
def writeReferences(inputSet, outputRoot): """ Write an references star and stack files from a given SetOfAverages or SetOfClasses2D. """ refsMd = md.MetaData() stackFile = outputRoot + '.stk' baseStack = basename(stackFile) starFile = outputRoot + '.star' ih = em.ImageHandler() if isinstance(inputSet, em.SetOfAverages): row = md.Row() for i, img in enumerate(inputSet): ih.convert(img, (i + 1, stackFile)) img.setLocation((i + 1, baseStack)) # make the star with relative particleToRow(img, row) row.writeToMd(refsMd, refsMd.addObject()) refsMd.write(starFile) elif isinstance(inputSet, em.SetOfClasses2D): pass else: raise Exception('Invalid object type: %s' % type(inputSet))
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 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 _processMovie(self, movie): movId = movie.getObjId() x, y, n = movie.getDim() iniFrame, lastFrame, _ = movie.getFramesRange() frame0, frameN = self._getRange(movie) boxSize = self.boxSize.get() if movie.hasAlignment() and self.applyAlignment: shiftX, shiftY = movie.getAlignment().getShifts() # lists. else: shiftX = [0] * (lastFrame - iniFrame + 1) shiftY = shiftX stkIndex = 0 movieStk = self._getMovieName(movie, '.stk') movieMdFile = self._getMovieName(movie, '.xmd') movieMd = md.MetaData() frameMd = md.MetaData() frameMdImages = md.MetaData() frameRow = md.Row() if self._hasCoordinates(movie): imgh = ImageHandler() for frame in range(frame0, frameN + 1): indx = frame - iniFrame frameName = self._getFnRelated('frameMic', movId, frame) frameMdFile = self._getFnRelated('frameMdFile', movId, frame) coordinatesName = self._getFnRelated('frameCoords', movId, frame) frameImages = self._getFnRelated('frameImages', movId, frame) frameStk = self._getFnRelated('frameStk', movId, frame) self._writeXmippPosFile(movie, coordinatesName, shiftX[indx], shiftY[indx]) self.info("Writing frame: %s" % frameName) # TODO: there is no need to write the frame and then operate # the input of the first operation should be the movie movieName = imgh.fixXmippVolumeFileName(movie) imgh.convert((frame, movieName), frameName) if self.doRemoveDust: self.info("Removing Dust") self._runNoDust(frameName) self.info("Extracting particles") args = '-i %(frameName)s --pos %(coordinatesName)s ' \ '-o %(frameImages)s --Xdim %(boxSize)d' % locals() if self.doInvert: args += " --invert" if self.doBorders: args += " --fillBorders" args += " --downsampling %f " % self.getBoxScale() self.runJob('xmipp_micrograph_scissor', args) cleanPath(frameName) self.info("Combining particles into one stack.") frameMdImages.read(frameMdFile) frameMd.read('particles@%s' % coordinatesName) frameMd.merge(frameMdImages) for objId in frameMd: stkIndex += 1 frameRow.readFromMd(frameMd, objId) location = xmippToLocation(frameRow.getValue(md.MDL_IMAGE)) newLocation = (stkIndex, movieStk) imgh.convert(location, newLocation) # Fix the name to be accessible from the Project directory # so we know that the movie stack file will be moved # to final particles folder newImageName = '%d@%s' % newLocation frameRow.setValue(md.MDL_IMAGE, newImageName) frameRow.setValue(md.MDL_MICROGRAPH_ID, long(movId)) frameRow.setValue(md.MDL_MICROGRAPH, str(movId)) frameRow.setValue(md.MDL_FRAME_ID, long(frame)) frameRow.setValue(md.MDL_PARTICLE_ID, frameRow.getValue(md.MDL_ITEM_ID)) frameRow.writeToMd(movieMd, movieMd.addObject()) movieMd.addItemId() movieMd.write(movieMdFile) cleanPath(frameStk) if self.doNormalize: numberOfFrames = frameN - frame0 + 1 self._runNormalize(movieStk, numberOfFrames)
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 _processMovie(self, movieId, movieName, movieFolder, shifts): ###pasar shifts movieName = os.path.join(movieFolder, movieName) boxSize = self.boxSize.get() # Read movie dimensions to iterate through each frame imgh = ImageHandler() x, y, z, n = imgh.getDimensions(movieName) first = self.firstFrame.get() if first <= 1: first = 1 last = self.lastFrame.get() if last <= 0 or last >= n: last = n numberOfFrames = last - first + 1 if shifts is None: frames = max(z, n) shifts = [0] * (2 * frames) stkIndex = 0 movieStk = self._getMovieName(movieId, '.stk') movieMdFile = self._getMovieName(movieId, '.xmd') movieMd = md.MetaData() frameMd = md.MetaData() frameMdImages = md.MetaData() frameRow = md.Row() for frame in range(first, last + 1): # Get the frame shifts index = frame - first shiftX = shifts[2 * index] shiftY = shifts[2 * index + 1] frameRoot = os.path.join(movieFolder, 'frame_%02d' % frame) frameName = frameRoot + '.mrc' frameMdFile = frameRoot + '.xmd' framePosFile = frameRoot + '_coordinates.xmd' coordinatesName = frameRoot + '_coordinates.xmd' hasCoordinates = self._writeXmippPosFile(movieId, movieName, coordinatesName, shiftX, shiftY) if hasCoordinates: self.info("Writing frame: %s" % frameName) #TODO: there is no need to write the frame and then operate #the input of the first operation should be the movie imgh.convert(tuple([frame, movieName]), frameName) if self.doRemoveDust: self.info("Removing Dust") self._runNoDust(frameName) self.info("Extracting particles") frameImages = frameRoot + '_images' args = '-i %(frameName)s --pos %(coordinatesName)s ' \ '-o %(frameRoot)s --Xdim %(boxSize)d' % locals() if self.doInvert: args += " --invert" args += " --downsampling %f " % self.factor self.runJob('xmipp_micrograph_scissor', args) cleanPath(frameName) frameStk = frameRoot + '.stk' self.info("Combining particles into one stack.") frameMdImages.read(frameMdFile) frameMd.read('particles@%s' % framePosFile) frameMd.merge(frameMdImages) for objId in frameMd: stkIndex += 1 frameRow.readFromMd(frameMd, objId) location = xmippToLocation(frameRow.getValue(md.MDL_IMAGE)) newLocation = (stkIndex, movieStk) imgh.convert(location, newLocation) # Fix the name to be accesible from the Project directory # so we know that the movie stack file will be moved # to final particles folder newImageName = '%d@%s' % newLocation frameRow.setValue(md.MDL_IMAGE, newImageName) frameRow.setValue(md.MDL_MICROGRAPH_ID, long(movieId)) frameRow.setValue(md.MDL_MICROGRAPH, str(movieId)) frameRow.setValue(md.MDL_FRAME_ID, long(frame)) frameRow.setValue(md.MDL_PARTICLE_ID, frameRow.getValue(md.MDL_ITEM_ID)) frameRow.writeToMd(movieMd, movieMd.addObject()) movieMd.addItemId() movieMd.write(movieMdFile) cleanPath(frameStk) if self.doNormalize: self._runNormalize(movieStk, numberOfFrames)