# **************************************************************************
# *
# * Authors: J.M. De la Rosa Trevin (delarosatrevin@scilifelab.se) [1]
# *
# * [1] SciLifeLab, Stockholm University
# *
# * 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 3 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 'scipion@cnb.csic.es'
# *
# **************************************************************************
import pyworkflow.object as pwobj
import pyworkflow.utils as pwutils
import pyworkflow.protocol.params as params
import pwem.objects as emobj
from .protocol_2d import ProtAlign2D
[docs]class ProtClassesConsensus(ProtAlign2D):
""" Compare two SetOfClasses
"""
_label = 'classes consensus'
def _defineParams(self, form):
form.addSection(label='Input')
form.addParam('inputClasses1', params.PointerParam,
pointerClass='SetOfClasses',
label='Input classes 1',
help='')
form.addParam('inputClasses2', params.PointerParam,
pointerClass='SetOfClasses',
label='Input classes 2',
help='')
form.addParallelSection(threads=0, mpi=0)
# -------------------------- INSERT steps functions ---------------------------
def _insertAllSteps(self):
"""for each ctf insert the steps to compare it
"""
self._insertFunctionStep('compareClassesStep',
self.inputClasses1.getObjId(),
self.inputClasses2.getObjId())
[docs] def compareClassesStep(self, i1, i2):
set1 = self.inputClasses1.get()
set2 = self.inputClasses2.get()
# Compare each pair of class from set1 and set2
# compute the Jaccard index for each (J = len(intersection) / len(union))
# Create a list will all pairs indexes and the sort them
jaccardList = []
f = open(self._getPath('jaccard.txt'), 'w')
f.write('; class1 class2 intersection(i) union(i) jaccard index = len(i)/len(u)\n')
for cls1 in set1:
ids1 = cls1.getIdSet()
for cls2 in set2:
ids2 = cls2.getIdSet()
inter = len(ids1.intersection(ids2))
union = len(ids1.union(ids2))
jaccardIndex = float(inter) / union
jaccardTuple = (cls1.getObjId(), cls2.getObjId(), inter, union,
jaccardIndex)
f.write('%d %d %d %d %0.3f\n' % jaccardTuple)
jaccardList.append(jaccardTuple)
f.close()
jaccardList.sort(key=lambda e: e[4], reverse=True)
visitedClasses = set()
outputFn = self._getPath('consensus.sqlite')
pwutils.cleanPath(outputFn)
outputSet = emobj.EMSet(filename=outputFn)
for clsId1, clsId2, inter, union, jaccardIndex in jaccardList:
if clsId1 not in visitedClasses:
visitedClasses.add(clsId1) # mark as visited
cls1 = set1[clsId1]
cls2 = set2[clsId2]
o = pwobj.Object()
o.setObjLabel('classes %d - %d' % (clsId1, clsId2))
o.class1 = cls1.clone()
o.class1.id = pwobj.Integer(clsId1)
o.class2 = cls2.clone()
o.class2.id = pwobj.Integer(clsId2)
o.jaccard = pwobj.Float(jaccardIndex)
o.intersection = pwobj.Integer(inter)
o.union = pwobj.Integer(union)
outputSet.append(o)
self._defineOutputs(outputConsensus=outputSet)
def _summary(self):
summary = []
return summary
def _methods(self):
methods = []
return methods
def _validate(self):
errors = []
return errors