| 6 | 1 # | 
|  | 2 # Copyright INRA-URGI 2009-2010 | 
|  | 3 # | 
|  | 4 # This software is governed by the CeCILL license under French law and | 
|  | 5 # abiding by the rules of distribution of free software. You can use, | 
|  | 6 # modify and/ or redistribute the software under the terms of the CeCILL | 
|  | 7 # license as circulated by CEA, CNRS and INRIA at the following URL | 
|  | 8 # "http://www.cecill.info". | 
|  | 9 # | 
|  | 10 # As a counterpart to the access to the source code and rights to copy, | 
|  | 11 # modify and redistribute granted by the license, users are provided only | 
|  | 12 # with a limited warranty and the software's author, the holder of the | 
|  | 13 # economic rights, and the successive licensors have only limited | 
|  | 14 # liability. | 
|  | 15 # | 
|  | 16 # In this respect, the user's attention is drawn to the risks associated | 
|  | 17 # with loading, using, modifying and/or developing or reproducing the | 
|  | 18 # software by the user in light of its specific status of free software, | 
|  | 19 # that may mean that it is complicated to manipulate, and that also | 
|  | 20 # therefore means that it is reserved for developers and experienced | 
|  | 21 # professionals having in-depth computer knowledge. Users are therefore | 
|  | 22 # encouraged to load and test the software's suitability as regards their | 
|  | 23 # requirements in conditions enabling the security of their systems and/or | 
|  | 24 # data to be ensured and, more generally, to use and operate it in the | 
|  | 25 # same conditions as regards security. | 
|  | 26 # | 
|  | 27 # The fact that you are presently reading this means that you have had | 
|  | 28 # knowledge of the CeCILL license and that you accept its terms. | 
|  | 29 # | 
|  | 30 from SMART.Java.Python.structure.Interval import Interval | 
|  | 31 from commons.core.coord.Align import Align | 
|  | 32 | 
|  | 33 class SubMapping(Align): | 
|  | 34     """ | 
|  | 35     A class that represents a part of a mapping, more precisely, a pair (target interval, query interval) that match together | 
|  | 36     @ivar targetInterval: the target interval | 
|  | 37     @type targetInterval: class L{Interval<Interval>} | 
|  | 38     @ivar queryInterval:  the query interval | 
|  | 39     @type queryInterval:  class L{Interval<Interval>} | 
|  | 40     @ivar size:           size of this sub-mapping | 
|  | 41     @type size:           int | 
|  | 42     @ivar tags:           various information | 
|  | 43     @type tags:           dict | 
|  | 44     """ | 
|  | 45 | 
|  | 46     def __init__(self, subMapping = None): | 
|  | 47         """ | 
|  | 48         Constructor | 
|  | 49         @param subMapping: a sub-mapping to be copied | 
|  | 50         @type  subMapping: class L{SubMapping<SubMapping>} | 
|  | 51         """ | 
|  | 52         self.targetInterval = Interval() | 
|  | 53         self.queryInterval  = Interval() | 
|  | 54         Align.__init__(self, self.queryInterval, self.targetInterval) | 
|  | 55         self.size = None | 
|  | 56         self.tags = {} | 
|  | 57         if subMapping != None: | 
|  | 58             self.copy(subMapping) | 
|  | 59 | 
|  | 60     def __eq__(self, o): | 
|  | 61         if o == None: | 
|  | 62             return False | 
|  | 63         areAlignAttributesEquals = Align.__eq__(self, o) | 
|  | 64         return areAlignAttributesEquals and (self.targetInterval == o.targetInterval) and (self.queryInterval == o.queryInterval) and self.size == o.getSize() and self.tags == o.getTags() | 
|  | 65 | 
|  | 66     def getSuperAdress(self): | 
|  | 67         return hex(id(super(Align, self))) | 
|  | 68 | 
|  | 69 #    def setRangesAlignToRangesInterval(self): | 
|  | 70 #        self.range_query = super(Range, self.queryInterval) | 
|  | 71 #        self.range_subject = super(Range, self.targetInterval) | 
|  | 72 | 
|  | 73     def copy(self, subMapping): | 
|  | 74         """ | 
|  | 75         Copy method | 
|  | 76         @param subMapping: a sub-mapping to be copied | 
|  | 77         @type    subMapping: class L{SubMapping<SubMapping>} | 
|  | 78         """ | 
|  | 79         self.setQueryName(subMapping.getQueryName()) | 
|  | 80         self.setQueryStart(subMapping.getQueryStart()) | 
|  | 81         self.setQueryEnd(subMapping.getQueryEnd()) | 
|  | 82         self.setSubjectName(subMapping.getSubjectName()) | 
|  | 83         self.setSubjectStart(subMapping.getSubjectStart()) | 
|  | 84         self.setSubjectEnd(subMapping.getSubjectEnd()) | 
|  | 85         self.e_value = subMapping.getEvalue() | 
|  | 86         self.score = subMapping.getScore() | 
|  | 87         self.identity = subMapping.getIdentity() | 
|  | 88 | 
|  | 89         self.targetInterval.copy(subMapping.targetInterval) | 
|  | 90         self.queryInterval.copy(subMapping.queryInterval) | 
|  | 91         self.size = subMapping.size | 
|  | 92         for tag in subMapping.tags: | 
|  | 93             self.tags[tag] = subMapping.tags[tag] | 
|  | 94 | 
|  | 95 | 
|  | 96     def setTargetInterval(self, interval): | 
|  | 97         """ | 
|  | 98         Set target interval | 
|  | 99         @param targetInterval: the target interval of the sub-mapping | 
|  | 100         @type    targetInterval: class L{Interval<Interval>} | 
|  | 101         """ | 
|  | 102         self.targetInterval.copy(interval) | 
|  | 103 | 
|  | 104 | 
|  | 105     def setQueryInterval(self, interval): | 
|  | 106         """ | 
|  | 107         Set query interval | 
|  | 108         @param queryInterval: the query interval of the sub-mapping | 
|  | 109         @type    queryInterval: class L{Interval<Interval>} | 
|  | 110         """ | 
|  | 111         self.queryInterval.copy(interval) | 
|  | 112 | 
|  | 113 | 
|  | 114     def setSize(self, size): | 
|  | 115         """ | 
|  | 116         Set the size of the sub-mapping | 
|  | 117         Possibly also target and query interval sizes, as well as number of mismatches | 
|  | 118         @param size: the size of the sub-mapping | 
|  | 119         @type    size: int | 
|  | 120         """ | 
|  | 121         self.size = size | 
|  | 122         if "identity" in self.getTagNames(): | 
|  | 123             self.setTagValue("nbMismatches", self.size - round(self.size * self.getTagValue("identity") / 100.0)) | 
|  | 124 | 
|  | 125 | 
|  | 126     def getDirection(self): | 
|  | 127         """ | 
|  | 128         Get the direction of the alignment | 
|  | 129         """ | 
|  | 130         return self.targetInterval.getDirection() | 
|  | 131 | 
|  | 132 | 
|  | 133     def setDirection(self, direction): | 
|  | 134         """ | 
|  | 135         Set the direction of the alignment | 
|  | 136         @param direction: the directio of the alignment | 
|  | 137         type   direction: int or string | 
|  | 138         """ | 
|  | 139         return self.targetInterval.setDirection(direction) | 
|  | 140 | 
|  | 141 | 
|  | 142     def setTagValue(self, name, value): | 
|  | 143         """ | 
|  | 144         Set the value of a tag | 
|  | 145         @param name:    name of the tag | 
|  | 146         @type    name:    string | 
|  | 147         @param value: value of the tag | 
|  | 148         @type    value: string or int | 
|  | 149         """ | 
|  | 150         self.tags[name] = value | 
|  | 151 | 
|  | 152 | 
|  | 153     def getTagValue(self, name): | 
|  | 154         """ | 
|  | 155         Get the value of a tag | 
|  | 156         @param name:    name of the tag | 
|  | 157         @type    name:    string | 
|  | 158         @return:            value of the tag | 
|  | 159         """ | 
|  | 160         return self.tags[name] | 
|  | 161 | 
|  | 162 | 
|  | 163     def getTagNames(self): | 
|  | 164         """ | 
|  | 165         Get all the names of the tags | 
|  | 166         @return: the names of the tags | 
|  | 167         """ | 
|  | 168         return self.tags.keys() | 
|  | 169 | 
|  | 170     def getTargetInterval(self): | 
|  | 171         return self.targetInterval | 
|  | 172 | 
|  | 173     def getQueryInterval(self): | 
|  | 174         return self.queryInterval | 
|  | 175 | 
|  | 176     def getSize(self): | 
|  | 177         return self.size | 
|  | 178 | 
|  | 179     def getTags(self): | 
|  | 180         return self.tags | 
|  | 181 | 
|  | 182     def setIdentity(self, identity): | 
|  | 183         """ | 
|  | 184         Set the percentage of identity of the sub-mapping | 
|  | 185         Possibly also set number of mismatches | 
|  | 186         @param identity: the percentage of identity of the sub-mapping | 
|  | 187         @type  identity: float | 
|  | 188         """ | 
|  | 189         self.identity = identity | 
|  | 190         self.setTagValue("identity", identity) | 
|  | 191         if self.size != None and "nbMismatches" not in self.getTagNames(): | 
|  | 192             self.setTagValue("nbMismatches", self.size - round(self.size * self.getTagValue("identity") / 100.0)) | 
|  | 193 | 
|  | 194 | 
|  | 195     def setNbMismatches(self, nbMismatches): | 
|  | 196         """ | 
|  | 197         Set the number of mismatches of the sub-mapping | 
|  | 198         Possibly also set percentage of identity | 
|  | 199         @param nbMismatches: the number of mismatches of the sub-mapping | 
|  | 200         @type    nbMismatches: int | 
|  | 201         """ | 
|  | 202         self.nbMismatches = nbMismatches | 
|  | 203         if self.size != None and "identity" not in self.getTagNames(): | 
|  | 204             self.setTagValue("identity", (self.size - self.getTagValue("nbMismatches")) / float(self.size) * 100) | 
|  | 205 | 
|  | 206 | 
|  | 207     def setNbGaps(self, nbGaps): | 
|  | 208         """ | 
|  | 209         Set the number of gaps of the sub-mapping | 
|  | 210         @param nbGaps: the number of gaps of the sub-mapping | 
|  | 211         @type    nbGaps: int | 
|  | 212         """ | 
|  | 213         self.setTagValue("nbGaps", nbGaps) | 
|  | 214 | 
|  | 215 | 
|  | 216     def merge(self, subMapping): | 
|  | 217         """ | 
|  | 218         Merge two subMappings | 
|  | 219         @param subMapping: another sub-mapping | 
|  | 220         @type    subMapping: class L{SubMapping<SubMapping>} | 
|  | 221         """ | 
|  | 222         self.targetInterval.merge(subMapping.targetInterval) | 
|  | 223         self.queryInterval.merge(subMapping.queryInterval) | 
|  | 224 | 
|  | 225 | 
|  | 226     def printCoordinates(self): | 
|  | 227         """ | 
|  | 228         Print the coordinates of the sub-mapping (considering the direction) | 
|  | 229         @return: a string | 
|  | 230         """ | 
|  | 231         if self.getDirection() == 1: | 
|  | 232             return "%d-%d" % (self.targetInterval.getStart(), self.targetInterval.getEnd()) | 
|  | 233         else: | 
|  | 234             return "%d-%d" % (self.targetInterval.getEnd(), self.targetInterval.getStart()) | 
|  | 235 | 
|  | 236 | 
|  | 237     def __str__(self): | 
|  | 238         """ | 
|  | 239         Return a representation of this object | 
|  | 240         @return: a string | 
|  | 241         """ | 
|  | 242 | 
|  | 243         if "match" in self.getTagNames() and not self.getTagValue("match"): | 
|  | 244             return "%s ---" % self.queryName | 
|  | 245 | 
|  | 246         direction = "+" | 
|  | 247         if self.getDirection() == -1: | 
|  | 248             direction = "-" | 
|  | 249         string = "%s:%d-%d -- %s:%d-%d    (%s)" % (self.targetInterval.getChromosome(), self.targetInterval.getStart(), self.targetInterval.getEnd(), self.queryInterval.name, self.queryInterval.getStart(), self.queryInterval.getEnd(), direction) | 
|  | 250         if "nbMismatches" in self.getTagNames(): | 
|  | 251             string += "(%i mm)" % (self.getTagValue("nbMismatches")) | 
|  | 252         if "identity" in self.getTagNames(): | 
|  | 253             string += "(id: %i%%)" % (self.getTagValue("identity")) | 
|  | 254         if self.targetInterval.getSize() != None and self.queryInterval.getSize() != None and self.size != None: | 
|  | 255             string += "(sizes: %d, %d -> %d)" % (self.targetInterval.getSize(), self.queryInterval.getSize(), self.size) | 
|  | 256         return string | 
|  | 257 | 
|  | 258 |