def createOutputStep(self): particles = self.inputParticles.get() # Generate the SetOfAlignmet alignedSet = self._createSetOfParticles() alignedSet.copyInfo(particles) inputMd = self._getPath('aligned_particles.xmd') alignedSet.copyItems(particles, updateItemCallback=self._updateItem, itemDataIterator=md.iterRows( inputMd, sortByLabel=md.MDL_ITEM_ID)) # Remove alignment 2D alignedSet.setAlignment(em.ALIGN_NONE) # Define the output average avgFile = self._getExtraPath("average.xmp") imgh = ImageHandler() avgImage = imgh.computeAverage(alignedSet) avgImage.write(avgFile) avg = em.Particle() avg.setLocation(1, avgFile) avg.copyInfo(alignedSet) self._defineOutputs(outputAverage=avg) self._defineSourceRelation(self.inputParticles, avg) self._defineOutputs(outputParticles=alignedSet) self._defineSourceRelation(self.inputParticles, alignedSet)
def readPartsFromMics(self, micList, outputParts): """ Read the particles extract for the given list of micrographs and update the outputParts set with new items. """ p = em.Particle() for mic in micList: # We need to make this dict because there is no ID in the # coord.star file coordDict = {} for coord in self.coordDict[mic.getObjId()]: coordDict[self._getPos(coord)] = coord _, partStarFn = self._getStarFiles(mic) for row in md.iterRows(self._getPath(partStarFn)): pos = (row.getValue(md.RLN_IMAGE_COORD_X), row.getValue(md.RLN_IMAGE_COORD_Y)) coord = coordDict.get(pos, None) if coord is not None: # scale the coordinates according to particles dimension. coord.scale(self.getBoxScale()) p.copyObjId(coord) idx, fn = relionToLocation(row.getValue(md.RLN_IMAGE_NAME)) p.setLocation(idx, self._getPath(fn[2:])) p.setCoordinate(coord) p.setMicId(mic.getObjId()) p.setCTF(mic.getCTF()) outputParts.append(p) # Release the list of coordinates for this micrograph since it # will not be longer needed del self.coordDict[mic.getObjId()]
def rowToParticle(partRow, **kwargs): """ Create a Particle from a row of a meta """ img = em.Particle() # Provide a hook to be used if something is needed to be # done for special cases before converting image to row preprocessImageRow = kwargs.get('preprocessImageRow', None) if preprocessImageRow: preprocessImageRow(img, partRow) # Decompose Relion filename index, filename = relionToLocation(partRow.getValue(md.RLN_IMAGE_NAME)) img.setLocation(index, filename) if partRow.containsLabel(md.RLN_PARTICLE_CLASS): img.setClassId(partRow.getValue(md.RLN_PARTICLE_CLASS)) if kwargs.get('readCtf', True): img.setCTF(rowToCtfModel(partRow)) # alignment is mandatory at this point, it shoud be check # and detected defaults if not passed at readSetOf.. level alignType = kwargs.get('alignType') if alignType != em.ALIGN_NONE: img.setTransform(rowToAlignment(partRow, alignType)) if kwargs.get('readAcquisition', True): img.setAcquisition(rowToAcquisition(partRow)) if kwargs.get('magnification', None): img.getAcquisition().setMagnification(kwargs.get("magnification")) setObjId(img, partRow) # Read some extra labels rowToObject(partRow, img, {}, extraLabels=IMAGE_EXTRA_LABELS + kwargs.get('extraLabels', [])) img.setCoordinate(rowToCoordinate(partRow)) # copy micId if available from row to particle if partRow.hasLabel(md.RLN_MICROGRAPH_ID): img.setMicId(partRow.getValue(md.RLN_MICROGRAPH_ID)) # copy particleId if available from row to particle if partRow.hasLabel(md.RLN_PARTICLE_ID): img._rlnParticleId = Integer(partRow.getValue(md.RLN_PARTICLE_ID)) # copy particleId if available from row to particle if partRow.hasLabel(md.RLN_PARTICLE_RANDOM_SUBSET): img._rln_halfId = Integer(partRow.getValue(md.RLN_PARTICLE_RANDOM_SUBSET)) # Provide a hook to be used if something is needed to be # done for special cases before converting image to row postprocessImageRow = kwargs.get('postprocessImageRow', None) if postprocessImageRow: postprocessImageRow(img, partRow) return img
def createOutputStep(self): """ Store the setOfParticles object as result of the protocol. """ particles = self.inputParticles.get() # Define the output average avgFile = self._getExtraPath('level_00', 'class_classes.stk') avg = em.Particle() avg.setLocation(1, avgFile) avg.copyInfo(particles) self._defineOutputs(outputAverage=avg) self._defineSourceRelation(self.inputParticles, avg) # Generate the Set of Particles with alignment alignedSet = self._createSetOfParticles() alignedSet.copyInfo(particles) alignedSet.setRepresentative(avg) alignedSet.copyItems(particles, updateItemCallback=self._createItemMatrix, itemDataIterator=md.iterRows(self.imgsFn, sortByLabel=md.MDL_ITEM_ID)) alignedSet.setAlignment(em.ALIGN_2D) self._defineOutputs(outputParticles=alignedSet) self._defineSourceRelation(self.inputParticles, alignedSet)
def createOutputStep(self): inputMics = self.getInputMicrographs() inputCoords = self.getInputCoords() coordMics = inputCoords.getMicrographs() # Create output SetOfParticles partSet = self._createSetOfParticles() partSet.copyInfo(inputMics) # set coords from the input, will update later if needed partSet.setCoordinates(inputCoords) hasCTF = self.ctfRelations.hasValue() partSet.setSamplingRate(self._getNewSampling()) partSet.setHasCTF(hasCTF) ctfDict = {} if hasCTF: # Load CTF dictionary for all micrographs, all CTF should be present for ctf in self.ctfRelations.get(): ctfMic = ctf.getMicrograph() newCTF = ctf.clone() ctfDict[ctfMic.getMicName()] = newCTF # Keep a dictionary between the micName and its corresponding # particles stack file and CTF model object micDict = {} for mic in inputMics: stackFile = self._getMicStackFile(mic) ctfModel = ctfDict[mic.getMicName()] if hasCTF else None micDict[mic.getMicName()] = (stackFile, ctfModel) scaleFactor = self.getBoxScale() doScale = self.notOne(scaleFactor) # Track last micName to know when to load particles from another # micrograph stack lastMicName = None count = 0 # Counter for the particles of a given micrograph for coord in inputCoords.iterItems(orderBy='_micId'): micName = coordMics[coord.getMicId()].getMicName() # If Micrograph Source is "other" and extract from a subset # of micrographs, micName key should be checked if it exists. if micName in micDict.keys(): # Load the new particles mrcs file and reset counter if micName != lastMicName: stackFile, ctfModel = micDict[micName] count = 1 lastMicName = micName p = em.Particle() p.setLocation(count, stackFile) if hasCTF: p.setCTF(ctfModel) p.setCoordinate(coord) # Copy objId and micId from the coordinate p.copyObjId(coord) p.setMicId(coord.getMicId()) if doScale: p.scaleCoordinate(scaleFactor) partSet.append(p) count += 1 self._defineOutputs(outputParticles=partSet) self._defineSourceRelation(self.inputCoordinates, partSet) if self.ctfRelations.hasValue(): self._defineSourceRelation(self.ctfRelations.get(), partSet)
def readPartsFromMics(self, micList, outputParts): """ Read the particles extract for the given list of micrographs and update the outputParts set with new items. """ p = em.Particle() # Let's create a dict with the names of the mic in Relion star files # and also create a set with all star files to iterate them once starSet = set() micPathDict = {} for mic in micList: starSet.add(self._micCoordStarDict[mic.getObjId()]) micName = pwutils.replaceBaseExt(mic.getFileName(), 'mrc') micFile = os.path.join('extra', micName) micPathDict[micFile] = mic prevMicFile = None mic = None for partStarFn in starSet: for row in md.iterRows(self._getPath(partStarFn), sortByLabel=md.RLN_MICROGRAPH_NAME): micFile = row.getValue(md.RLN_MICROGRAPH_NAME) if micFile != prevMicFile: # Load some stuff when new mic if prevMicFile is not None: # cleanup previous mic # Release the list of coordinates for this micrograph # since it will not be longer needed del self.coordDict[mic.getObjId()] mic = micPathDict[micFile] coordDict = {self._getPos(coord): coord for coord in self.coordDict[mic.getObjId()]} posSet = set() # Set of (x, y) pairs to avoid duplicates prevMicFile = micFile pos = (row.getValue(md.RLN_IMAGE_COORD_X), row.getValue(md.RLN_IMAGE_COORD_Y)) if pos in posSet: print("Duplicate coordinate at: %s, IGNORED. " % str(pos)) coord = None else: coord = coordDict.get(pos, None) if coord is not None: # scale the coordinates according to particles dimension. coord.scale(self.getBoxScale()) p.copyObjId(coord) idx, fn = relionToLocation(row.getValue(md.RLN_IMAGE_NAME)) p.setLocation(idx, self._getPath(fn[2:])) p.setCoordinate(coord) p.setMicId(mic.getObjId()) p.setCTF(mic.getCTF()) outputParts.append(p) posSet.add(pos) # Clean up the last mic if necessary if mic is not None: del self.coordDict[mic.getObjId()]