react-msaview 4.5.0 → 4.8.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 (98) hide show
  1. package/bundle/index.js +99 -99
  2. package/bundle/index.js.LICENSE.txt +6 -6
  3. package/bundle/index.js.map +1 -1
  4. package/dist/__snapshots__/parseAsn1.test.js.snap +2400 -0
  5. package/dist/components/header/HeaderInfoArea.js +3 -4
  6. package/dist/components/header/HeaderInfoArea.js.map +1 -1
  7. package/dist/components/import/ImportForm.js +6 -2
  8. package/dist/components/import/ImportForm.js.map +1 -1
  9. package/dist/components/import/util.d.ts +1 -1
  10. package/dist/components/import/util.js +4 -1
  11. package/dist/components/import/util.js.map +1 -1
  12. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +7 -2
  13. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  14. package/dist/components/msa/renderMSABlock.js +20 -18
  15. package/dist/components/msa/renderMSABlock.js.map +1 -1
  16. package/dist/components/msa/renderMSAMouseover.js +8 -1
  17. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  18. package/dist/components/tree/renderTreeCanvas.d.ts +0 -1
  19. package/dist/components/tree/renderTreeCanvas.js +32 -31
  20. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  21. package/dist/model.d.ts +168 -16
  22. package/dist/model.js +116 -29
  23. package/dist/model.js.map +1 -1
  24. package/dist/rowCoordinateCalculations.d.ts +69 -9
  25. package/dist/rowCoordinateCalculations.js +118 -46
  26. package/dist/rowCoordinateCalculations.js.map +1 -1
  27. package/dist/rowCoordinateCalculations.test.js +152 -52
  28. package/dist/rowCoordinateCalculations.test.js.map +1 -1
  29. package/dist/seqPosToGlobalCol.d.ts +19 -0
  30. package/dist/seqPosToGlobalCol.js +34 -0
  31. package/dist/seqPosToGlobalCol.js.map +1 -0
  32. package/dist/seqPosToGlobalCol.test.js +60 -0
  33. package/dist/seqPosToGlobalCol.test.js.map +1 -0
  34. package/dist/util.d.ts +1 -2
  35. package/dist/util.js +0 -9
  36. package/dist/util.js.map +1 -1
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/package.json +7 -9
  40. package/src/components/header/HeaderInfoArea.tsx +2 -5
  41. package/src/components/import/ImportForm.tsx +6 -1
  42. package/src/components/import/util.ts +4 -0
  43. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +7 -2
  44. package/src/components/msa/renderMSABlock.ts +26 -19
  45. package/src/components/msa/renderMSAMouseover.ts +9 -0
  46. package/src/components/tree/renderTreeCanvas.ts +35 -42
  47. package/src/declare.d.ts +0 -1
  48. package/src/model.ts +143 -42
  49. package/src/rowCoordinateCalculations.test.ts +167 -74
  50. package/src/rowCoordinateCalculations.ts +138 -63
  51. package/src/seqPosToGlobalCol.test.ts +71 -0
  52. package/src/seqPosToGlobalCol.ts +40 -0
  53. package/src/util.ts +1 -19
  54. package/src/version.ts +1 -1
  55. package/dist/parseGFF.d.ts +0 -10
  56. package/dist/parseGFF.js +0 -31
  57. package/dist/parseGFF.js.map +0 -1
  58. package/dist/parseNewick.d.ts +0 -60
  59. package/dist/parseNewick.js +0 -95
  60. package/dist/parseNewick.js.map +0 -1
  61. package/dist/parsers/A3mMSA.d.ts +0 -43
  62. package/dist/parsers/A3mMSA.js +0 -277
  63. package/dist/parsers/A3mMSA.js.map +0 -1
  64. package/dist/parsers/A3mMSA.test.js +0 -138
  65. package/dist/parsers/A3mMSA.test.js.map +0 -1
  66. package/dist/parsers/ClustalMSA.d.ts +0 -30
  67. package/dist/parsers/ClustalMSA.js +0 -55
  68. package/dist/parsers/ClustalMSA.js.map +0 -1
  69. package/dist/parsers/EmfMSA.d.ts +0 -27
  70. package/dist/parsers/EmfMSA.js +0 -53
  71. package/dist/parsers/EmfMSA.js.map +0 -1
  72. package/dist/parsers/EmfTree.d.ts +0 -5
  73. package/dist/parsers/EmfTree.js +0 -8
  74. package/dist/parsers/EmfTree.js.map +0 -1
  75. package/dist/parsers/FastaMSA.d.ts +0 -19
  76. package/dist/parsers/FastaMSA.js +0 -69
  77. package/dist/parsers/FastaMSA.js.map +0 -1
  78. package/dist/parsers/StockholmMSA.d.ts +0 -68
  79. package/dist/parsers/StockholmMSA.js +0 -107
  80. package/dist/parsers/StockholmMSA.js.map +0 -1
  81. package/dist/seqCoordToRowSpecificGlobalCoord.d.ts +0 -4
  82. package/dist/seqCoordToRowSpecificGlobalCoord.js +0 -19
  83. package/dist/seqCoordToRowSpecificGlobalCoord.js.map +0 -1
  84. package/dist/seqCoordToRowSpecificGlobalCoord.test.d.ts +0 -1
  85. package/dist/seqCoordToRowSpecificGlobalCoord.test.js +0 -42
  86. package/dist/seqCoordToRowSpecificGlobalCoord.test.js.map +0 -1
  87. package/src/parseGFF.ts +0 -34
  88. package/src/parseNewick.ts +0 -94
  89. package/src/parsers/A3mMSA.test.ts +0 -164
  90. package/src/parsers/A3mMSA.ts +0 -321
  91. package/src/parsers/ClustalMSA.ts +0 -69
  92. package/src/parsers/EmfMSA.ts +0 -67
  93. package/src/parsers/EmfTree.ts +0 -9
  94. package/src/parsers/FastaMSA.ts +0 -82
  95. package/src/parsers/StockholmMSA.ts +0 -140
  96. package/src/seqCoordToRowSpecificGlobalCoord.test.ts +0 -53
  97. package/src/seqCoordToRowSpecificGlobalCoord.ts +0 -25
  98. /package/dist/{parsers/A3mMSA.test.d.ts → seqPosToGlobalCol.test.d.ts} +0 -0
package/dist/model.d.ts CHANGED
@@ -1,8 +1,4 @@
1
- import A3mMSA from './parsers/A3mMSA';
2
- import ClustalMSA from './parsers/ClustalMSA';
3
- import EmfMSA from './parsers/EmfMSA';
4
- import FastaMSA from './parsers/FastaMSA';
5
- import StockholmMSA from './parsers/StockholmMSA';
1
+ import { A3mMSA, ClustalMSA, EmfMSA, FastaMSA, StockholmMSA } from '@react-msaview/parsers';
6
2
  import type { InterProScanResults } from './launchInterProScan';
7
3
  import type { Accession, BasicTrack, NodeWithIds, NodeWithIdsAndLength } from './types';
8
4
  import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types';
@@ -195,6 +191,57 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
195
191
  authInfo: import("mobx-state-tree").IType<any, any, any>;
196
192
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
197
193
  }>> & import("mobx-state-tree/dist/internal").NonEmptyObject)>, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
194
+ gffFilehandle: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISnapshotProcessor<import("mobx-state-tree").ITypeUnion<import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
195
+ locationType: import("mobx-state-tree").ISimpleType<"UriLocation">;
196
+ uri: import("mobx-state-tree").ISimpleType<string>;
197
+ baseUri: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
198
+ internetAccountId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
199
+ internetAccountPreAuthorization: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
200
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
201
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
202
+ }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
203
+ }>> | import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
204
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
205
+ name: import("mobx-state-tree").ISimpleType<string>;
206
+ blobId: import("mobx-state-tree").ISimpleType<string>;
207
+ }>> | import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
208
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
209
+ localPath: import("mobx-state-tree").ISimpleType<string>;
210
+ }>>, {
211
+ locationType: "UriLocation";
212
+ uri: string;
213
+ internetAccountId: string | undefined;
214
+ internetAccountPreAuthorization: import("mobx-state-tree").ModelSnapshotType<{
215
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
216
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
217
+ }> | undefined;
218
+ } | import("mobx-state-tree").ModelSnapshotType<{
219
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
220
+ name: import("mobx-state-tree").ISimpleType<string>;
221
+ blobId: import("mobx-state-tree").ISimpleType<string>;
222
+ }> | import("mobx-state-tree").ModelSnapshotType<{
223
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
224
+ localPath: import("mobx-state-tree").ISimpleType<string>;
225
+ }>, import("mobx-state-tree").ModelInstanceType<{
226
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
227
+ name: import("mobx-state-tree").ISimpleType<string>;
228
+ blobId: import("mobx-state-tree").ISimpleType<string>;
229
+ }, {}> | import("mobx-state-tree").ModelInstanceType<{
230
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
231
+ localPath: import("mobx-state-tree").ISimpleType<string>;
232
+ }, {}> | ({
233
+ locationType: "UriLocation";
234
+ uri: string;
235
+ } & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
236
+ locationType: import("mobx-state-tree").ISimpleType<"UriLocation">;
237
+ uri: import("mobx-state-tree").ISimpleType<string>;
238
+ baseUri: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
239
+ internetAccountId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
240
+ internetAccountPreAuthorization: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
241
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
242
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
243
+ }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
244
+ }>> & import("mobx-state-tree/dist/internal").NonEmptyObject)>, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
198
245
  currentAlignment: import("mobx-state-tree").IType<number | undefined, number, number>;
199
246
  collapsed: import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>;
200
247
  collapsedLeaves: import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>;
@@ -308,6 +355,11 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
308
355
  nodeId: string;
309
356
  descendantNames: string[];
310
357
  } | undefined;
358
+ /**
359
+ * #volatile
360
+ * array of column indices to highlight
361
+ */
362
+ highlightedColumns: number[] | undefined;
311
363
  /**
312
364
  * #volatile
313
365
  * a dummy variable that is incremented when ref changes so autorun for
@@ -390,6 +442,11 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
390
442
  * set hovered tree node and its descendants
391
443
  */
392
444
  setHoveredTreeNode(nodeId?: string): void;
445
+ /**
446
+ * #action
447
+ * set highlighted columns
448
+ */
449
+ setHighlightedColumns(columns?: number[]): void;
393
450
  /**
394
451
  * #action
395
452
  */
@@ -451,6 +508,10 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
451
508
  * #action
452
509
  */
453
510
  setTreeFilehandle(treeFilehandle?: FileLocationType): void;
511
+ /**
512
+ * #action
513
+ */
514
+ setGFFFilehandle(gffFilehandle?: FileLocationType): void;
454
515
  /**
455
516
  * #action
456
517
  */
@@ -651,6 +712,11 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
651
712
  * #getter
652
713
  */
653
714
  readonly allBranchesLength0: boolean;
715
+ /**
716
+ * #getter
717
+ * effective showBranchLen accounting for allBranchesLength0
718
+ */
719
+ readonly showBranchLenEffective: boolean;
654
720
  } & {
655
721
  /**
656
722
  * #getter
@@ -790,27 +856,62 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
790
856
  readonly rowNamesSet: Map<string, number>;
791
857
  /**
792
858
  * #method
793
- * return a row-specific letter, or undefined if gap
859
+ * Return a row-specific letter at a visible column, or undefined if gap.
860
+ *
861
+ * @param rowName - The name of the row
862
+ * @param visibleCol - The visible column index (what the user sees on screen)
863
+ * @returns The letter at that position, or undefined if it's a gap
864
+ */
865
+ visibleColToRowLetter(rowName: string, visibleCol: number): string | undefined;
866
+ /**
867
+ * #method
868
+ * Convert a visible column to a row-specific sequence position (0-based).
869
+ * Returns undefined if the position is a gap in the sequence.
870
+ *
871
+ * @param rowName - The name of the row
872
+ * @param visibleCol - The visible column index
873
+ * @returns The sequence position (0-based), or undefined if it's a gap
874
+ */
875
+ visibleColToSeqPos(rowName: string, visibleCol: number): number | undefined;
876
+ /**
877
+ * #method
878
+ * Convert a visible column to a row-specific sequence position (1-based).
879
+ * Returns undefined if the position is a gap in the sequence.
880
+ *
881
+ * @param rowName - The name of the row
882
+ * @param visibleCol - The visible column index
883
+ * @returns The sequence position (1-based), or undefined if it's a gap
794
884
  */
795
- mouseOverCoordToRowLetter(rowName: string, pos: number): string | undefined;
885
+ visibleColToSeqPosOneBased(rowName: string, visibleCol: number): number | undefined;
796
886
  /**
797
887
  * #method
798
- * return a row-specific sequence coordinate, skipping gaps, given a
799
- * global coordinate
888
+ * Convert a global column index to a visible column index.
889
+ * Returns undefined if the column is hidden (in blanks).
890
+ * This is the inverse of visibleColToGlobalCol.
891
+ *
892
+ * @param globalCol - The global column index in the full MSA
893
+ * @returns The visible column index, or undefined if the column is hidden
800
894
  */
801
- mouseOverCoordToGapRemovedRowCoord(rowName: string, position: number): number | undefined;
895
+ globalColToVisibleCol(globalCol: number): number | undefined;
802
896
  /**
803
897
  * #method
804
- * return a row-specific sequence coordinate, skipping gaps, given a
805
- * global coordinate
898
+ * Convert a sequence position (ungapped) to a global column index.
899
+ *
900
+ * @param rowName - The name of the row
901
+ * @param seqPos - The sequence position (0-based, ungapped)
902
+ * @returns The global column index in the full MSA
806
903
  */
807
- mouseOverCoordToGapRemovedRowCoordOneBased(rowName: string, position: number): number | undefined;
904
+ seqPosToGlobalCol(rowName: string, seqPos: number): number;
808
905
  /**
809
906
  * #method
810
- * return a global coordinate given a row-specific sequence coordinate
811
- * which does not not include gaps
907
+ * Convert a sequence position (ungapped) directly to a visible column index.
908
+ * This combines seqPosToGlobalCol and globalColToVisibleCol.
909
+ *
910
+ * @param rowName - The name of the row
911
+ * @param seqPos - The sequence position (0-based, ungapped)
912
+ * @returns The visible column index, or undefined if the column is hidden
812
913
  */
813
- seqCoordToRowSpecificGlobalCoord(rowName: string, position: number): number;
914
+ seqPosToVisibleCol(rowName: string, seqPos: number): number | undefined;
814
915
  } & {
815
916
  /**
816
917
  * #getter
@@ -1113,6 +1214,57 @@ declare function stateModelFactory(): import("mobx-state-tree").IModelType<{
1113
1214
  authInfo: import("mobx-state-tree").IType<any, any, any>;
1114
1215
  }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
1115
1216
  }>> & import("mobx-state-tree/dist/internal").NonEmptyObject)>, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
1217
+ gffFilehandle: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISnapshotProcessor<import("mobx-state-tree").ITypeUnion<import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
1218
+ locationType: import("mobx-state-tree").ISimpleType<"UriLocation">;
1219
+ uri: import("mobx-state-tree").ISimpleType<string>;
1220
+ baseUri: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
1221
+ internetAccountId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
1222
+ internetAccountPreAuthorization: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
1223
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
1224
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
1225
+ }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
1226
+ }>> | import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
1227
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
1228
+ name: import("mobx-state-tree").ISimpleType<string>;
1229
+ blobId: import("mobx-state-tree").ISimpleType<string>;
1230
+ }>> | import("mobx-state-tree").ModelCreationType<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
1231
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
1232
+ localPath: import("mobx-state-tree").ISimpleType<string>;
1233
+ }>>, {
1234
+ locationType: "UriLocation";
1235
+ uri: string;
1236
+ internetAccountId: string | undefined;
1237
+ internetAccountPreAuthorization: import("mobx-state-tree").ModelSnapshotType<{
1238
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
1239
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
1240
+ }> | undefined;
1241
+ } | import("mobx-state-tree").ModelSnapshotType<{
1242
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
1243
+ name: import("mobx-state-tree").ISimpleType<string>;
1244
+ blobId: import("mobx-state-tree").ISimpleType<string>;
1245
+ }> | import("mobx-state-tree").ModelSnapshotType<{
1246
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
1247
+ localPath: import("mobx-state-tree").ISimpleType<string>;
1248
+ }>, import("mobx-state-tree").ModelInstanceType<{
1249
+ locationType: import("mobx-state-tree").ISimpleType<"BlobLocation">;
1250
+ name: import("mobx-state-tree").ISimpleType<string>;
1251
+ blobId: import("mobx-state-tree").ISimpleType<string>;
1252
+ }, {}> | import("mobx-state-tree").ModelInstanceType<{
1253
+ locationType: import("mobx-state-tree").ISimpleType<"LocalPathLocation">;
1254
+ localPath: import("mobx-state-tree").ISimpleType<string>;
1255
+ }, {}> | ({
1256
+ locationType: "UriLocation";
1257
+ uri: string;
1258
+ } & Partial<import("mobx-state-tree/dist/internal").ExtractCFromProps<{
1259
+ locationType: import("mobx-state-tree").ISimpleType<"UriLocation">;
1260
+ uri: import("mobx-state-tree").ISimpleType<string>;
1261
+ baseUri: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
1262
+ internetAccountId: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
1263
+ internetAccountPreAuthorization: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
1264
+ internetAccountType: import("mobx-state-tree").ISimpleType<string>;
1265
+ authInfo: import("mobx-state-tree").IType<any, any, any>;
1266
+ }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
1267
+ }>> & import("mobx-state-tree/dist/internal").NonEmptyObject)>, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
1116
1268
  currentAlignment: import("mobx-state-tree").IType<number | undefined, number, number>;
1117
1269
  collapsed: import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>;
1118
1270
  collapsedLeaves: import("mobx-state-tree").IArrayType<import("mobx-state-tree").ISimpleType<string>>;
package/dist/model.js CHANGED
@@ -1,14 +1,13 @@
1
1
  import { clamp, fetchAndMaybeUnzipText, groupBy, localStorageGetBoolean, localStorageSetBoolean, notEmpty, sum, } from '@jbrowse/core/util';
2
2
  import { openLocation } from '@jbrowse/core/util/io';
3
3
  import { ElementId, FileLocation } from '@jbrowse/core/util/types/mst';
4
+ import { A3mMSA, ClustalMSA, EmfMSA, FastaMSA, StockholmMSA, generateNodeIds, gffToInterProResults, parseEmfTree, parseGFF, parseNewick, stockholmSniff, } from '@react-msaview/parsers';
4
5
  import { colord } from 'colord';
5
6
  import { ascending } from 'd3-array';
6
7
  import { cluster, hierarchy } from 'd3-hierarchy';
7
- import { parseEmfTree } from 'emf-js';
8
8
  import { saveAs } from 'file-saver';
9
9
  import { autorun, transaction } from 'mobx';
10
10
  import { addDisposer, cast, types } from 'mobx-state-tree';
11
- import Stockholm from 'stockholm-js';
12
11
  import { blocksX, blocksY } from './calculateBlocks';
13
12
  import colorSchemes from './colorSchemes';
14
13
  import ConservationTrack from './components/ConservationTrack';
@@ -23,16 +22,10 @@ import { MSAModelF } from './model/msaModel';
23
22
  import { TreeModelF } from './model/treeModel';
24
23
  import { calculateNeighborJoiningTree } from './neighborJoining';
25
24
  import { parseAsn1 } from './parseAsn1';
26
- import parseNewick from './parseNewick';
27
- import A3mMSA from './parsers/A3mMSA';
28
- import ClustalMSA from './parsers/ClustalMSA';
29
- import EmfMSA from './parsers/EmfMSA';
30
- import FastaMSA from './parsers/FastaMSA';
31
- import StockholmMSA from './parsers/StockholmMSA';
32
25
  import { reparseTree } from './reparseTree';
33
- import { mouseOverCoordToGapRemovedRowCoord, mouseOverCoordToGlobalCoord, } from './rowCoordinateCalculations';
34
- import { seqCoordToRowSpecificGlobalCoord } from './seqCoordToRowSpecificGlobalCoord';
35
- import { collapse, generateNodeIds, len, maxLength, setBrLength, skipBlanks, } from './util';
26
+ import { globalColToVisibleCol, visibleColToGlobalCol, visibleColToSeqPosForRow, } from './rowCoordinateCalculations';
27
+ import { seqPosToGlobalCol } from './seqPosToGlobalCol';
28
+ import { collapse, len, maxLength, setBrLength, skipBlanks } from './util';
36
29
  const showZoomStarKey = 'msa-showZoomStar';
37
30
  /**
38
31
  * #stateModel MsaView
@@ -119,6 +112,11 @@ function stateModelFactory() {
119
112
  * filehandle object for tree metadata
120
113
  */
121
114
  treeMetadataFilehandle: types.maybe(FileLocation),
115
+ /**
116
+ * #property
117
+ * filehandle object for InterProScan GFF file
118
+ */
119
+ gffFilehandle: types.maybe(FileLocation),
122
120
  /**
123
121
  * #property
124
122
  *
@@ -232,6 +230,11 @@ function stateModelFactory() {
232
230
  * the currently hovered tree node ID and its descendant leaf names
233
231
  */
234
232
  hoveredTreeNode: undefined,
233
+ /**
234
+ * #volatile
235
+ * array of column indices to highlight
236
+ */
237
+ highlightedColumns: undefined,
235
238
  /**
236
239
  * #volatile
237
240
  * a dummy variable that is incremented when ref changes so autorun for
@@ -349,6 +352,13 @@ function stateModelFactory() {
349
352
  const descendantNames = node.leaves().map((leaf) => leaf.data.name);
350
353
  self.hoveredTreeNode = { nodeId, descendantNames };
351
354
  },
355
+ /**
356
+ * #action
357
+ * set highlighted columns
358
+ */
359
+ setHighlightedColumns(columns) {
360
+ self.highlightedColumns = columns;
361
+ },
352
362
  /**
353
363
  * #action
354
364
  */
@@ -443,6 +453,12 @@ function stateModelFactory() {
443
453
  setTreeFilehandle(treeFilehandle) {
444
454
  self.treeFilehandle = treeFilehandle;
445
455
  },
456
+ /**
457
+ * #action
458
+ */
459
+ setGFFFilehandle(gffFilehandle) {
460
+ self.gffFilehandle = gffFilehandle;
461
+ },
446
462
  /**
447
463
  * #action
448
464
  */
@@ -557,7 +573,7 @@ function stateModelFactory() {
557
573
  get MSA() {
558
574
  const text = self.data.msa;
559
575
  if (text) {
560
- if (Stockholm.sniff(text)) {
576
+ if (stockholmSniff(text)) {
561
577
  return new StockholmMSA(text, self.currentAlignment);
562
578
  }
563
579
  else if (A3mMSA.sniff(text)) {
@@ -1046,6 +1062,13 @@ function stateModelFactory() {
1046
1062
  get allBranchesLength0() {
1047
1063
  return this.hierarchy.links().every(s => !s.source.data.length);
1048
1064
  },
1065
+ /**
1066
+ * #getter
1067
+ * effective showBranchLen accounting for allBranchesLength0
1068
+ */
1069
+ get showBranchLenEffective() {
1070
+ return this.allBranchesLength0 ? false : self.showBranchLen;
1071
+ },
1049
1072
  }))
1050
1073
  .views(self => ({
1051
1074
  /**
@@ -1314,49 +1337,93 @@ function stateModelFactory() {
1314
1337
  },
1315
1338
  /**
1316
1339
  * #method
1317
- * return a row-specific letter, or undefined if gap
1340
+ * Return a row-specific letter at a visible column, or undefined if gap.
1341
+ *
1342
+ * @param rowName - The name of the row
1343
+ * @param visibleCol - The visible column index (what the user sees on screen)
1344
+ * @returns The letter at that position, or undefined if it's a gap
1318
1345
  */
1319
- mouseOverCoordToRowLetter(rowName, pos) {
1346
+ visibleColToRowLetter(rowName, visibleCol) {
1320
1347
  const { rowMap, blanks } = self;
1321
- return rowMap.get(rowName)?.[mouseOverCoordToGlobalCoord(blanks, pos)];
1348
+ return rowMap.get(rowName)?.[visibleColToGlobalCol(blanks, visibleCol)];
1322
1349
  },
1323
1350
  /**
1324
1351
  * #method
1325
- * return a row-specific sequence coordinate, skipping gaps, given a
1326
- * global coordinate
1352
+ * Convert a visible column to a row-specific sequence position (0-based).
1353
+ * Returns undefined if the position is a gap in the sequence.
1354
+ *
1355
+ * @param rowName - The name of the row
1356
+ * @param visibleCol - The visible column index
1357
+ * @returns The sequence position (0-based), or undefined if it's a gap
1327
1358
  */
1328
- mouseOverCoordToGapRemovedRowCoord(rowName, position) {
1329
- return mouseOverCoordToGapRemovedRowCoord({
1359
+ visibleColToSeqPos(rowName, visibleCol) {
1360
+ return visibleColToSeqPosForRow({
1330
1361
  rowName,
1331
- position,
1362
+ visibleCol,
1332
1363
  rowMap: self.rowMap,
1333
1364
  blanks: self.blanks,
1334
1365
  });
1335
1366
  },
1336
1367
  /**
1337
1368
  * #method
1338
- * return a row-specific sequence coordinate, skipping gaps, given a
1339
- * global coordinate
1369
+ * Convert a visible column to a row-specific sequence position (1-based).
1370
+ * Returns undefined if the position is a gap in the sequence.
1371
+ *
1372
+ * @param rowName - The name of the row
1373
+ * @param visibleCol - The visible column index
1374
+ * @returns The sequence position (1-based), or undefined if it's a gap
1340
1375
  */
1341
- mouseOverCoordToGapRemovedRowCoordOneBased(rowName, position) {
1342
- const val = this.mouseOverCoordToGapRemovedRowCoord(rowName, position);
1376
+ visibleColToSeqPosOneBased(rowName, visibleCol) {
1377
+ const val = this.visibleColToSeqPos(rowName, visibleCol);
1343
1378
  return val !== undefined ? val + 1 : undefined;
1344
1379
  },
1345
1380
  /**
1346
1381
  * #method
1347
- * return a global coordinate given a row-specific sequence coordinate
1348
- * which does not not include gaps
1382
+ * Convert a global column index to a visible column index.
1383
+ * Returns undefined if the column is hidden (in blanks).
1384
+ * This is the inverse of visibleColToGlobalCol.
1385
+ *
1386
+ * @param globalCol - The global column index in the full MSA
1387
+ * @returns The visible column index, or undefined if the column is hidden
1388
+ */
1389
+ globalColToVisibleCol(globalCol) {
1390
+ const { blanks, hideGapsEffective } = self;
1391
+ if (!hideGapsEffective) {
1392
+ return globalCol;
1393
+ }
1394
+ return globalColToVisibleCol(blanks, globalCol);
1395
+ },
1396
+ /**
1397
+ * #method
1398
+ * Convert a sequence position (ungapped) to a global column index.
1399
+ *
1400
+ * @param rowName - The name of the row
1401
+ * @param seqPos - The sequence position (0-based, ungapped)
1402
+ * @returns The global column index in the full MSA
1349
1403
  */
1350
- seqCoordToRowSpecificGlobalCoord(rowName, position) {
1404
+ seqPosToGlobalCol(rowName, seqPos) {
1351
1405
  const { rowNames, rows } = self;
1352
1406
  const index = rowNames.indexOf(rowName);
1353
1407
  return index !== -1 && rows[index]
1354
- ? seqCoordToRowSpecificGlobalCoord({
1408
+ ? seqPosToGlobalCol({
1355
1409
  row: rows[index][1],
1356
- position,
1410
+ seqPos,
1357
1411
  })
1358
1412
  : 0;
1359
1413
  },
1414
+ /**
1415
+ * #method
1416
+ * Convert a sequence position (ungapped) directly to a visible column index.
1417
+ * This combines seqPosToGlobalCol and globalColToVisibleCol.
1418
+ *
1419
+ * @param rowName - The name of the row
1420
+ * @param seqPos - The sequence position (0-based, ungapped)
1421
+ * @returns The visible column index, or undefined if the column is hidden
1422
+ */
1423
+ seqPosToVisibleCol(rowName, seqPos) {
1424
+ const globalCol = this.seqPosToGlobalCol(rowName, seqPos);
1425
+ return this.globalColToVisibleCol(globalCol);
1426
+ },
1360
1427
  }))
1361
1428
  .views(self => ({
1362
1429
  /**
@@ -1595,6 +1662,26 @@ function stateModelFactory() {
1595
1662
  }
1596
1663
  }
1597
1664
  }));
1665
+ // autorun opens gffFilehandle for InterProScan domains
1666
+ addDisposer(self, autorun(async () => {
1667
+ const { gffFilehandle } = self;
1668
+ if (gffFilehandle) {
1669
+ try {
1670
+ const gffText = await fetchAndMaybeUnzipText(openLocation(gffFilehandle));
1671
+ const gffRecords = parseGFF(gffText);
1672
+ const interProResults = gffToInterProResults(gffRecords);
1673
+ self.setInterProAnnotations(interProResults);
1674
+ self.setShowDomains(true);
1675
+ if (gffFilehandle.locationType === 'BlobLocation') {
1676
+ self.setGFFFilehandle(undefined);
1677
+ }
1678
+ }
1679
+ catch (e) {
1680
+ console.error(e);
1681
+ self.setError(e);
1682
+ }
1683
+ }
1684
+ }));
1598
1685
  // autorun opens msaFilehandle
1599
1686
  addDisposer(self, autorun(async () => {
1600
1687
  const { msaFilehandle } = self;