|
9 | 9 | HGVSError, |
10 | 10 | HGVSInvalidVariantError, |
11 | 11 | HGVSUnsupportedOperationError, |
| 12 | + HGVSInvalidIntervalError, |
12 | 13 | ) |
13 | 14 | from hgvs.variantmapper import VariantMapper |
| 15 | +from hgvs.posedit import PosEdit |
| 16 | +from hgvs.edit import NARefAlt |
| 17 | +from hgvs.location import SimplePosition, Interval |
14 | 18 |
|
15 | 19 | _logger = logging.getLogger(__name__) |
16 | 20 |
|
@@ -172,7 +176,31 @@ def n_to_c(self, var_n): |
172 | 176 | return self._maybe_normalize(var_out) |
173 | 177 |
|
174 | 178 | def c_to_p(self, var_c): |
175 | | - var_out = super(AssemblyMapper, self).c_to_p(var_c) |
| 179 | + var_out = super(AssemblyMapper, self)._c_to_p(var_c) |
| 180 | + |
| 181 | + if ( |
| 182 | + var_c.posedit.edit.type in ['ins', 'dup'] |
| 183 | + and var_c.type in "cnr" |
| 184 | + and var_c.posedit.pos is not None |
| 185 | + and (var_c.posedit.pos.start.offset != 0 or var_c.posedit.pos.end.offset != 0) |
| 186 | + and var_out.posedit is None |
| 187 | + ): |
| 188 | + try: |
| 189 | + var_g = self.c_to_g(var_c) |
| 190 | + strand = self._fetch_AlignmentMapper(tx_ac=var_c.ac).strand |
| 191 | + |
| 192 | + for shuffle_direction in [3, 5]: |
| 193 | + shifted_var_g = self._far_shift(var_g, shuffle_direction, strand) |
| 194 | + shifted_var_c = super(AssemblyMapper, self).g_to_c( |
| 195 | + shifted_var_g, var_c.ac, alt_aln_method=self.alt_aln_method |
| 196 | + ) |
| 197 | + var_out = super(AssemblyMapper, self)._c_to_p(shifted_var_c) |
| 198 | + |
| 199 | + if var_out.posedit is not None: |
| 200 | + break |
| 201 | + except (HGVSInvalidVariantError, HGVSInvalidIntervalError, HGVSUnsupportedOperationError): |
| 202 | + pass |
| 203 | + |
176 | 204 | return self._maybe_normalize(var_out) |
177 | 205 |
|
178 | 206 | def relevant_transcripts(self, var_g): |
@@ -268,6 +296,34 @@ def _maybe_normalize(self, var): |
268 | 296 | # fall through to return unnormalized variant |
269 | 297 | return var |
270 | 298 |
|
| 299 | + def _far_shift(self, var_g, shuffle_direction, strand): |
| 300 | + """Attempt to shift a variant all the way left or right. Rewrite |
| 301 | + duplications as insertions so that the change is shifted as far as |
| 302 | + possible.""" |
| 303 | + normalizer = hgvs.normalizer.Normalizer( |
| 304 | + self._norm.hdp, alt_aln_method=self.alt_aln_method, validate=False, shuffle_direction=shuffle_direction |
| 305 | + ) |
| 306 | + shifted_var_g = normalizer.normalize(var_g) |
| 307 | + if shifted_var_g.posedit.edit.type == 'dup': |
| 308 | + self._replace_reference(shifted_var_g) |
| 309 | + if (strand == 1 and shuffle_direction == 3) or (strand == -1 and shuffle_direction == 5): |
| 310 | + shifted_var_g.posedit = PosEdit( |
| 311 | + pos=Interval( |
| 312 | + start=SimplePosition(base=shifted_var_g.posedit.pos.start.base-1), |
| 313 | + end=SimplePosition(base=shifted_var_g.posedit.pos.start.base), |
| 314 | + ), |
| 315 | + edit=NARefAlt(ref=None, alt=shifted_var_g.posedit.edit.ref) |
| 316 | + ) |
| 317 | + else: |
| 318 | + shifted_var_g.posedit = PosEdit( |
| 319 | + pos=Interval( |
| 320 | + start=SimplePosition(base=shifted_var_g.posedit.pos.end.base), |
| 321 | + end=SimplePosition(base=shifted_var_g.posedit.pos.end.base+1), |
| 322 | + ), |
| 323 | + edit=NARefAlt(ref=None, alt=shifted_var_g.posedit.edit.ref) |
| 324 | + ) |
| 325 | + return shifted_var_g |
| 326 | + |
271 | 327 |
|
272 | 328 | # <LICENSE> |
273 | 329 | # Copyright 2018 HGVS Contributors (https://github.com/biocommons/hgvs) |
|
0 commit comments