Source code for deepfinder.protocols.protocol_annotation

# -*- coding: utf-8 -*-
# **************************************************************************
# *
# * Authors: Emmanuel Moebel (emmanuel.moebel@inria.fr)
# *
# * Inria - Centre de Rennes Bretagne Atlantique, France
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'you@yourinstitution.email'
# *
# **************************************************************************
from os.path import abspath
from pyworkflow import BETA
from pyworkflow.object import String, Integer
from pyworkflow.protocol import IntParam
from pyworkflow.utils import removeBaseExt
from tomo.constants import BOTTOM_LEFT_CORNER
from tomo.protocols import ProtTomoPicking
from tomo.objects import Coordinate3D

import deepfinder.convert as cv
from deepfinder.viewers.particle_annotator_tomo_viewer import ParticleAnnotatorDialog
from deepfinder.viewers.particle_annotator_tree import ParticleAnnotatorProvider


[docs]class DeepFinderAnnotations(ProtTomoPicking): """This protocol allows you to annotate macromolecules in your tomograms, using a visual tool.""" _label = 'annotate' _devStatus = BETA def __init__(self, **args): ProtTomoPicking.__init__(self, **args) self.annotationSummary = String() self._objectsToGo = Integer() self._provider = None # --------------------------- DEFINE param functions ---------------------- def _defineParams(self, form): ProtTomoPicking._defineParams(self, form) from pyworkflow.protocol import LEVEL_ADVANCED form.addParam('boxSize', IntParam, label="Box size", expertLevel=LEVEL_ADVANCED, help='Defualt box size for the output.', default=50) # --------------------------- INSERT steps functions ---------------------- def _insertAllSteps(self): self._initialize() self._insertFunctionStep('launchAnnotationStep', interactive=True) # self._insertFunctionStep('createOutputStep') # --------------------------- STEPS functions -----------------------------
[docs] def launchAnnotationStep(self): """ This generates 1 objl.xml file per tomogram and stores it in EXTRA""" # There are still some objects which haven't been annotated --> launch GUI self._getAnnotationStatus() if self._objectsToGo.get() > 0: ParticleAnnotatorDialog(None, self._getExtraPath(), provider=self._provider, prot=self) # All the objetcs have been annotated --> create output objects self._getAnnotationStatus() if self._objectsToGo.get() == 0: print("\n==> Generating the outputs") self._genOutput3DCoords() self._store()
def _genOutput3DCoords(self): setTomograms = self.inputTomograms.get() coord3DSet = self._createSetOfCoordinates3D(setTomograms) coord3DSet.setSamplingRate(setTomograms.getSamplingRate()) coord3DSet.setBoxSize(self.boxSize.get()) coordCounter = 0 annotationSummary = '' for tomo in setTomograms.iterItems(): # Read objl: fname_objl = 'objl_annot_' + removeBaseExt(tomo.getFileName()) + '.xml' objl_tomo = cv.objl_read(abspath(self._getExtraPath(fname_objl))) # Generate string for protocol summary: msg = 'Tomogram ' + tomo.getFileName() + ': a total of ' + \ str(len(objl_tomo)) + ' objects has been annotated.' annotationSummary += msg lbl_list = cv.objl_get_labels(objl_tomo) for lbl in lbl_list: objl_class = cv.objl_get_class(objl_tomo, lbl) msg = '\nClass ' + str(lbl) + ': ' + str(len(objl_class)) + ' objects' annotationSummary += msg annotationSummary += '\n' for idx in range(len(objl_tomo)): x = objl_tomo[idx]['x'] y = objl_tomo[idx]['y'] z = objl_tomo[idx]['z'] lbl = objl_tomo[idx]['label'] coord = Coordinate3D() coord.setObjId(coordCounter + 1) coord.setVolume(tomo) coord.setPosition(x, y, z, BOTTOM_LEFT_CORNER) coord.setVolId(tomo.getObjId()) coord._dfLabel = String(str(lbl)) coord.setBoxSize(self.boxSize.get()) coord3DSet.append(coord) coordCounter += 1 self._defineOutputs(outputCoordinates=coord3DSet) self._defineSourceRelation(setTomograms, coord3DSet) # --------------------------- DEFINE info functions ---------------------- def _summary(self): """ Summarize what the protocol has done""" summary = [] objects2go = self._objectsToGo.get() if objects2go is not None: if objects2go > 0: summary.append('*%i* remaining tomograms to be annotated.' % objects2go) else: summary.append('All tomograms have been already annotated.') if self.annotationSummary.get(): summary.append(self.annotationSummary.get()) return summary # --------------------------- UTIL functions ----------------------------------- def _initialize(self): self._tomoList = [tomo.clone() for tomo in self.inputTomograms.get().iterItems()] self._provider = ParticleAnnotatorProvider(self._tomoList, self._getExtraPath(), 'partAnnotator') self._getAnnotationStatus() def _getAnnotationStatus(self): """Check if all the tomo masks have been annotated and store current status in a text file""" doneTomes = [self._provider.getObjectInfo(tomo)['tags'] == 'done' for tomo in self._tomoList] self._objectsToGo.set(len(self._tomoList) - sum(doneTomes))