p2s_mapper 2.0.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.
- package/README.md +37 -38
- package/dist/alignmentQuality.d.ts +5 -5
- package/dist/alphaFoldModels.d.ts +4 -4
- package/dist/alphaFoldModels.js +4 -4
- package/dist/chooseMappedEntity.d.ts +11 -13
- package/dist/chooseMappedEntity.js +9 -12
- package/dist/chooseMappedEntity.js.map +1 -1
- package/dist/coordinates.d.ts +11 -13
- package/dist/coordinates.js.map +1 -1
- package/dist/extractStructureSequences.d.ts +21 -28
- package/dist/extractStructureSequences.js +2 -2
- package/dist/extractStructureSequences.js.map +1 -1
- package/dist/fetchUtils.d.ts +7 -7
- package/dist/fetchUtils.js +7 -7
- package/dist/isoformRanking.d.ts +1 -1
- package/dist/mappings.d.ts +9 -12
- package/dist/mappings.js +4 -5
- package/dist/mappings.js.map +1 -1
- package/dist/pairwiseAlignment.d.ts +4 -2
- package/dist/pairwiseAlignment.js +9 -7
- package/dist/pairwiseAlignment.js.map +1 -1
- package/dist/pdbUniProtMapping.d.ts +5 -6
- package/dist/pdbUniProtMapping.js +5 -6
- package/dist/pdbUniProtMapping.js.map +1 -1
- package/dist/structureFormat.d.ts +11 -18
- package/dist/structureFormat.js +4 -6
- package/dist/structureFormat.js.map +1 -1
- package/dist/structureSources.d.ts +1 -1
- package/dist/structureUrls.d.ts +11 -16
- package/dist/structureUrls.js +14 -23
- package/dist/structureUrls.js.map +1 -1
- package/dist/types.d.ts +2 -5
- package/dist/types.js +2 -5
- package/dist/types.js.map +1 -1
- package/dist/uniProtSearch.js +3 -8
- package/dist/uniProtSearch.js.map +1 -1
- package/esm/alignmentQuality.d.ts +5 -5
- package/esm/alphaFoldModels.d.ts +4 -4
- package/esm/alphaFoldModels.js +4 -4
- package/esm/chooseMappedEntity.d.ts +11 -13
- package/esm/chooseMappedEntity.js +9 -12
- package/esm/chooseMappedEntity.js.map +1 -1
- package/esm/coordinates.d.ts +11 -13
- package/esm/coordinates.js.map +1 -1
- package/esm/extractStructureSequences.d.ts +21 -28
- package/esm/extractStructureSequences.js +2 -2
- package/esm/extractStructureSequences.js.map +1 -1
- package/esm/fetchUtils.d.ts +7 -7
- package/esm/fetchUtils.js +7 -7
- package/esm/isoformRanking.d.ts +1 -1
- package/esm/mappings.d.ts +9 -12
- package/esm/mappings.js +4 -5
- package/esm/mappings.js.map +1 -1
- package/esm/pairwiseAlignment.d.ts +4 -2
- package/esm/pairwiseAlignment.js +7 -5
- package/esm/pairwiseAlignment.js.map +1 -1
- package/esm/pdbUniProtMapping.d.ts +5 -6
- package/esm/pdbUniProtMapping.js +5 -6
- package/esm/pdbUniProtMapping.js.map +1 -1
- package/esm/structureFormat.d.ts +11 -18
- package/esm/structureFormat.js +4 -6
- package/esm/structureFormat.js.map +1 -1
- package/esm/structureSources.d.ts +1 -1
- package/esm/structureUrls.d.ts +11 -16
- package/esm/structureUrls.js +14 -23
- package/esm/structureUrls.js.map +1 -1
- package/esm/types.d.ts +2 -5
- package/esm/types.js +2 -5
- package/esm/types.js.map +1 -1
- package/esm/uniProtSearch.js +3 -8
- package/esm/uniProtSearch.js.map +1 -1
- package/package.json +1 -1
- package/src/alignmentQuality.ts +5 -5
- package/src/alphaFoldModels.ts +4 -4
- package/src/chooseMappedEntity.ts +12 -15
- package/src/coordinates.ts +11 -13
- package/src/extractStructureSequences.ts +21 -28
- package/src/fetchUtils.ts +7 -7
- package/src/isoformRanking.ts +1 -1
- package/src/mappings.ts +9 -12
- package/src/pairwiseAlignment.ts +11 -8
- package/src/pdbUniProtMapping.ts +5 -6
- package/src/structureFormat.ts +11 -18
- package/src/structureSources.ts +1 -1
- package/src/structureUrls.ts +14 -23
- package/src/types.ts +2 -5
- package/src/uniProtSearch.ts +3 -8
package/src/coordinates.ts
CHANGED
|
@@ -8,16 +8,15 @@ import { invertMap } from './invertMap.ts'
|
|
|
8
8
|
import type { PairwiseAlignment } from './mappings.ts'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Branded coordinate spaces. Every position
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* the
|
|
15
|
-
*
|
|
16
|
-
* boundaries where raw numbers enter (molstar picks, hover events, features).
|
|
11
|
+
* Branded coordinate spaces. Every position is a plain `number` at runtime, but
|
|
12
|
+
* a structure residue index, a transcript residue index and an alignment column
|
|
13
|
+
* mean different things, and mixing them causes off-by-one bugs. The brands
|
|
14
|
+
* make the compiler reject mixing; wrap a raw number with the helpers below
|
|
15
|
+
* where it enters, such as a molstar pick, a hover event or a feature.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* All are 0-based. StructurePos indexes the ungapped structure sequence,
|
|
18
|
+
* TranscriptPos the ungapped transcript sequence, and AlignmentCol a column of
|
|
19
|
+
* the pairwise alignment, gaps included.
|
|
21
20
|
*/
|
|
22
21
|
export type StructurePos = number & { readonly __brand: 'StructurePos' }
|
|
23
22
|
export type TranscriptPos = number & { readonly __brand: 'TranscriptPos' }
|
|
@@ -44,10 +43,9 @@ export interface CoordinateMapper {
|
|
|
44
43
|
transcriptToAlignment: (p: TranscriptPos) => AlignmentCol | undefined
|
|
45
44
|
alignmentToTranscript: (c: AlignmentCol) => TranscriptPos | undefined
|
|
46
45
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* point conversions.
|
|
46
|
+
* The lookup tables as plain numbers, for code that iterates a whole map,
|
|
47
|
+
* such as drawing a per-residue track or selecting every aligned residue.
|
|
48
|
+
* Use the typed methods above to convert one position.
|
|
51
49
|
*/
|
|
52
50
|
readonly maps: CoordinateMaps
|
|
53
51
|
}
|
|
@@ -1,42 +1,35 @@
|
|
|
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
|
|
2
|
+
* sequence, and the molstar `label_seq_id` of each residue.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
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
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* residues
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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 {
|
|
23
|
-
/** mmCIF entity id
|
|
17
|
+
/** mmCIF entity id */
|
|
24
18
|
entityId: string
|
|
25
19
|
/** one letter per residue, observed or not */
|
|
26
20
|
seq: string
|
|
27
21
|
/** molstar `label_seq_id` per position of `seq` */
|
|
28
22
|
seqIds: number[]
|
|
29
|
-
/** author chain ids
|
|
30
|
-
*
|
|
23
|
+
/** author chain ids of this entity, e.g. ['A', 'B'] for a homodimer, as
|
|
24
|
+
* the PDB entry page lists them */
|
|
31
25
|
chains: string[]
|
|
32
|
-
/** DNA, RNA or a hybrid, by molstar's entity subtype.
|
|
33
|
-
* amino
|
|
34
|
-
* rather than left to score 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. */
|
|
35
28
|
nucleicAcid?: boolean
|
|
36
29
|
/** `auth_seq_id` per position: the depositors' numbering, which papers cite
|
|
37
|
-
* (1TUP's position 154 is R248) and Mol*'s hover shows.
|
|
38
|
-
*
|
|
39
|
-
* hierarchy. See `residueNumber`. */
|
|
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
35
|
|
|
@@ -284,8 +277,8 @@ export function entityLabel(entity: Entity) {
|
|
|
284
277
|
return `${chains} (${entity.seq.length} ${entity.nucleicAcid ? 'nt' : 'aa'})`
|
|
285
278
|
}
|
|
286
279
|
|
|
287
|
-
/** The protein chains' sequences, for
|
|
288
|
-
*
|
|
280
|
+
/** The protein chains' sequences, for ranking isoforms against a structure.
|
|
281
|
+
* DNA chains are left out, because their letters align as amino acids. */
|
|
289
282
|
export function extractStructureSequences(
|
|
290
283
|
model: StructureModel,
|
|
291
284
|
): string[] | undefined {
|
package/src/fetchUtils.ts
CHANGED
|
@@ -36,9 +36,9 @@ export function isDefinitiveFailure(e: unknown) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* The error a failed response
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* The error for a failed response: status and host, plus at most the first line
|
|
40
|
+
* of the body. A whole body is an HTML error page or a megabyte of JSON, which
|
|
41
|
+
* hides the line that says what went wrong.
|
|
42
42
|
*/
|
|
43
43
|
export async function httpError(response: Response, url: string) {
|
|
44
44
|
const detail = firstLine(await response.text().catch(() => ''))
|
|
@@ -127,10 +127,10 @@ export async function jsonfetch<T = unknown>(
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
|
-
* An AbortSignal's reason as a real Error. `signal.reason` is `any
|
|
131
|
-
* DOMException, but a caller can abort with
|
|
132
|
-
*
|
|
133
|
-
*
|
|
130
|
+
* An AbortSignal's reason as a real Error. `signal.reason` is `any`, usually a
|
|
131
|
+
* DOMException, but a caller can abort with any value, and throwing a non-Error
|
|
132
|
+
* loses the stack and breaks `instanceof Error` checks. Use it at every throw
|
|
133
|
+
* site.
|
|
134
134
|
*/
|
|
135
135
|
export function abortError(signal: AbortSignal) {
|
|
136
136
|
return signal.reason instanceof Error
|
package/src/isoformRanking.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface RankedIsoform {
|
|
|
17
17
|
/** identical residues against the structure, for an isoform that does not
|
|
18
18
|
* match it exactly; undefined with no structure to compare to */
|
|
19
19
|
identical?: number
|
|
20
|
-
/** that alignment's score, which
|
|
20
|
+
/** that alignment's score, which ranks the non-matching isoforms */
|
|
21
21
|
score?: number
|
|
22
22
|
}
|
|
23
23
|
|
package/src/mappings.ts
CHANGED
|
@@ -6,13 +6,11 @@ export interface AlignmentRow {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* A two-row alignment
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* every coordinate map. Read the rows through the accessors below rather than
|
|
15
|
-
* indexing, so a call site states which sequence it means.
|
|
9
|
+
* A two-row alignment: row 0 is the transcript and row 1 is the structure.
|
|
10
|
+
* alignSequences takes them in that order and every consumer depends on it,
|
|
11
|
+
* but the type cannot enforce it, and swapped rows invert every coordinate map
|
|
12
|
+
* without an error. Read the rows with the accessors below, so a call site
|
|
13
|
+
* names the sequence it means.
|
|
16
14
|
*/
|
|
17
15
|
export interface PairwiseAlignment {
|
|
18
16
|
consensus: string
|
|
@@ -28,11 +26,10 @@ export const alignmentLength = (pa: PairwiseAlignment) =>
|
|
|
28
26
|
transcriptAlignedSeq(pa).length
|
|
29
27
|
|
|
30
28
|
/**
|
|
31
|
-
* Why a pairwise alignment can't be used, or undefined if it's usable.
|
|
32
|
-
* rows must
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* report it; the internal map builders assert on it.
|
|
29
|
+
* Why a pairwise alignment can't be used, or undefined if it's usable. Both
|
|
30
|
+
* rows must have the same non-zero length, because every coordinate map walks
|
|
31
|
+
* them in step. Check an alignment from outside the package with this; the
|
|
32
|
+
* internal map builders throw on it.
|
|
36
33
|
*/
|
|
37
34
|
export function pairwiseAlignmentProblem(pa: PairwiseAlignment) {
|
|
38
35
|
const transcript = transcriptAlignedSeq(pa)
|
package/src/pairwiseAlignment.ts
CHANGED
|
@@ -393,14 +393,14 @@ export function selfScore(seq: string) {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
export function scoredAlignment(
|
|
396
|
-
|
|
397
|
-
|
|
396
|
+
transcript: string,
|
|
397
|
+
structure: string,
|
|
398
398
|
algorithm: AlignmentAlgorithm,
|
|
399
399
|
): { alignment: PairwiseAlignment; score: number } {
|
|
400
400
|
const { alignedSeq1, alignedSeq2, score } =
|
|
401
401
|
algorithm === 'smith_waterman'
|
|
402
|
-
? smithWaterman(
|
|
403
|
-
: needlemanWunsch(
|
|
402
|
+
? smithWaterman(transcript, structure)
|
|
403
|
+
: needlemanWunsch(transcript, structure)
|
|
404
404
|
|
|
405
405
|
return {
|
|
406
406
|
alignment: {
|
|
@@ -414,10 +414,13 @@ export function scoredAlignment(
|
|
|
414
414
|
}
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
export function
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
export function alignSequences(
|
|
418
|
+
transcript: string,
|
|
419
|
+
structure: string,
|
|
420
420
|
algorithm: AlignmentAlgorithm,
|
|
421
421
|
): PairwiseAlignment {
|
|
422
|
-
return scoredAlignment(
|
|
422
|
+
return scoredAlignment(transcript, structure, algorithm).alignment
|
|
423
423
|
}
|
|
424
|
+
|
|
425
|
+
/** @deprecated renamed to `alignSequences`, which runs either algorithm */
|
|
426
|
+
export const runLocalAlignment = alignSequences
|
package/src/pdbUniProtMapping.ts
CHANGED
|
@@ -70,12 +70,11 @@ function segmentsForEntity(
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
* Picks the UniProt entry
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* contributing the most residues wins.
|
|
73
|
+
* Picks the UniProt entry for a given entity, with its segments narrowed to
|
|
74
|
+
* that entity. Pass the entity mapped to the transcript: a heteromer's chains
|
|
75
|
+
* align to different accessions, and the wrong one would annotate the wrong
|
|
76
|
+
* protein. When several accessions cover one entity (a chimeric construct), the
|
|
77
|
+
* one covering the most residues wins.
|
|
79
78
|
*/
|
|
80
79
|
export function chooseUniProtMappingForEntity(
|
|
81
80
|
mappings: UniProtStructureMapping[],
|
package/src/structureFormat.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Which molstar trajectory parser a structure needs.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* error.
|
|
4
|
+
* A wrong choice fails either way. Parsing a PDB file as mmCIF throws
|
|
5
|
+
* ("Unexpected token. Expected data_, loop_, or data name"). Parsing an mmCIF
|
|
6
|
+
* as PDB succeeds and yields a model with zero polymer entities and thousands of
|
|
7
|
+
* misread atoms, so the structure loads with no sequence, no alignment and no
|
|
8
|
+
* genome mapping, and with no error.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* The two names are the subset of molstar's `BuiltInTrajectoryFormat` a
|
|
15
|
-
* structure loaded from a file or a url can be, spelled out rather than
|
|
16
|
-
* imported so nothing here depends on molstar.
|
|
10
|
+
* The two names are the subset of molstar's `BuiltInTrajectoryFormat` that a
|
|
11
|
+
* structure file or URL can be, written out so nothing here imports molstar.
|
|
17
12
|
*/
|
|
18
13
|
export type StructureFormat = 'pdb' | 'mmcif'
|
|
19
14
|
|
|
@@ -35,8 +30,7 @@ export function structureFileExtension(nameOrUrl: string) {
|
|
|
35
30
|
|
|
36
31
|
/**
|
|
37
32
|
* Format for a filename or URL. Unknown extensions fall back to mmCIF, which is
|
|
38
|
-
* what
|
|
39
|
-
* hand out `.cif`).
|
|
33
|
+
* what AlphaFold and RCSB serve (`.cif`).
|
|
40
34
|
*/
|
|
41
35
|
export function structureFormatFromName(nameOrUrl: string): StructureFormat {
|
|
42
36
|
return PDB_EXTENSIONS.has(structureFileExtension(nameOrUrl)) ? 'pdb' : 'mmcif'
|
|
@@ -49,10 +43,9 @@ export function isBinaryStructureUrl(url: string) {
|
|
|
49
43
|
}
|
|
50
44
|
|
|
51
45
|
/**
|
|
52
|
-
* Format for structure text
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* and is the only signal available here.
|
|
46
|
+
* Format for structure text with no filename, such as inline data, a pasted
|
|
47
|
+
* file, or a PDB built by `caCoordsToPdb`. The content is more reliable than a
|
|
48
|
+
* name, and here it is the only signal.
|
|
56
49
|
*
|
|
57
50
|
* mmCIF is line-oriented and its first meaningful line is a `data_` block
|
|
58
51
|
* header (comments and blank lines may precede it); PDB has none.
|
package/src/structureSources.ts
CHANGED
package/src/structureUrls.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
//
|
|
2
|
-
// the launch flow and the ProteinView model (e.g. resolving a `uniprotId`/`pdbId`
|
|
3
|
-
// shorthand at hydration) can import them without pulling in heavy launch code.
|
|
1
|
+
// Structure URL builders and target parsers, with no dependencies.
|
|
4
2
|
|
|
5
3
|
const ALPHAFOLD_VERSION = 'v6'
|
|
6
4
|
|
|
7
|
-
// UniProt endpoints. rest.* is the machine API
|
|
8
|
-
// the
|
|
9
|
-
// assembly is built from); www.*/entry is the human-facing entry page the UI
|
|
10
|
-
// links to. Centralized so a path change is one edit rather than a grep.
|
|
5
|
+
// UniProt endpoints. rest.* is the machine API, serving the features as GFF
|
|
6
|
+
// and the sequence as FASTA; www.*/entry is the entry page for people.
|
|
11
7
|
export function uniprotGffUrl(uniprotId: string) {
|
|
12
8
|
return `https://rest.uniprot.org/uniprotkb/${uniprotId}.gff`
|
|
13
9
|
}
|
|
@@ -49,20 +45,15 @@ export function rcsbEntryUrl(pdbId: string) {
|
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
/**
|
|
52
|
-
* Resolve the `{ pdbId }` shorthand to a
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
48
|
+
* Resolve the `{ pdbId }` shorthand to a structure URL, so a hand-written config
|
|
49
|
+
* or a short launch URL needs no RCSB filename. An explicit `url` (or inline
|
|
50
|
+
* `data`) always wins, and resolving an already-resolved spec returns the same
|
|
51
|
+
* url.
|
|
56
52
|
*
|
|
57
|
-
* `uniprotId`
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* file to open.
|
|
62
|
-
*
|
|
63
|
-
* Shared by the Structure model's snapshot preprocessor and the
|
|
64
|
-
* LaunchView-ProteinView extension point, which would otherwise each carry
|
|
65
|
-
* their own copy of the same precedence rule.
|
|
53
|
+
* `uniprotId` resolves to no url and still outranks a `pdbId`. AlphaFold DB's
|
|
54
|
+
* files for an accession change (an isoform model, several fragments, a new
|
|
55
|
+
* model version), so the caller keeps the accession and asks
|
|
56
|
+
* `fetchAlphaFoldModels` which file to open.
|
|
66
57
|
*/
|
|
67
58
|
export function resolveStructureUrl({
|
|
68
59
|
url,
|
|
@@ -149,9 +140,9 @@ export function getConfidenceUrlFromTarget(target: string) {
|
|
|
149
140
|
}
|
|
150
141
|
|
|
151
142
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
143
|
+
* The name to show for a structure: its PDB id, its AlphaFold accession, else
|
|
144
|
+
* the file's name. Use it wherever a structure is named, so each place shows
|
|
145
|
+
* the same name.
|
|
155
146
|
*/
|
|
156
147
|
export function structureDisplayLabel({
|
|
157
148
|
url,
|
package/src/types.ts
CHANGED
|
@@ -12,11 +12,8 @@ export const ALIGNMENT_ALGORITHM_VALUES: AlignmentAlgorithm[] = [
|
|
|
12
12
|
'smith_waterman',
|
|
13
13
|
]
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* The only place a coercion is needed: the model property is an enumeration, so
|
|
18
|
-
* everything downstream of hydration is already typed.
|
|
19
|
-
*/
|
|
15
|
+
/** Parses an untrusted algorithm name, such as a URL parameter, falling back
|
|
16
|
+
* to Smith-Waterman. */
|
|
20
17
|
export function coerceAlignmentAlgorithm(value: string): AlignmentAlgorithm {
|
|
21
18
|
return (
|
|
22
19
|
ALIGNMENT_ALGORITHM_VALUES.find(v => v === value) ??
|
package/src/uniProtSearch.ts
CHANGED
|
@@ -111,7 +111,6 @@ async function searchByXref(
|
|
|
111
111
|
try {
|
|
112
112
|
return { entries: await searchUniProt(query, 10, opts), error: undefined }
|
|
113
113
|
} catch (e) {
|
|
114
|
-
console.error(`xref search failed for ${id}:`, e)
|
|
115
114
|
return { entries: [], error: e }
|
|
116
115
|
}
|
|
117
116
|
}
|
|
@@ -132,22 +131,18 @@ async function searchByGeneName(
|
|
|
132
131
|
// are 284812. The descendants are asked only on a miss, because for a
|
|
133
132
|
// species with reviewed subspecies entries (human and Neanderthal) they
|
|
134
133
|
// turn one answer into two.
|
|
135
|
-
//
|
|
136
|
-
//
|
|
134
|
+
// When the descendant search fails, the taxon's own empty result stands
|
|
135
|
+
// rather than becoming an error.
|
|
137
136
|
const entries =
|
|
138
137
|
exact.length === 0 && organismId
|
|
139
138
|
? await searchUniProt(
|
|
140
139
|
buildGeneNameQuery(geneName, organismId, 'taxonomy_id'),
|
|
141
140
|
5,
|
|
142
141
|
opts,
|
|
143
|
-
).catch((
|
|
144
|
-
console.error(`descendant-taxon search failed for ${geneName}:`, e)
|
|
145
|
-
return exact
|
|
146
|
-
})
|
|
142
|
+
).catch(() => exact)
|
|
147
143
|
: exact
|
|
148
144
|
return { entries, error: undefined }
|
|
149
145
|
} catch (e) {
|
|
150
|
-
console.error(`gene name search failed for ${geneName}:`, e)
|
|
151
146
|
return { entries: [], error: e }
|
|
152
147
|
}
|
|
153
148
|
}
|