|
13 | 13 | HGVSUnsupportedOperationError, |
14 | 14 | ) |
15 | 15 | from hgvs.variantmapper import VariantMapper |
| 16 | +from hgvs.posedit import PosEdit |
| 17 | +from hgvs.edit import NARefAlt |
| 18 | +from hgvs.location import SimplePosition, Interval |
16 | 19 |
|
17 | 20 | _logger = logging.getLogger(__name__) |
18 | 21 |
|
@@ -180,17 +183,18 @@ def c_to_p(self, var_c): |
180 | 183 | and (var_c.posedit.pos.start.offset != 0 or var_c.posedit.pos.end.offset != 0) |
181 | 184 | and var_out.posedit is None |
182 | 185 | ): |
183 | | - if self._fetch_AlignmentMapper(tx_ac=var_c.ac).strand == 1: |
184 | | - normalizer = hgvs.normalizer.Normalizer( |
185 | | - self._norm.hdp, alt_aln_method=self.alt_aln_method, validate=False, shuffle_direction=5 |
186 | | - ) |
187 | | - else: |
188 | | - normalizer = hgvs.normalizer.Normalizer( |
189 | | - self._norm.hdp, alt_aln_method=self.alt_aln_method, validate=False, shuffle_direction=3 |
| 186 | + var_g = self.c_to_g(var_c) |
| 187 | + strand = self._fetch_AlignmentMapper(tx_ac=var_c.ac).strand |
| 188 | + |
| 189 | + for shuffle_direction in [3, 5]: |
| 190 | + shifted_var_g = self._far_shift(var_g, shuffle_direction, strand) |
| 191 | + shifted_var_c = super(AssemblyMapper, self).g_to_c( |
| 192 | + shifted_var_g, var_c.ac, alt_aln_method=self.alt_aln_method |
190 | 193 | ) |
191 | | - var_g = normalizer.normalize(self.c_to_g(var_c)) |
192 | | - var_c = self.g_to_c(var_g, var_c.ac) |
193 | | - var_out = super(AssemblyMapper, self)._c_to_p(var_c) |
| 194 | + var_out = super(AssemblyMapper, self)._c_to_p(shifted_var_c) |
| 195 | + |
| 196 | + if var_out.posedit is not None: |
| 197 | + break |
194 | 198 |
|
195 | 199 | return self._maybe_normalize(var_out) |
196 | 200 |
|
@@ -287,6 +291,34 @@ def _maybe_normalize(self, var): |
287 | 291 | # fall through to return unnormalized variant |
288 | 292 | return var |
289 | 293 |
|
| 294 | + def _far_shift(self, var_g, shuffle_direction, strand): |
| 295 | + """Attempt to shift a variant all the way left or right. Rewrite |
| 296 | + duplications as insertions so that the change is shifted as far as |
| 297 | + possible.""" |
| 298 | + normalizer = hgvs.normalizer.Normalizer( |
| 299 | + self._norm.hdp, alt_aln_method=self.alt_aln_method, validate=False, shuffle_direction=shuffle_direction |
| 300 | + ) |
| 301 | + shifted_var_g = normalizer.normalize(var_g) |
| 302 | + if shifted_var_g.posedit.edit.type == 'dup': |
| 303 | + self._replace_reference(shifted_var_g) |
| 304 | + if (strand == 1 and shuffle_direction == 3) or (strand == -1 and shuffle_direction == 5): |
| 305 | + shifted_var_g.posedit = PosEdit( |
| 306 | + pos=Interval( |
| 307 | + start=SimplePosition(base=shifted_var_g.posedit.pos.start.base-1), |
| 308 | + end=SimplePosition(base=shifted_var_g.posedit.pos.start.base), |
| 309 | + ), |
| 310 | + edit=NARefAlt(ref=None, alt=shifted_var_g.posedit.edit.ref) |
| 311 | + ) |
| 312 | + else: |
| 313 | + shifted_var_g.posedit = PosEdit( |
| 314 | + pos=Interval( |
| 315 | + start=SimplePosition(base=shifted_var_g.posedit.pos.end.base), |
| 316 | + end=SimplePosition(base=shifted_var_g.posedit.pos.end.base+1), |
| 317 | + ), |
| 318 | + edit=NARefAlt(ref=None, alt=shifted_var_g.posedit.edit.ref) |
| 319 | + ) |
| 320 | + return shifted_var_g |
| 321 | + |
290 | 322 |
|
291 | 323 | # <LICENSE> |
292 | 324 | # Copyright 2018 HGVS Contributors (https://github.com/biocommons/hgvs) |
|
0 commit comments