p2s_mapper 1.4.0 → 2.1.0

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.
Files changed (134) hide show
  1. package/README.md +220 -39
  2. package/dist/alignmentQuality.d.ts +5 -5
  3. package/dist/alphaFoldModels.d.ts +4 -4
  4. package/dist/alphaFoldModels.js +4 -4
  5. package/dist/chooseMappedEntity.d.ts +11 -13
  6. package/dist/chooseMappedEntity.js +9 -12
  7. package/dist/chooseMappedEntity.js.map +1 -1
  8. package/dist/coordinates.d.ts +19 -19
  9. package/dist/coordinates.js.map +1 -1
  10. package/dist/dbIds.d.ts +1 -2
  11. package/dist/extractPerResidueConfidence.d.ts +1 -2
  12. package/dist/extractStructureSequences.d.ts +26 -34
  13. package/dist/extractStructureSequences.js +2 -2
  14. package/dist/extractStructureSequences.js.map +1 -1
  15. package/dist/fetchUtils.d.ts +7 -7
  16. package/dist/fetchUtils.js +26 -8
  17. package/dist/fetchUtils.js.map +1 -1
  18. package/dist/index.d.ts +1 -3
  19. package/dist/index.js +2 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/isoformRanking.d.ts +4 -1
  22. package/dist/mappings.d.ts +9 -12
  23. package/dist/mappings.js +4 -5
  24. package/dist/mappings.js.map +1 -1
  25. package/dist/pairwiseAlignment.d.ts +5 -4
  26. package/dist/pairwiseAlignment.js +9 -7
  27. package/dist/pairwiseAlignment.js.map +1 -1
  28. package/dist/pdbEntry.d.ts +32 -0
  29. package/dist/pdbEntry.js +182 -0
  30. package/dist/pdbEntry.js.map +1 -0
  31. package/dist/pdbUniProtMapping.d.ts +14 -39
  32. package/dist/pdbUniProtMapping.js +22 -140
  33. package/dist/pdbUniProtMapping.js.map +1 -1
  34. package/dist/structureFormat.d.ts +11 -18
  35. package/dist/structureFormat.js +4 -6
  36. package/dist/structureFormat.js.map +1 -1
  37. package/dist/structureSources.d.ts +37 -13
  38. package/dist/structureSources.js +144 -57
  39. package/dist/structureSources.js.map +1 -1
  40. package/dist/structureUrls.d.ts +13 -16
  41. package/dist/structureUrls.js +25 -23
  42. package/dist/structureUrls.js.map +1 -1
  43. package/dist/types.d.ts +2 -5
  44. package/dist/types.js +2 -5
  45. package/dist/types.js.map +1 -1
  46. package/dist/uniProtSearch.js +3 -8
  47. package/dist/uniProtSearch.js.map +1 -1
  48. package/esm/alignmentQuality.d.ts +5 -5
  49. package/esm/alphaFoldModels.d.ts +4 -4
  50. package/esm/alphaFoldModels.js +4 -4
  51. package/esm/chooseMappedEntity.d.ts +11 -13
  52. package/esm/chooseMappedEntity.js +9 -12
  53. package/esm/chooseMappedEntity.js.map +1 -1
  54. package/esm/coordinates.d.ts +19 -19
  55. package/esm/coordinates.js.map +1 -1
  56. package/esm/dbIds.d.ts +1 -2
  57. package/esm/extractPerResidueConfidence.d.ts +1 -2
  58. package/esm/extractStructureSequences.d.ts +26 -34
  59. package/esm/extractStructureSequences.js +2 -2
  60. package/esm/extractStructureSequences.js.map +1 -1
  61. package/esm/fetchUtils.d.ts +7 -7
  62. package/esm/fetchUtils.js +26 -8
  63. package/esm/fetchUtils.js.map +1 -1
  64. package/esm/index.d.ts +1 -3
  65. package/esm/index.js +2 -4
  66. package/esm/index.js.map +1 -1
  67. package/esm/isoformRanking.d.ts +4 -1
  68. package/esm/mappings.d.ts +9 -12
  69. package/esm/mappings.js +4 -5
  70. package/esm/mappings.js.map +1 -1
  71. package/esm/pairwiseAlignment.d.ts +5 -4
  72. package/esm/pairwiseAlignment.js +7 -5
  73. package/esm/pairwiseAlignment.js.map +1 -1
  74. package/esm/pdbEntry.d.ts +32 -0
  75. package/esm/pdbEntry.js +174 -0
  76. package/esm/pdbEntry.js.map +1 -0
  77. package/esm/pdbUniProtMapping.d.ts +14 -39
  78. package/esm/pdbUniProtMapping.js +22 -137
  79. package/esm/pdbUniProtMapping.js.map +1 -1
  80. package/esm/structureFormat.d.ts +11 -18
  81. package/esm/structureFormat.js +4 -6
  82. package/esm/structureFormat.js.map +1 -1
  83. package/esm/structureSources.d.ts +37 -13
  84. package/esm/structureSources.js +139 -55
  85. package/esm/structureSources.js.map +1 -1
  86. package/esm/structureUrls.d.ts +13 -16
  87. package/esm/structureUrls.js +23 -23
  88. package/esm/structureUrls.js.map +1 -1
  89. package/esm/types.d.ts +2 -5
  90. package/esm/types.js +2 -5
  91. package/esm/types.js.map +1 -1
  92. package/esm/uniProtSearch.js +3 -8
  93. package/esm/uniProtSearch.js.map +1 -1
  94. package/package.json +3 -2
  95. package/src/alignmentQuality.ts +5 -5
  96. package/src/alphaFoldModels.ts +4 -4
  97. package/src/chooseMappedEntity.ts +12 -15
  98. package/src/coordinates.ts +14 -17
  99. package/src/dbIds.ts +1 -1
  100. package/src/extractPerResidueConfidence.ts +1 -1
  101. package/src/extractStructureSequences.ts +26 -33
  102. package/src/fetchUtils.ts +30 -8
  103. package/src/index.ts +2 -4
  104. package/src/isoformRanking.ts +4 -4
  105. package/src/mappings.ts +9 -12
  106. package/src/pairwiseAlignment.ts +12 -9
  107. package/src/pdbEntry.ts +240 -0
  108. package/src/pdbUniProtMapping.ts +25 -164
  109. package/src/structureFormat.ts +11 -18
  110. package/src/structureSources.ts +194 -70
  111. package/src/structureUrls.ts +25 -23
  112. package/src/types.ts +2 -5
  113. package/src/uniProtSearch.ts +3 -8
  114. package/dist/pdbeBestStructures.d.ts +0 -23
  115. package/dist/pdbeBestStructures.js +0 -79
  116. package/dist/pdbeBestStructures.js.map +0 -1
  117. package/dist/pdbeEntryMolecules.d.ts +0 -7
  118. package/dist/pdbeEntryMolecules.js +0 -39
  119. package/dist/pdbeEntryMolecules.js.map +0 -1
  120. package/dist/siftsNumbering.d.ts +0 -23
  121. package/dist/siftsNumbering.js +0 -44
  122. package/dist/siftsNumbering.js.map +0 -1
  123. package/esm/pdbeBestStructures.d.ts +0 -23
  124. package/esm/pdbeBestStructures.js +0 -73
  125. package/esm/pdbeBestStructures.js.map +0 -1
  126. package/esm/pdbeEntryMolecules.d.ts +0 -7
  127. package/esm/pdbeEntryMolecules.js +0 -35
  128. package/esm/pdbeEntryMolecules.js.map +0 -1
  129. package/esm/siftsNumbering.d.ts +0 -23
  130. package/esm/siftsNumbering.js +0 -40
  131. package/esm/siftsNumbering.js.map +0 -1
  132. package/src/pdbeBestStructures.ts +0 -94
  133. package/src/pdbeEntryMolecules.ts +0 -37
  134. package/src/siftsNumbering.ts +0 -61
package/README.md CHANGED
@@ -1,28 +1,17 @@
1
1
  # p2s_mapper
2
2
 
3
- Map a transcript's translation onto a protein structure.
4
-
5
- - **Align** the transcript to the structure's sequence (Smith-Waterman or
6
- Needleman-Wunsch, BLOSUM62)
7
- - **Convert coordinates** both ways between transcript, alignment, structure,
8
- Mol\* and UniProt numbering
9
- - **Choose the chain** that best matches the gene's protein
10
- - **Use SIFTS** to place UniProt annotations and drop fusion-partner residues
11
- - **Find structures** through AlphaFold, 3D-Beacons, PDBe and UniProt
12
-
13
- ## Works with g2p_mapper
14
-
15
- p2s_mapper covers **protein ↔ structure**. The other half, **genome ↔ protein**,
16
- is [g2p_mapper](https://github.com/GMOD/g2p_mapper): it turns a transcript's CDS
17
- into per-codon genome positions, on either strand and across exon boundaries. It
18
- is p2s_mapper's only runtime dependency, and chaining the two takes you from a
19
- genome coordinate to a residue in 3D and back.
20
-
21
- Extracted from
22
- [jbrowse-plugin-protein3d](https://github.com/GMOD/jbrowse-plugin-protein3d),
23
- where we made the measurements behind the scoring rules. The package has no
24
- React, JBrowse or Mol\* dependency: a loaded Mol\* model reaches it through
25
- narrow structural interfaces.
3
+ Lines up a protein sequence with its 3D structure, residue by residue.
4
+
5
+ - **In:** a protein sequence, and an AlphaFold or PDB structure
6
+ - **Out:** which 3D residue each amino acid is, and back
7
+ - Picks the right chain and flags a poor match
8
+ - Finds structures for a gene
9
+ - Places UniProt annotations on a PDB entry
10
+ - With [g2p_mapper](https://github.com/GMOD/g2p_mapper): genome position ↔ 3D
11
+ residue
12
+ - No React, JBrowse or Mol\* dependency
13
+ - Used by
14
+ [jbrowse-plugin-protein3d](https://github.com/GMOD/jbrowse-plugin-protein3d)
26
15
 
27
16
  ## Install
28
17
 
@@ -30,28 +19,220 @@ narrow structural interfaces.
30
19
  npm install p2s_mapper
31
20
  ```
32
21
 
33
- ## How it fits together
22
+ ## Usage
23
+
24
+ ### Map a transcript onto a structure
25
+
26
+ Pass the transcript's translation and the structure's chain sequences.
27
+ `chooseMappedEntity` picks the chain, `isLowSimilarity` checks the match is not
28
+ chance, and `makeCoordinateMapper` converts positions both ways.
29
+
30
+ ```ts
31
+ import {
32
+ alignmentQuality,
33
+ chooseMappedEntity,
34
+ describeAlignmentQuality,
35
+ isLowSimilarity,
36
+ makeCoordinateMapper,
37
+ structurePos,
38
+ transcriptPos,
39
+ } from 'p2s_mapper'
40
+
41
+ // p53's N-terminus, and a structure holding a DNA strand and a tagged fragment
42
+ const transcript = 'MEEPQSDPSVEPPLSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQWFTEDP*'
43
+ const chains = [
44
+ { seq: 'TTTCCTAGACTTGCCCAATTA', nucleicAcid: true },
45
+ { seq: 'GSHMSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQW' },
46
+ ]
47
+
48
+ const picked = chooseMappedEntity(transcript, chains, 'smith_waterman')
49
+ if (picked) {
50
+ picked.index // 1: the protein chain
51
+
52
+ const quality = alignmentQuality(picked.alignment)
53
+ isLowSimilarity(quality) // false
54
+ describeAlignmentQuality(quality)
55
+ // '98% identity over 40 of 43 structure residues'
56
+
57
+ const mapper = makeCoordinateMapper(picked.alignment)
58
+ mapper.transcriptToStructure(transcriptPos(16)) // 6
59
+ mapper.structureToTranscript(structurePos(6)) // 16
60
+ mapper.structureToTranscript(structurePos(0)) // undefined: the GSH tag
61
+ }
62
+ ```
63
+
64
+ Every position is 0-based. Structure and transcript positions are separate
65
+ types, so passing one where the other belongs is a compile error.
66
+
67
+ ### From a genome position to a residue, and back
68
+
69
+ g2p_mapper maps genome positions to protein positions. p2s_mapper maps a protein
70
+ position to a structure position, and that to the `label_seq_id` Mol\* uses to
71
+ select a residue.
72
+
73
+ ```ts
74
+ import { genomeToTranscriptSeqMapping } from 'g2p_mapper'
75
+ import {
76
+ chooseMappedEntity,
77
+ codonGenomeSpan,
78
+ makeCoordinateMapper,
79
+ makeLabelSeqIdIndex,
80
+ residueNumber,
81
+ structurePos,
82
+ toLabelSeqIds,
83
+ transcriptPos,
84
+ } from 'p2s_mapper'
85
+ import type { Entity } from 'p2s_mapper'
86
+
87
+ const transcript = 'MEEPQSDPSVEPPLSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQWFTEDP*'
88
+ const { g2p, p2gCodon } = genomeToTranscriptSeqMapping({
89
+ refName: 'chr17',
90
+ start: 1000,
91
+ end: 2117,
92
+ strand: 1,
93
+ subfeatures: [
94
+ { refName: 'chr17', start: 1000, end: 1060, type: 'CDS', phase: 0 },
95
+ { refName: 'chr17', start: 2000, end: 2117, type: 'CDS' },
96
+ ],
97
+ })
98
+
99
+ // normally from extractEntities(model); here the author numbering starts at 12
100
+ const entity: Entity = {
101
+ entityId: '1',
102
+ seq: 'GSHMSQETFSDLWKLLPENNVLSPLPSQAMDDLMLSPDDIEQW',
103
+ seqIds: Array.from({ length: 43 }, (_, i) => i + 1),
104
+ authSeqIds: Array.from({ length: 43 }, (_, i) => i + 12),
105
+ chains: ['A'],
106
+ }
107
+ const picked = chooseMappedEntity(transcript, [entity], 'smith_waterman')!
108
+ const mapper = makeCoordinateMapper(picked.alignment)
109
+
110
+ // genome -> structure
111
+ const proteinPos = g2p[2000] // 20
112
+ if (proteinPos !== undefined) {
113
+ const pos = mapper.transcriptToStructure(transcriptPos(proteinPos)) // 10
114
+ if (pos !== undefined) {
115
+ toLabelSeqIds(entity, [pos]) // [11]: what to highlight in Mol*
116
+ residueNumber(entity, pos) // 22: what to show the user
117
+ }
118
+ }
119
+
120
+ // a Mol* hover on label_seq_id 15 -> genome
121
+ const hovered = makeLabelSeqIdIndex(entity).get(15) // 14
122
+ if (hovered !== undefined) {
123
+ const t = mapper.structureToTranscript(structurePos(hovered)) // 24
124
+ if (t !== undefined) {
125
+ codonGenomeSpan(p2gCodon, t) // [2012, 2015]
126
+ }
127
+ }
128
+ ```
129
+
130
+ ### With a structure loaded in Mol\*
131
+
132
+ `extractEntities` reads each chain's sequence, residue ids and numbering from a
133
+ loaded Mol\* model. `StructureModel` lists the fields it reads, so the package
134
+ needs no Mol\* import.
135
+
136
+ ```ts
137
+ import {
138
+ chooseMappedEntity,
139
+ extractEntities,
140
+ rangeToLabelSeqIds,
141
+ } from 'p2s_mapper'
142
+ import type { StructureModel } from 'p2s_mapper'
143
+
144
+ // e.g. what plugin.builders.structure.createModel resolves to
145
+ declare const model: StructureModel
146
+ declare const transcript: string
147
+
148
+ const entities = extractEntities(model) ?? []
149
+ const picked = chooseMappedEntity(transcript, entities, 'smith_waterman')
150
+ const entity = picked ? entities[picked.index] : undefined
151
+
152
+ // the label_seq_ids of structure positions 10-19, for a Mol* selection
153
+ rangeToLabelSeqIds(entity, { start: 10, end: 20 })
154
+ ```
155
+
156
+ ### Find a structure for a gene
157
+
158
+ ```ts
159
+ import {
160
+ fetchAlphaFoldModels,
161
+ fetchExperimentalStructures,
162
+ getPdbStructureUrl,
163
+ pickAlphaFoldModel,
164
+ searchUniProtEntries,
165
+ } from 'p2s_mapper'
166
+
167
+ declare const translation: string
168
+
169
+ const { entries } = await searchUniProtEntries({
170
+ recognizedIds: ['GeneID:7157', 'ENST00000269305'],
171
+ geneName: 'TP53',
172
+ organismId: 9606,
173
+ })
174
+ const accession = entries[0]?.accession // 'P04637'
175
+
176
+ if (accession) {
177
+ // predicted: the model folded from this exact translation, else the canonical one
178
+ const models = await fetchAlphaFoldModels(accession)
179
+ const predicted = pickAlphaFoldModel(models, { tx1: { seq: translation } })
180
+
181
+ // experimental: PDB entries, best coverage first
182
+ const [best] = await fetchExperimentalStructures(accession)
183
+ const url = predicted?.url ?? (best && getPdbStructureUrl(best.pdbId))
184
+ }
185
+ ```
186
+
187
+ Every network function takes `{ fetch?, signal? }` last, defaulting to
188
+ `globalThis.fetch`, so the caller can pass a custom fetch and an `AbortSignal`.
189
+
190
+ ### Place UniProt annotations on a PDB entry
191
+
192
+ A PDB construct is usually a fragment, numbered differently from UniProt.
193
+ `fetchUniProtStructureMappings` reads the entry's alignment to UniProt from
194
+ RCSB.
195
+
196
+ ```ts
197
+ import {
198
+ chooseUniProtMappingForEntity,
199
+ fetchUniProtStructureMappings,
200
+ makeUniProtPositionMap,
201
+ } from 'p2s_mapper'
202
+
203
+ const mappings = await fetchUniProtStructureMappings('1tup')
204
+ const mapping = chooseUniProtMappingForEntity(mappings, {
205
+ entityId: '3',
206
+ chains: ['A', 'B', 'C'],
207
+ })
208
+ const toStructure = makeUniProtPositionMap(mapping?.segments ?? [])
209
+ toStructure(248) // 154: UniProt residue 248 is structure position 154
210
+ ```
211
+
212
+ ## Pipeline
34
213
 
35
214
  ![From a gene on the genome to a residue in 3D, and back](docs/img/pipeline.svg)
36
215
 
37
216
  ## Docs
38
217
 
39
- - [faq.md](docs/faq.md) — can I trust the mapping? What the package checks, and
40
- what it leaves to you
41
- - [pipeline.md](docs/pipeline.md) — the flow above, step by step, and why chain
218
+ - [api.md](docs/api.md): every export, with its signature, types and an example
219
+ - [pipeline.md](docs/pipeline.md): the flow above, step by step, and why chain
42
220
  choice divides by the shorter sequence
43
- - [coordinates.md](docs/coordinates.md) — the four numberings of a residue and
44
- the one route between each
45
- - [api.md](docs/api.md) — every export, grouped by job
46
-
47
- ## Things to know first
48
-
49
- - Every coordinate in the API is **0-based**, branded by space so the compiler
50
- rejects mixing them. See [coordinates.md](docs/coordinates.md).
51
- - A `PairwiseAlignment` has **row 0 = transcript, row 1 = structure**. Use the
52
- accessors, not indexes.
53
- - Network functions take `{ fetch?, signal? }` and default to
54
- `globalThis.fetch`.
221
+ - [coordinates.md](docs/coordinates.md): the four ways a residue is numbered,
222
+ and which function converts between them
223
+ - [faq.md](docs/faq.md): can I trust the mapping? What the package checks, and
224
+ what it leaves to you
225
+
226
+ ## Pitfalls
227
+
228
+ - Positions are **0-based**, except UniProt positions and author residue
229
+ numbers, which are 1-based. See [coordinates.md](docs/coordinates.md).
230
+ - A `PairwiseAlignment` has **row 0 = transcript, row 1 = structure**. Read the
231
+ rows with `transcriptAlignedSeq` and `structureAlignedSeq`.
232
+ - `chooseMappedEntity` returns the best-matching chain even when the match is
233
+ poor. Check it with `isLowSimilarity` before trusting the mapping.
234
+ - Get Mol\*'s `label_seq_id` from `toLabelSeqIds`, which reads `Entity.seqIds`.
235
+ Adding 1 to the position gives the wrong residue in a PDB file without SEQRES.
55
236
 
56
237
  ## License
57
238
 
@@ -1,20 +1,20 @@
1
1
  import type { PairwiseAlignment } from './mappings.ts';
2
2
  export interface AlignmentQuality {
3
- /** columns carrying a residue on both rows, i.e. mapped positions */
3
+ /** columns with a residue in both rows, i.e. mapped positions */
4
4
  aligned: number;
5
5
  identical: number;
6
6
  transcriptLength: number;
7
7
  structureLength: number;
8
8
  /** identical over aligned; 0 when nothing aligned */
9
9
  identity: number;
10
- /** identical over the shorter of the two sequences: the statistic that
11
- * separates a real match from a chance local alignment, see below */
10
+ /** identical over the shorter of the two sequences, which separates a
11
+ * real match from a chance local alignment (see LOW_IDENTITY_OVER_SHORTER) */
12
12
  identityOverShorter: number;
13
13
  /** aligned over the structure's length */
14
14
  structureCoverage: number;
15
15
  /** first and last transcript residue the alignment covers, 1-based
16
- * inclusive; 0 when nothing aligned. A structure is usually a fragment, and
17
- * which part of the protein it holds is the reader's first question. */
16
+ * inclusive; 0 when nothing aligned. A structure is usually a fragment, so
17
+ * these show which part of the protein it contains. */
18
18
  transcriptStart: number;
19
19
  transcriptEnd: number;
20
20
  }
@@ -22,11 +22,11 @@ export declare function parseAlphaFoldModels(json: unknown): AlphaFoldModel[];
22
22
  export declare function fetchAlphaFoldModels(uniprotId: string, opts?: FetchOptions): Promise<AlphaFoldModel[]>;
23
23
  /**
24
24
  * The model to open for a gene's transcripts: one folded from exactly a
25
- * transcript's translation, canonical first, so the view maps it as an
26
- * identity; else the canonical model; else the longest isoform model.
25
+ * transcript's translation, canonical first, so every residue maps to itself;
26
+ * else the canonical model; else the longest isoform model.
27
27
  *
28
- * Takes any record of sequences, since the structure loader knows one
29
- * translation rather than a gene's isoforms.
28
+ * Takes any record of sequences, since a caller may know one translation rather
29
+ * than a gene's isoforms.
30
30
  */
31
31
  export declare function pickAlphaFoldModel(models: AlphaFoldModel[], isoformSequences: Record<string, {
32
32
  seq: string;
@@ -48,11 +48,11 @@ async function fetchAlphaFoldModels(uniprotId, opts) {
48
48
  }
49
49
  /**
50
50
  * The model to open for a gene's transcripts: one folded from exactly a
51
- * transcript's translation, canonical first, so the view maps it as an
52
- * identity; else the canonical model; else the longest isoform model.
51
+ * transcript's translation, canonical first, so every residue maps to itself;
52
+ * else the canonical model; else the longest isoform model.
53
53
  *
54
- * Takes any record of sequences, since the structure loader knows one
55
- * translation rather than a gene's isoforms.
54
+ * Takes any record of sequences, since a caller may know one translation rather
55
+ * than a gene's isoforms.
56
56
  */
57
57
  function pickAlphaFoldModel(models, isoformSequences) {
58
58
  const translations = new Set(Object.values(isoformSequences ?? {}).map(v => (0, stripStopCodon_ts_1.stripStopCodon)(v.seq)));
@@ -9,12 +9,12 @@ import type { AlignmentAlgorithm } from './types.ts';
9
9
  */
10
10
  export declare function interactionMatchesMappedEntity(entityId: string, mappedEntityId: string | undefined): boolean;
11
11
  export interface EntitySelection extends ScoredAlignment {
12
- /** index into the candidate array of the entity that is the transcript's */
12
+ /** index of the chosen entity in the candidate array */
13
13
  index: number;
14
14
  }
15
15
  export interface ScoredAlignment {
16
- /** alignment of the transcript against the entity (stop codons stripped on
17
- * both sides, matching the rest of the mapping pipeline) */
16
+ /** alignment of the transcript against the entity, with stop codons
17
+ * stripped from both */
18
18
  alignment: PairwiseAlignment;
19
19
  /** identical aligned residues */
20
20
  matches: number;
@@ -39,17 +39,15 @@ export declare function explainedFraction(matches: number, transcriptLength: num
39
39
  */
40
40
  export declare function alignTranscriptToEntity(transcript: string, entitySeq: string, algorithm: AlignmentAlgorithm): ScoredAlignment | undefined;
41
41
  /**
42
- * Pick which polymer entity of a structure corresponds to the transcript.
42
+ * Pick the polymer entity of a structure that is the transcript's protein.
43
43
  *
44
- * The plugin historically hardcoded entity `[0]`, which silently mis-maps every
45
- * heteromeric / protein-DNA / processed-peptide structure where the protein of
46
- * interest is some other chain. Selecting by alignment makes the structure self-
47
- * describe which entity is the gene's protein: an exact sequence match wins
48
- * outright, otherwise the entity with the highest identity over the shorter
49
- * sequence (see `explainedFraction`). Nucleic-acid entities are never
50
- * candidates.
44
+ * Taking entity `[0]` mis-maps every heteromeric, protein-DNA or
45
+ * processed-peptide structure where the protein is another chain. An exact
46
+ * sequence match wins outright; otherwise the entity with the highest identity
47
+ * over the shorter sequence wins (see `explainedFraction`). Nucleic-acid
48
+ * entities are never candidates.
51
49
  *
52
- * Returns `undefined` only when there is nothing to map (no transcript or no
53
- * protein entities) — never a silent fallback to the wrong entity.
50
+ * Returns `undefined` only when there is nothing to map: no transcript, or no
51
+ * protein entity. It never falls back to another entity.
54
52
  */
55
53
  export declare function chooseMappedEntity(transcript: string, entities: readonly (string | EntityCandidate)[], algorithm: AlignmentAlgorithm): EntitySelection | undefined;
@@ -25,8 +25,7 @@ function interactionMatchesMappedEntity(entityId, mappedEntityId) {
25
25
  * usually is: on 1H26 the 11-residue p53 peptide matches 11 while CDK2 accrues
26
26
  * 58 scattered identities, and on 4ZZJ SIRT1 beats the 7-residue p53 peptide
27
27
  * 63 to 6. The Smith-Waterman score is no better there (56 vs 58). Dividing
28
- * by length asks the question the picker actually has, which chain *is* this
29
- * gene's product: the peptide scores 0.69 and 0.50, the partners 0.19 and
28
+ * by the shorter length identifies the chain that *is* this gene's product: the peptide scores 0.69 and 0.50, the partners 0.19 and
30
29
  * 0.17, and across a ribosome's 55 chains no decoy passes 0.29.
31
30
  *
32
31
  * Dividing by the *entity's* length alone penalised a fusion construct: a
@@ -91,18 +90,16 @@ function alignTranscriptToEntity(transcript, entitySeq, algorithm) {
91
90
  };
92
91
  }
93
92
  /**
94
- * Pick which polymer entity of a structure corresponds to the transcript.
93
+ * Pick the polymer entity of a structure that is the transcript's protein.
95
94
  *
96
- * The plugin historically hardcoded entity `[0]`, which silently mis-maps every
97
- * heteromeric / protein-DNA / processed-peptide structure where the protein of
98
- * interest is some other chain. Selecting by alignment makes the structure self-
99
- * describe which entity is the gene's protein: an exact sequence match wins
100
- * outright, otherwise the entity with the highest identity over the shorter
101
- * sequence (see `explainedFraction`). Nucleic-acid entities are never
102
- * candidates.
95
+ * Taking entity `[0]` mis-maps every heteromeric, protein-DNA or
96
+ * processed-peptide structure where the protein is another chain. An exact
97
+ * sequence match wins outright; otherwise the entity with the highest identity
98
+ * over the shorter sequence wins (see `explainedFraction`). Nucleic-acid
99
+ * entities are never candidates.
103
100
  *
104
- * Returns `undefined` only when there is nothing to map (no transcript or no
105
- * protein entities) — never a silent fallback to the wrong entity.
101
+ * Returns `undefined` only when there is nothing to map: no transcript, or no
102
+ * protein entity. It never falls back to another entity.
106
103
  */
107
104
  function chooseMappedEntity(transcript, entities, algorithm) {
108
105
  const t = (0, stripStopCodon_ts_1.stripStopCodon)(transcript);
@@ -1 +1 @@
1
- {"version":3,"file":"chooseMappedEntity.js","sourceRoot":"","sources":["../src/chooseMappedEntity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chooseMappedEntity.js","sourceRoot":"","sources":["../src/chooseMappedEntity.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,24 @@
1
1
  import type { PairwiseAlignment } from './mappings.ts';
2
2
  /**
3
- * Branded coordinate spaces. Every position in this plugin is a bare `number`,
4
- * but the *meaning* differs: a structure residue index is not interchangeable
5
- * with a transcript residue index or an alignment column, and mixing them is
6
- * the root cause of the off-by-one class of bugs. Branding makes the compiler
7
- * reject cross-space mixing; construct values with the helpers below at the
8
- * boundaries where raw numbers enter (molstar picks, hover events, features).
3
+ * Branded coordinate spaces. Every position is a plain `number` at runtime, but
4
+ * a structure residue index, a transcript residue index and an alignment column
5
+ * mean different things, and mixing them causes off-by-one bugs. The brands
6
+ * make the compiler reject mixing; wrap a raw number with the helpers below
7
+ * where it enters, such as a molstar pick, a hover event or a feature.
9
8
  *
10
- * Conventions: all are 0-based. StructurePos indexes the ungapped structure
11
- * sequence; TranscriptPos the ungapped transcript sequence; AlignmentCol a
12
- * column of the pairwise alignment (gaps included).
9
+ * All are 0-based. StructurePos indexes the ungapped structure sequence,
10
+ * TranscriptPos the ungapped transcript sequence, and AlignmentCol a column of
11
+ * the pairwise alignment, gaps included.
13
12
  */
14
- type Branded<B extends string> = number & {
15
- readonly __brand: B;
13
+ export type StructurePos = number & {
14
+ readonly __brand: 'StructurePos';
15
+ };
16
+ export type TranscriptPos = number & {
17
+ readonly __brand: 'TranscriptPos';
18
+ };
19
+ export type AlignmentCol = number & {
20
+ readonly __brand: 'AlignmentCol';
16
21
  };
17
- export type StructurePos = Branded<'StructurePos'>;
18
- export type TranscriptPos = Branded<'TranscriptPos'>;
19
- export type AlignmentCol = Branded<'AlignmentCol'>;
20
22
  export declare const structurePos: (n: number) => StructurePos;
21
23
  export declare const transcriptPos: (n: number) => TranscriptPos;
22
24
  export declare const alignmentCol: (n: number) => AlignmentCol;
@@ -36,10 +38,9 @@ export interface CoordinateMapper {
36
38
  transcriptToAlignment: (p: TranscriptPos) => AlignmentCol | undefined;
37
39
  alignmentToTranscript: (c: AlignmentCol) => TranscriptPos | undefined;
38
40
  /**
39
- * Raw lookup tables, for consumers that iterate the whole map rather than
40
- * convert a single position (e.g. per-residue track rendering, selection of
41
- * all aligned residues). Plain numbers — prefer the typed methods above for
42
- * point conversions.
41
+ * The lookup tables as plain numbers, for code that iterates a whole map,
42
+ * such as drawing a per-residue track or selecting every aligned residue.
43
+ * Use the typed methods above to convert one position.
43
44
  */
44
45
  readonly maps: CoordinateMaps;
45
46
  }
@@ -63,4 +64,3 @@ export declare function transcriptRangeToStructureRange(mapper: CoordinateMapper
63
64
  start: number;
64
65
  end: number;
65
66
  } | undefined;
66
- export {};
@@ -1 +1 @@
1
- {"version":3,"file":"coordinates.js","sourceRoot":"","sources":["../src/coordinates.ts"],"names":[],"mappings":";;;AA4DA,oDAiCC;AASD,0EAgBC;AAtHD,+CAIsB;AACtB,iDAA0C;AAqBnC,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAiB,CAAA;AAA/C,QAAA,YAAY,gBAAmC;AACrD,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAkB,CAAA;AAAjD,QAAA,aAAa,iBAAoC;AACvD,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAiB,CAAA;AAA/C,QAAA,YAAY,gBAAmC;AA2B5D;;;;GAIG;AACH,SAAgB,oBAAoB,CAClC,iBAAoC;IAEpC,MAAM,EACJ,mCAAmC,EACnC,mCAAmC,GACpC,GAAG,IAAA,4CAA8B,EAAC,iBAAiB,CAAC,CAAA;IACrD,MAAM,KAAK,GAAG,IAAA,6CAA+B,EAAC,iBAAiB,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,IAAA,8CAAgC,EAAC,iBAAiB,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,IAAA,wBAAS,EAAC,KAAK,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAA,wBAAS,EAAC,KAAK,CAAC,CAAA;IAE9B,uEAAuE;IACvE,6EAA6E;IAC7E,sEAAsE;IACtE,OAAO;QACL,qBAAqB,EAAE,CAAC,CAAC,EAAE,CACzB,mCAAmC,CAAC,CAAC,CAA8B;QACrE,qBAAqB,EAAE,CAAC,CAAC,EAAE,CACzB,mCAAmC,CAAC,CAAC,CAA6B;QACpE,oBAAoB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAC/D,oBAAoB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAC/D,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAChE,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA8B;QACjE,IAAI,EAAE;YACJ,mCAAmC;YACnC,mCAAmC;YACnC,+BAA+B,EAAE,KAAK;YACtC,gCAAgC,EAAE,KAAK;YACvC,4BAA4B,EAAE,KAAK;YACnC,6BAA6B,EAAE,KAAK;SACrC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAC7C,MAAwB,EACxB,KAAqC;IAErC,IAAI,KAAyB,CAAA;IAC7B,IAAI,IAAwB,CAAA;IAC5B,KAAK,IAAI,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAA,qBAAa,EAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;QACpE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YACxD,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAC9C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,EAAE,CAAA;AACrC,CAAC"}
1
+ {"version":3,"file":"coordinates.js","sourceRoot":"","sources":["../src/coordinates.ts"],"names":[],"mappings":";;;AAyDA,oDAiCC;AASD,0EAgBC;AAnHD,+CAIsB;AACtB,iDAA0C;AAmBnC,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAiB,CAAA;AAA/C,QAAA,YAAY,gBAAmC;AACrD,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAkB,CAAA;AAAjD,QAAA,aAAa,iBAAoC;AACvD,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAiB,CAAA;AAA/C,QAAA,YAAY,gBAAmC;AA0B5D;;;;GAIG;AACH,SAAgB,oBAAoB,CAClC,iBAAoC;IAEpC,MAAM,EACJ,mCAAmC,EACnC,mCAAmC,GACpC,GAAG,IAAA,4CAA8B,EAAC,iBAAiB,CAAC,CAAA;IACrD,MAAM,KAAK,GAAG,IAAA,6CAA+B,EAAC,iBAAiB,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,IAAA,8CAAgC,EAAC,iBAAiB,CAAC,CAAA;IACjE,MAAM,KAAK,GAAG,IAAA,wBAAS,EAAC,KAAK,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAA,wBAAS,EAAC,KAAK,CAAC,CAAA;IAE9B,uEAAuE;IACvE,6EAA6E;IAC7E,sEAAsE;IACtE,OAAO;QACL,qBAAqB,EAAE,CAAC,CAAC,EAAE,CACzB,mCAAmC,CAAC,CAAC,CAA8B;QACrE,qBAAqB,EAAE,CAAC,CAAC,EAAE,CACzB,mCAAmC,CAAC,CAAC,CAA6B;QACpE,oBAAoB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAC/D,oBAAoB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAC/D,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA6B;QAChE,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAA8B;QACjE,IAAI,EAAE;YACJ,mCAAmC;YACnC,mCAAmC;YACnC,+BAA+B,EAAE,KAAK;YACtC,gCAAgC,EAAE,KAAK;YACvC,4BAA4B,EAAE,KAAK;YACnC,6BAA6B,EAAE,KAAK;SACrC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAC7C,MAAwB,EACxB,KAAqC;IAErC,IAAI,KAAyB,CAAA;IAC7B,IAAI,IAAwB,CAAA;IAC5B,KAAK,IAAI,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAA,qBAAa,EAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;QACpE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YACxD,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAC9C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,EAAE,CAAA;AACrC,CAAC"}
package/dist/dbIds.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type DbType = 'ensembl' | 'refseq' | 'ccds' | 'hgnc' | 'geneid';
1
+ export type DbType = 'ensembl' | 'refseq' | 'ccds' | 'hgnc' | 'geneid';
2
2
  export declare function matchDbIdPattern(id: string): {
3
3
  db: DbType;
4
4
  pattern: RegExp;
@@ -13,4 +13,3 @@ export declare function getDbIdLabel(id: string): string;
13
13
  * "xref:ensembl-ENST00000123". HGNC strips its redundant "HGNC:" prefix. */
14
14
  export declare function buildUniProtXrefQuery(id: string): string | undefined;
15
15
  export declare function stripTrailingVersion(s?: string): string | undefined;
16
- export {};
@@ -1,4 +1,4 @@
1
- interface ConfidenceModel {
1
+ export interface ConfidenceModel {
2
2
  obj?: {
3
3
  data: {
4
4
  atomicConformation: {
@@ -46,4 +46,3 @@ export declare function extractPerResidueConfidence(model: ConfidenceModel): Ent
46
46
  * indicate the track wouldn't be meaningful as confidence.
47
47
  */
48
48
  export declare function looksLikePlddt(values: number[] | undefined): values is number[];
49
- export {};
@@ -1,49 +1,42 @@
1
1
  /** A polymer entity of a loaded structure: its mmCIF entity id, its one-letter
2
- * sequence, and the molstar `label_seq_id` of each of those residues.
2
+ * sequence, and the molstar `label_seq_id` of each residue.
3
3
  *
4
- * The entity id is what lets every downstream step talk about "the gene's
5
- * protein" by identity instead of by the fragile entity-[0] position.
4
+ * Structure positions are 0-based indices into `seq`, and molstar selects
5
+ * residues by `label_seq_id`. The two differ by 1 only when the entity's
6
+ * sequence covers every residue from 1, which holds for any mmCIF with an
7
+ * `entity_poly_seq` category (all of RCSB and AlphaFold) and for a PDB file
8
+ * with SEQRES records, from which molstar builds that category.
6
9
  *
7
- * `seqIds` is what lets it talk about a *residue* by identity. Structure
8
- * positions in this plugin are 0-based indices into `seq`; molstar addresses
9
- * residues by `label_seq_id`. Those are related by `+1` only when the entity's
10
- * sequence covers every residue from 1 — true for any mmCIF with an
11
- * `entity_poly_seq` category (all of RCSB and AlphaFold) and for PDB files
12
- * carrying SEQRES records, because molstar synthesizes the category from them.
13
- *
14
- * A PDB-format file with no SEQRES has no such category, so molstar falls back
15
- * to `StructureSequence.fromHierarchy` and takes `label_seq_id` straight from
16
- * the observed residues' author numbering: a chain whose coordinates start at
17
- * residue 94 yields seqIds 94.., and an unobserved loop leaves a hole. Deriving
18
- * the id arithmetically there is off by the whole offset, in both directions —
19
- * every hover reads the wrong residue and every highlight paints the wrong one.
20
- * So carry the real ids and convert through them.
10
+ * For a PDB file without SEQRES, molstar falls back to
11
+ * `StructureSequence.fromHierarchy` and takes `label_seq_id` from the observed
12
+ * residues' author numbering: a chain whose coordinates start at residue 94 has
13
+ * seqIds 94.., and an unobserved loop leaves a gap. Adding 1 there is off by the
14
+ * whole offset, in both directions, so convert through `seqIds`.
21
15
  */
22
16
  export interface Entity {
17
+ /** mmCIF entity id */
23
18
  entityId: string;
19
+ /** one letter per residue, observed or not */
24
20
  seq: string;
21
+ /** molstar `label_seq_id` per position of `seq` */
25
22
  seqIds: number[];
26
- /** author chain ids carrying this entity, e.g. ['A', 'B'] for a homodimer;
27
- * what a user recognises from the PDB entry page, where the entity id is
28
- * molstar's own bookkeeping */
23
+ /** author chain ids of this entity, e.g. ['A', 'B'] for a homodimer, as
24
+ * the PDB entry page lists them */
29
25
  chains: string[];
30
- /** DNA, RNA or a hybrid, by molstar's entity subtype. Its one-letter
31
- * sequence spells amino acids too (A, C, G, T, U), so it has to be kept
32
- * out of the transcript alignment rather than merely scoring low. */
26
+ /** DNA, RNA or a hybrid, by molstar's entity subtype. A, C, G, T and U
27
+ * are amino-acid letters too, so chooseMappedEntity skips these. */
33
28
  nucleicAcid?: boolean;
34
- /** `auth_seq_id` per position: the numbering the depositors chose, which
35
- * for an RCSB entry is the one papers and UniProt cite (1TUP's position 154
36
- * is R248) and what Mol*'s own hover label shows. Display only; every
37
- * coordinate the plugin computes with stays a 0-based position, and molstar
38
- * is addressed through `seqIds`. Absent when the model has no atomic
39
- * hierarchy to read it from. See `residueNumber`. */
29
+ /** `auth_seq_id` per position: the depositors' numbering, which papers cite
30
+ * (1TUP's position 154 is R248) and Mol*'s hover shows. For display only;
31
+ * use `seqIds` to select residues in Mol*. Absent when the model has no
32
+ * atomic hierarchy. See `residueNumber`. */
40
33
  authSeqIds?: number[];
41
34
  }
42
- interface Column<T> {
35
+ export interface Column<T> {
43
36
  rowCount: number;
44
37
  value(row: number): T;
45
38
  }
46
- interface StructureModel {
39
+ export interface StructureModel {
47
40
  obj?: {
48
41
  data: {
49
42
  entities?: {
@@ -123,8 +116,8 @@ export declare function oneLetterSequence(codes: ArrayLike<string>, canonical: s
123
116
  export declare function extractEntities(model: StructureModel): Entity[] | undefined;
124
117
  /** A user-facing name for an entity: its chains when known, else its id. */
125
118
  export declare function entityLabel(entity: Entity): string;
126
- /** The protein chains' sequences, for the launch dialog's isoform matching,
127
- * which has no use for a DNA strand that happens to align. */
119
+ /** The protein chains' sequences, for ranking isoforms against a structure.
120
+ * DNA chains are left out, because their letters align as amino acids. */
128
121
  export declare function extractStructureSequences(model: StructureModel): string[] | undefined;
129
122
  /**
130
123
  * The molstar `label_seq_id`s for a set of 0-based structure positions. Unknown
@@ -139,4 +132,3 @@ export declare function rangeToLabelSeqIds(entity: Entity | undefined, range: {
139
132
  } | undefined): number[];
140
133
  /** Reverse of `seqIds`: molstar's label_seq_id -> 0-based structure position. */
141
134
  export declare function makeLabelSeqIdIndex(entity: Entity | undefined): Map<number, number>;
142
- export {};
@@ -169,8 +169,8 @@ function entityLabel(entity) {
169
169
  : `Entity ${entity.entityId}`;
170
170
  return `${chains} (${entity.seq.length} ${entity.nucleicAcid ? 'nt' : 'aa'})`;
171
171
  }
172
- /** The protein chains' sequences, for the launch dialog's isoform matching,
173
- * which has no use for a DNA strand that happens to align. */
172
+ /** The protein chains' sequences, for ranking isoforms against a structure.
173
+ * DNA chains are left out, because their letters align as amino acids. */
174
174
  function extractStructureSequences(model) {
175
175
  return extractEntities(model)
176
176
  ?.filter(e => !e.nucleicAcid)