stcrpy 1.0.3__py3-none-any.whl → 1.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stcrpy/__init__.py +1 -1
- stcrpy/tcr_formats/tcr_formats.py +20 -1
- stcrpy/tcr_geometry/TCRAngle.py +177 -0
- stcrpy/tcr_geometry/reference_data/Acoreset.txt +30 -0
- stcrpy/tcr_geometry/reference_data/Bcoreset.txt +30 -0
- stcrpy/tcr_geometry/reference_data/consensus_A.pdb +31 -0
- stcrpy/tcr_geometry/reference_data/consensus_B.pdb +31 -0
- stcrpy/tcr_geometry/reference_data/consensus_D.pdb +31 -0
- stcrpy/tcr_geometry/reference_data/consensus_G.pdb +31 -0
- stcrpy/tcr_geometry/reference_data/pcA.txt +3 -0
- stcrpy/tcr_geometry/reference_data/pcB.txt +3 -0
- stcrpy/tcr_interactions/TCRInteractionProfiler.py +8 -1
- stcrpy/tcr_methods/tcr_batch_operations.py +14 -10
- stcrpy/tcr_methods/tcr_methods.py +23 -22
- stcrpy/tcr_metrics/tcr_dockq.py +404 -0
- stcrpy/tcr_processing/MHC.py +389 -4
- stcrpy/tcr_processing/TCR.py +252 -0
- stcrpy/tcr_processing/TCRParser.py +351 -189
- stcrpy/tcr_processing/annotate.py +6 -1
- stcrpy/tcr_processing/utils/region_definitions.py +9 -0
- stcrpy/tcr_processing/utils/symmetry_mates.py +96 -0
- stcrpy-1.0.6.dist-info/METADATA +286 -0
- {stcrpy-1.0.3.dist-info → stcrpy-1.0.6.dist-info}/RECORD +27 -16
- {stcrpy-1.0.3.dist-info → stcrpy-1.0.6.dist-info}/WHEEL +1 -1
- stcrpy-1.0.3.dist-info/METADATA +0 -173
- {stcrpy-1.0.3.dist-info → stcrpy-1.0.6.dist-info}/licenses/LICENCE +0 -0
- {stcrpy-1.0.3.dist-info → stcrpy-1.0.6.dist-info}/licenses/stcrpy/tcr_geometry/TCRCoM_LICENCE +0 -0
- {stcrpy-1.0.3.dist-info → stcrpy-1.0.6.dist-info}/top_level.txt +0 -0
stcrpy/tcr_processing/TCR.py
CHANGED
|
@@ -7,7 +7,11 @@ The TCR class.
|
|
|
7
7
|
import sys
|
|
8
8
|
import warnings
|
|
9
9
|
|
|
10
|
+
from Bio import BiopythonWarning
|
|
11
|
+
|
|
10
12
|
from .Entity import Entity
|
|
13
|
+
from .TCRchain import TCRchain
|
|
14
|
+
from .utils.region_definitions import IMGT_VARIABLE_DOMAIN
|
|
11
15
|
|
|
12
16
|
try:
|
|
13
17
|
from .. import tcr_interactions
|
|
@@ -18,6 +22,10 @@ except ImportError as e:
|
|
|
18
22
|
print(e)
|
|
19
23
|
|
|
20
24
|
|
|
25
|
+
class TCRError(Exception):
|
|
26
|
+
"""Error raised when there is an issue with the TCR."""
|
|
27
|
+
|
|
28
|
+
|
|
21
29
|
class TCR(Entity):
|
|
22
30
|
"""
|
|
23
31
|
TCR class. Inherits from PDB.Entity.
|
|
@@ -49,6 +57,24 @@ class TCR(Entity):
|
|
|
49
57
|
if set(mhc.antigen) - set(self.antigen):
|
|
50
58
|
self.antigen.extend(mhc.antigen)
|
|
51
59
|
|
|
60
|
+
def copy(self, copy_siblings = True ):
|
|
61
|
+
"""
|
|
62
|
+
Return a copy of the TCR object. This returns a shallow copy of the TCR object.
|
|
63
|
+
If the copy_siblings flag is set to True, the antigen and MHC objects will also be copied. Warning - if the copy_siblings flag is set to False, the antigen and MHC objects will not be copied, and the reference will still point to the same MHC and antigen objects as the original.
|
|
64
|
+
|
|
65
|
+
copy_siblings: Whether to copy sibling entities (ie. MHC and Antigen objects). Default True.
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
shallow = super().copy()
|
|
69
|
+
if copy_siblings:
|
|
70
|
+
shallow.antigen = [a.copy() for a in self.get_antigen()]
|
|
71
|
+
shallow.MHC = [m.copy(copy_siblings=False) for m in self.get_MHC()]
|
|
72
|
+
for m in shallow.MHC:
|
|
73
|
+
m.tcr = [t.copy(copy_siblings=False) if t.id != shallow.id else shallow for t in m.tcr]
|
|
74
|
+
m.antigen = [ag.copy() if ag.id not in [a.id for a in shallow.antigen] else [a for a in shallow.antigen if a.id==ag.id][0] for ag in m.antigen]
|
|
75
|
+
|
|
76
|
+
return shallow
|
|
77
|
+
|
|
52
78
|
def get_antigen(self):
|
|
53
79
|
"""
|
|
54
80
|
Return a list of TCR associated antigens.
|
|
@@ -224,6 +250,25 @@ class TCR(Entity):
|
|
|
224
250
|
|
|
225
251
|
return germlines_and_alleles
|
|
226
252
|
|
|
253
|
+
def get_chain_mapping(self):
|
|
254
|
+
"""Get a dictionary of chain IDs to chain types.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
dict: Dictionary of chain IDs to chain types
|
|
258
|
+
"""
|
|
259
|
+
tcr_chain_mapping = {v: k for k, v in self.get_domain_assignment().items()}
|
|
260
|
+
antigen_chain_mapping = {c.id: "Ag" for c in self.get_antigen()}
|
|
261
|
+
mhc_chain_mapping = {
|
|
262
|
+
c.id: c.chain_type for m in self.get_MHC() for c in m.get_chains()
|
|
263
|
+
}
|
|
264
|
+
chain_mapping = {
|
|
265
|
+
**tcr_chain_mapping,
|
|
266
|
+
**antigen_chain_mapping,
|
|
267
|
+
**mhc_chain_mapping,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return chain_mapping
|
|
271
|
+
|
|
227
272
|
def save(self, save_as=None, tcr_only: bool = False, format: str = "pdb"):
|
|
228
273
|
"""Save TCR object as PDB or MMCIF file.
|
|
229
274
|
|
|
@@ -384,6 +429,44 @@ class TCR(Entity):
|
|
|
384
429
|
def profile_MHC_interactions(self):
|
|
385
430
|
raise NotImplementedError
|
|
386
431
|
|
|
432
|
+
def get_TCR_angles(self):
|
|
433
|
+
from ..tcr_geometry.TCRAngle import TCRAngle
|
|
434
|
+
|
|
435
|
+
return TCRAngle().calculate_angles(self)
|
|
436
|
+
|
|
437
|
+
def crop(self, *, crop_mhc: bool = True, remove_het_atoms: bool = True) -> None:
|
|
438
|
+
"""Crop TCR to variable domain and optionally crop MHC to antigen binding domain.
|
|
439
|
+
|
|
440
|
+
This method mutates the TCR object.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
crop_mhc: crop mhc to antigen binding domain
|
|
444
|
+
remove_het_atoms: remove het atoms from structure as well
|
|
445
|
+
|
|
446
|
+
"""
|
|
447
|
+
new_child_dict = {}
|
|
448
|
+
for chain in self:
|
|
449
|
+
new_chain = TCRchain(chain.id)
|
|
450
|
+
|
|
451
|
+
for residue in chain:
|
|
452
|
+
if residue.id[1] in IMGT_VARIABLE_DOMAIN or (not remove_het_atoms and residue.id[0] != ' '):
|
|
453
|
+
new_chain.add(residue.copy())
|
|
454
|
+
|
|
455
|
+
new_chain.analyse(chain.chain_type)
|
|
456
|
+
new_chain.set_engineered(chain.engineered)
|
|
457
|
+
new_chain.xtra.update(chain.xtra)
|
|
458
|
+
new_child_dict[new_chain.id] = new_chain
|
|
459
|
+
|
|
460
|
+
for chain_id in new_child_dict:
|
|
461
|
+
del self[chain_id]
|
|
462
|
+
|
|
463
|
+
for new_chain in new_child_dict.values():
|
|
464
|
+
self.add(new_chain)
|
|
465
|
+
|
|
466
|
+
if crop_mhc:
|
|
467
|
+
for mhc in self.get_MHC():
|
|
468
|
+
mhc.crop(remove_het_atoms=remove_het_atoms)
|
|
469
|
+
|
|
387
470
|
def _create_interaction_visualiser(self):
|
|
388
471
|
"""Function called during TCR initialisation checks if pymol is installed and assigns a visualisation method accordingly.
|
|
389
472
|
If pymol is installed, method to generate interaction visualisations is returned.
|
|
@@ -446,6 +529,25 @@ class TCR(Entity):
|
|
|
446
529
|
|
|
447
530
|
return visualise_interactions
|
|
448
531
|
|
|
532
|
+
def standardise_chain_names(self):
|
|
533
|
+
"""Raises NotImplementedError."""
|
|
534
|
+
raise NotImplementedError()
|
|
535
|
+
|
|
536
|
+
def _validate_chain_standardising(self) -> None:
|
|
537
|
+
if (hasattr(self, 'antigen') and len(self.antigen) > 1) or (hasattr(self, 'MHC') and len(self.MHC) > 1):
|
|
538
|
+
msg = 'More than one antigen or MHC molecule is not currently supported for standardising.'
|
|
539
|
+
raise TCRError(msg)
|
|
540
|
+
|
|
541
|
+
def _standardise_antigen_chain_names(self) -> None:
|
|
542
|
+
"""Will give the antigen the chain id C. Does not support multiple antigens."""
|
|
543
|
+
with warnings.catch_warnings():
|
|
544
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
545
|
+
self.antigen[0].id = 'C'
|
|
546
|
+
|
|
547
|
+
def _standardise_mhc_chain_names(self) -> None:
|
|
548
|
+
"""Will give the MHC first chain id A and second chain B. Does not support more than one MHC molecule."""
|
|
549
|
+
self.MHC[0].standardise_chain_names()
|
|
550
|
+
|
|
449
551
|
|
|
450
552
|
class abTCR(TCR):
|
|
451
553
|
"""
|
|
@@ -575,6 +677,56 @@ class abTCR(TCR):
|
|
|
575
677
|
for frag in var_domain.get_fragments():
|
|
576
678
|
yield frag
|
|
577
679
|
|
|
680
|
+
def standardise_chain_names(self) -> None:
|
|
681
|
+
"""
|
|
682
|
+
Standardise the TCR, antigen, and MHC chain names to the following convention.
|
|
683
|
+
|
|
684
|
+
Convention:
|
|
685
|
+
- A - MHC chain 1
|
|
686
|
+
- B - MHC chain 2 (eg B2M)
|
|
687
|
+
- C - antigen chain
|
|
688
|
+
- D - TCR alpha chain
|
|
689
|
+
- E - TCR beta chain
|
|
690
|
+
|
|
691
|
+
Note, this mutates the original object.
|
|
692
|
+
|
|
693
|
+
Raises:
|
|
694
|
+
TCRError: if there is more than one antigen or MHC molecules attached to the TCR.
|
|
695
|
+
|
|
696
|
+
"""
|
|
697
|
+
self._validate_chain_standardising()
|
|
698
|
+
|
|
699
|
+
new_id = []
|
|
700
|
+
new_child_dict = {}
|
|
701
|
+
|
|
702
|
+
if hasattr(self, 'VB'):
|
|
703
|
+
new_child_dict['E'] = self.child_dict[self.VB]
|
|
704
|
+
self.VB = 'E'
|
|
705
|
+
new_id.append('E')
|
|
706
|
+
|
|
707
|
+
if hasattr(self, 'VA'):
|
|
708
|
+
new_child_dict['D'] = self.child_dict[self.VA]
|
|
709
|
+
self.VA = 'D'
|
|
710
|
+
new_id.append('D')
|
|
711
|
+
|
|
712
|
+
with warnings.catch_warnings():
|
|
713
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
714
|
+
|
|
715
|
+
for chain_id, chain in new_child_dict.items():
|
|
716
|
+
chain.id = chain_id
|
|
717
|
+
|
|
718
|
+
self.child_dict = new_child_dict
|
|
719
|
+
|
|
720
|
+
if hasattr(self, 'antigen') and self.antigen:
|
|
721
|
+
self._standardise_antigen_chain_names()
|
|
722
|
+
|
|
723
|
+
if hasattr(self, 'MHC') and self.MHC:
|
|
724
|
+
self._standardise_mhc_chain_names()
|
|
725
|
+
|
|
726
|
+
with warnings.catch_warnings():
|
|
727
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
728
|
+
self.id = ''.join(new_id)
|
|
729
|
+
|
|
578
730
|
|
|
579
731
|
class gdTCR(TCR):
|
|
580
732
|
|
|
@@ -651,6 +803,56 @@ class gdTCR(TCR):
|
|
|
651
803
|
for frag in var_domain.get_fragments():
|
|
652
804
|
yield frag
|
|
653
805
|
|
|
806
|
+
def standardise_chain_names(self) -> None:
|
|
807
|
+
"""
|
|
808
|
+
Standardise the TCR, antigen, and MHC chain names to the following convention.
|
|
809
|
+
|
|
810
|
+
Convention:
|
|
811
|
+
- A - MHC chain 1
|
|
812
|
+
- B - MHC chain 2 (eg B2M)
|
|
813
|
+
- C - antigen chain
|
|
814
|
+
- D - TCR delta chain
|
|
815
|
+
- E - TCR gamma chain
|
|
816
|
+
|
|
817
|
+
Note, this mutates the original object.
|
|
818
|
+
|
|
819
|
+
Raises:
|
|
820
|
+
TCRError: if there is more than one antigen or MHC molecules attached to the TCR.
|
|
821
|
+
|
|
822
|
+
"""
|
|
823
|
+
self._validate_chain_standardising()
|
|
824
|
+
|
|
825
|
+
new_id = []
|
|
826
|
+
new_child_dict = {}
|
|
827
|
+
|
|
828
|
+
if hasattr(self, 'VG'):
|
|
829
|
+
new_child_dict['E'] = self.child_dict[self.VG]
|
|
830
|
+
self.VG = 'E'
|
|
831
|
+
new_id.append('E')
|
|
832
|
+
|
|
833
|
+
if hasattr(self, 'VD'):
|
|
834
|
+
new_child_dict['D'] = self.child_dict[self.VD]
|
|
835
|
+
self.VD = 'D'
|
|
836
|
+
new_id.append('D')
|
|
837
|
+
|
|
838
|
+
with warnings.catch_warnings():
|
|
839
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
840
|
+
|
|
841
|
+
for chain_id, chain in new_child_dict.items():
|
|
842
|
+
chain.id = chain_id
|
|
843
|
+
|
|
844
|
+
self.child_dict = new_child_dict
|
|
845
|
+
|
|
846
|
+
if hasattr(self, 'antigen') and self.antigen:
|
|
847
|
+
self._standardise_antigen_chain_names()
|
|
848
|
+
|
|
849
|
+
if hasattr(self, 'MHC') and self.MHC:
|
|
850
|
+
self._standardise_mhc_chain_names()
|
|
851
|
+
|
|
852
|
+
with warnings.catch_warnings():
|
|
853
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
854
|
+
self.id = ''.join(new_id)
|
|
855
|
+
|
|
654
856
|
|
|
655
857
|
class dbTCR(TCR):
|
|
656
858
|
def __init__(self, c1, c2):
|
|
@@ -726,3 +928,53 @@ class dbTCR(TCR):
|
|
|
726
928
|
if var_domain:
|
|
727
929
|
for frag in var_domain.get_fragments():
|
|
728
930
|
yield frag
|
|
931
|
+
|
|
932
|
+
def standardise_chain_names(self) -> None:
|
|
933
|
+
"""
|
|
934
|
+
Standardise the TCR, antigen, and MHC chain names to the following convention.
|
|
935
|
+
|
|
936
|
+
Convention:
|
|
937
|
+
- A - MHC chain 1
|
|
938
|
+
- B - MHC chain 2 (eg B2M)
|
|
939
|
+
- C - antigen chain
|
|
940
|
+
- D - TCR delta chain
|
|
941
|
+
- E - TCR beta chain
|
|
942
|
+
|
|
943
|
+
Note, this mutates the original object.
|
|
944
|
+
|
|
945
|
+
Raises:
|
|
946
|
+
TCRError: if there is more than one antigen or MHC molecules attached to the TCR.
|
|
947
|
+
|
|
948
|
+
"""
|
|
949
|
+
self._validate_chain_standardising()
|
|
950
|
+
|
|
951
|
+
new_id = []
|
|
952
|
+
new_child_dict = {}
|
|
953
|
+
|
|
954
|
+
if hasattr(self, 'VB'):
|
|
955
|
+
new_child_dict['E'] = self.child_dict[self.VB]
|
|
956
|
+
self.VB = 'E'
|
|
957
|
+
new_id.append('E')
|
|
958
|
+
|
|
959
|
+
if hasattr(self, 'VD'):
|
|
960
|
+
new_child_dict['D'] = self.child_dict[self.VD]
|
|
961
|
+
self.VD = 'D'
|
|
962
|
+
new_id.append('D')
|
|
963
|
+
|
|
964
|
+
with warnings.catch_warnings():
|
|
965
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
966
|
+
|
|
967
|
+
for chain_id, chain in new_child_dict.items():
|
|
968
|
+
chain.id = chain_id
|
|
969
|
+
|
|
970
|
+
self.child_dict = new_child_dict
|
|
971
|
+
|
|
972
|
+
if hasattr(self, 'antigen') and self.antigen:
|
|
973
|
+
self._standardise_antigen_chain_names()
|
|
974
|
+
|
|
975
|
+
if hasattr(self, 'MHC') and self.MHC:
|
|
976
|
+
self._standardise_mhc_chain_names()
|
|
977
|
+
|
|
978
|
+
with warnings.catch_warnings():
|
|
979
|
+
warnings.simplefilter('ignore', BiopythonWarning)
|
|
980
|
+
self.id = ''.join(new_id)
|