@czi-sds/mcp 0.20.1 → 0.20.2

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.
@@ -877,7 +877,7 @@ export default App;
877
877
 
878
878
  ### Complexes and chains
879
879
 
880
- A multi-chain structure needs nothing special: pass the whole complex as one structure string and the viewer finds the chains itself, reporting them through `onChainsChange` as `ChainRef`s. It draws one cartoon per chain, splits the sequence panel into one grid per chain, and - when neither `plddt` nor `residueOverlay` is coloring the structure - paints each chain its own color and shows a chain legend with a swatch and a visibility toggle for each.
880
+ A multi-chain structure needs nothing special: pass the whole complex as one structure string and the viewer finds the chains itself, reporting them through `onChainsChange` as `ChainRef`s. It draws one cartoon per chain, splits the sequence panel into one grid per chain, and - when chain coloring is what paints the structure - paints each chain its own color and shows a chain legend with a swatch and a visibility toggle for each.
881
881
 
882
882
  Visibility works out of the box: the toggles own it unless you pass `hiddenChains`, which takes it over and leaves the toggles reporting through `onChainVisibilityChange`. Hiding a chain removes everything it is drawn with, which also takes it out of reach of hover and click; its sequence stays in the panel, dimmed, so the panel does not reflow on every toggle. `chainColors` overrides the palette per chain.
883
883
 
@@ -1200,6 +1200,341 @@ They belong to the chain they sit on, so hiding that chain takes them with it an
1200
1200
 
1201
1201
  Bulk water is the exception, and is not drawn. A structure's worth of solvent rendered as sticks buries the structure it surrounds.
1202
1202
 
1203
+ ### Representation, coloring and highlights
1204
+
1205
+ `representation` draws the polymer as a cartoon, the default, or as a molecular surface. The surface is one surface over every visible chain rather than one per chain, so where two chains meet the interface is buried - and hiding a partner rebuilds it over what is left, exposing the face the partner was bound to. Ligands stay ball-and-stick either way. A surface too large to compute keeps the cartoon in its place and is reported to `onError` as a `"representation"` failure.
1206
+
1207
+ `colorBy` names what paints the structure. Left undefined it follows what is supplied - an overlay, then pLDDT, then chain colors - and naming one is how a toggle keeps both `plddt` and `chainColors` in place while it switches between them. The legend follows whichever is painting. A `null` in `plddt`, or a residue past its end, reads as unscored and is painted neutral rather than at the bottom of the scale, and the structure text is parsed exactly as given: scores are read by residue, not written into the file's B-factor column.
1208
+
1209
+ `highlights` picks residues out in colors of their own, by the chain, number and insertion code the file gives them. They paint over whatever colors the rest, and are drawn in ball-and-stick over the cartoon; a surface carries them in its own colors. Highlights that name no color take the viewer's palette in turn, which is exported as `HIGHLIGHT_COLOR_PALETTE` for a legend of your own. They are separate from the selection: highlighting a residue neither selects it nor moves the camera. `selection.addresses` selects by the same kind of address.
1210
+
1211
+ Every one of these changes is made in place, so the camera stays wherever it was left.
1212
+
1213
+ **Example: SceneProteinStructureViewer**
1214
+
1215
+ ```tsx
1216
+ // What is drawn, and how it is painted, are props: `representation` swaps the
1217
+ // cartoon for a molecular surface, `colorBy` switches between confidence and
1218
+ // chain coloring with both supplied, and `highlights` picks residues out by the
1219
+ // address the file gives them, in colors of their own. `orientation` turns the
1220
+ // camera to face the highlights when the structure loads.
1221
+ //
1222
+ // Every change is made in place, so the camera stays wherever it was left. The
1223
+ // scores below have a gap: residues without one read as unscored gray rather
1224
+ // than at the bottom of the scale.
1225
+ //
1226
+ // The structure is crambin (PDB 1CRN), trimmed to its backbone atoms.
1227
+
1228
+ import { Button } from "@czi-sds/components";
1229
+ import {
1230
+ ProteinStructureViewer,
1231
+ ResidueHighlight,
1232
+ StructureColorBy,
1233
+ StructureRepresentation,
1234
+ } from "@czi-sds/data-viz";
1235
+ import { useState } from "react";
1236
+
1237
+ const PDB = `
1238
+ ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N
1239
+ ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C
1240
+ ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C
1241
+ ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O
1242
+ ATOM 5 N THR A 2 15.115 11.555 5.265 1.00 7.81 N
1243
+ ATOM 6 CA THR A 2 13.856 11.469 6.066 1.00 8.31 C
1244
+ ATOM 7 C THR A 2 14.164 10.785 7.379 1.00 5.80 C
1245
+ ATOM 8 O THR A 2 14.993 9.862 7.443 1.00 6.94 O
1246
+ ATOM 9 N CYS A 3 13.488 11.241 8.417 1.00 5.24 N
1247
+ ATOM 10 CA CYS A 3 13.660 10.707 9.787 1.00 5.39 C
1248
+ ATOM 11 C CYS A 3 12.269 10.431 10.323 1.00 4.45 C
1249
+ ATOM 12 O CYS A 3 11.393 11.308 10.185 1.00 6.54 O
1250
+ ATOM 13 N CYS A 4 12.019 9.272 10.928 1.00 3.90 N
1251
+ ATOM 14 CA CYS A 4 10.646 8.991 11.408 1.00 4.24 C
1252
+ ATOM 15 C CYS A 4 10.654 8.793 12.919 1.00 3.72 C
1253
+ ATOM 16 O CYS A 4 11.659 8.296 13.491 1.00 5.30 O
1254
+ ATOM 17 N PRO A 5 9.561 9.108 13.563 1.00 3.96 N
1255
+ ATOM 18 CA PRO A 5 9.448 9.034 15.012 1.00 4.25 C
1256
+ ATOM 19 C PRO A 5 9.288 7.670 15.606 1.00 4.96 C
1257
+ ATOM 20 O PRO A 5 9.490 7.519 16.819 1.00 7.44 O
1258
+ ATOM 21 N SER A 6 8.875 6.686 14.796 1.00 4.83 N
1259
+ ATOM 22 CA SER A 6 8.673 5.314 15.279 1.00 4.45 C
1260
+ ATOM 23 C SER A 6 8.753 4.376 14.083 1.00 4.99 C
1261
+ ATOM 24 O SER A 6 8.726 4.858 12.923 1.00 4.61 O
1262
+ ATOM 25 N ILE A 7 8.881 3.075 14.358 1.00 4.94 N
1263
+ ATOM 26 CA ILE A 7 8.912 2.083 13.258 1.00 6.33 C
1264
+ ATOM 27 C ILE A 7 7.581 2.090 12.506 1.00 5.32 C
1265
+ ATOM 28 O ILE A 7 7.670 2.031 11.245 1.00 6.85 O
1266
+ ATOM 29 N VAL A 8 6.458 2.162 13.159 1.00 5.02 N
1267
+ ATOM 30 CA VAL A 8 5.145 2.209 12.453 1.00 6.93 C
1268
+ ATOM 31 C VAL A 8 5.115 3.379 11.461 1.00 5.39 C
1269
+ ATOM 32 O VAL A 8 4.664 3.268 10.343 1.00 6.30 O
1270
+ ATOM 33 N ALA A 9 5.606 4.546 11.941 1.00 3.73 N
1271
+ ATOM 34 CA ALA A 9 5.598 5.767 11.082 1.00 3.56 C
1272
+ ATOM 35 C ALA A 9 6.441 5.527 9.850 1.00 4.13 C
1273
+ ATOM 36 O ALA A 9 6.052 5.933 8.744 1.00 4.36 O
1274
+ ATOM 37 N ARG A 10 7.647 4.909 10.005 1.00 3.73 N
1275
+ ATOM 38 CA ARG A 10 8.496 4.609 8.837 1.00 3.38 C
1276
+ ATOM 39 C ARG A 10 7.798 3.609 7.876 1.00 3.47 C
1277
+ ATOM 40 O ARG A 10 7.878 3.778 6.651 1.00 4.67 O
1278
+ ATOM 41 N SER A 11 7.186 2.582 8.445 1.00 5.19 N
1279
+ ATOM 42 CA SER A 11 6.500 1.584 7.565 1.00 4.60 C
1280
+ ATOM 43 C SER A 11 5.382 2.313 6.773 1.00 4.84 C
1281
+ ATOM 44 O SER A 11 5.213 2.016 5.557 1.00 5.84 O
1282
+ ATOM 45 N ASN A 12 4.648 3.182 7.446 1.00 3.54 N
1283
+ ATOM 46 CA ASN A 12 3.545 3.935 6.751 1.00 4.57 C
1284
+ ATOM 47 C ASN A 12 4.107 4.851 5.691 1.00 4.14 C
1285
+ ATOM 48 O ASN A 12 3.536 5.001 4.617 1.00 5.52 O
1286
+ ATOM 49 N PHE A 13 5.259 5.498 6.005 1.00 3.43 N
1287
+ ATOM 50 CA PHE A 13 5.929 6.358 5.055 1.00 3.49 C
1288
+ ATOM 51 C PHE A 13 6.304 5.578 3.799 1.00 3.40 C
1289
+ ATOM 52 O PHE A 13 6.136 6.072 2.653 1.00 4.07 O
1290
+ ATOM 53 N ASN A 14 6.900 4.390 3.989 1.00 3.64 N
1291
+ ATOM 54 CA ASN A 14 7.331 3.607 2.791 1.00 4.31 C
1292
+ ATOM 55 C ASN A 14 6.116 3.210 1.915 1.00 3.98 C
1293
+ ATOM 56 O ASN A 14 6.240 3.144 0.684 1.00 6.22 O
1294
+ ATOM 57 N VAL A 15 4.993 2.927 2.571 1.00 3.76 N
1295
+ ATOM 58 CA VAL A 15 3.782 2.599 1.742 1.00 3.98 C
1296
+ ATOM 59 C VAL A 15 3.296 3.871 1.004 1.00 3.80 C
1297
+ ATOM 60 O VAL A 15 2.947 3.817 -0.189 1.00 4.85 O
1298
+ ATOM 61 N CYS A 16 3.321 4.987 1.720 1.00 3.79 N
1299
+ ATOM 62 CA CYS A 16 2.890 6.285 1.126 1.00 3.54 C
1300
+ ATOM 63 C CYS A 16 3.687 6.597 -0.111 1.00 3.48 C
1301
+ ATOM 64 O CYS A 16 3.200 7.147 -1.103 1.00 4.63 O
1302
+ ATOM 65 N ARG A 17 4.997 6.227 -0.100 1.00 3.99 N
1303
+ ATOM 66 CA ARG A 17 5.895 6.489 -1.213 1.00 3.83 C
1304
+ ATOM 67 C ARG A 17 5.738 5.560 -2.409 1.00 3.79 C
1305
+ ATOM 68 O ARG A 17 6.228 5.901 -3.507 1.00 5.39 O
1306
+ ATOM 69 N LEU A 18 5.051 4.411 -2.204 1.00 4.70 N
1307
+ ATOM 70 CA LEU A 18 4.933 3.431 -3.326 1.00 5.46 C
1308
+ ATOM 71 C LEU A 18 4.397 4.014 -4.620 1.00 5.13 C
1309
+ ATOM 72 O LEU A 18 4.988 3.755 -5.687 1.00 5.55 O
1310
+ ATOM 73 N PRO A 19 3.329 4.795 -4.543 1.00 4.28 N
1311
+ ATOM 74 CA PRO A 19 2.792 5.376 -5.797 1.00 5.38 C
1312
+ ATOM 75 C PRO A 19 3.573 6.540 -6.322 1.00 6.30 C
1313
+ ATOM 76 O PRO A 19 3.260 7.045 -7.422 1.00 9.62 O
1314
+ ATOM 77 N GLY A 20 4.565 7.047 -5.559 1.00 4.94 N
1315
+ ATOM 78 CA GLY A 20 5.366 8.191 -6.018 1.00 5.39 C
1316
+ ATOM 79 C GLY A 20 5.007 9.481 -5.280 1.00 5.03 C
1317
+ ATOM 80 O GLY A 20 5.535 10.510 -5.730 1.00 7.34 O
1318
+ ATOM 81 N THR A 21 4.181 9.438 -4.262 1.00 4.10 N
1319
+ ATOM 82 CA THR A 21 3.767 10.609 -3.513 1.00 3.94 C
1320
+ ATOM 83 C THR A 21 5.017 11.397 -3.042 1.00 3.96 C
1321
+ ATOM 84 O THR A 21 5.947 10.757 -2.523 1.00 5.82 O
1322
+ ATOM 85 N PRO A 22 4.971 12.703 -3.176 1.00 5.04 N
1323
+ ATOM 86 CA PRO A 22 6.143 13.513 -2.696 1.00 4.69 C
1324
+ ATOM 87 C PRO A 22 6.400 13.233 -1.225 1.00 4.19 C
1325
+ ATOM 88 O PRO A 22 5.485 13.061 -0.382 1.00 4.47 O
1326
+ ATOM 89 N GLU A 23 7.728 13.297 -0.921 1.00 5.16 N
1327
+ ATOM 90 CA GLU A 23 8.114 13.103 0.500 1.00 5.31 C
1328
+ ATOM 91 C GLU A 23 7.427 14.073 1.410 1.00 4.11 C
1329
+ ATOM 92 O GLU A 23 7.036 13.682 2.540 1.00 5.11 O
1330
+ ATOM 93 N ALA A 24 7.212 15.334 0.966 1.00 4.56 N
1331
+ ATOM 94 CA ALA A 24 6.614 16.317 1.913 1.00 4.49 C
1332
+ ATOM 95 C ALA A 24 5.212 15.936 2.350 1.00 4.10 C
1333
+ ATOM 96 O ALA A 24 4.782 16.166 3.495 1.00 5.64 O
1334
+ ATOM 97 N ILE A 25 4.445 15.318 1.405 1.00 4.37 N
1335
+ ATOM 98 CA ILE A 25 3.074 14.894 1.756 1.00 5.44 C
1336
+ ATOM 99 C ILE A 25 3.085 13.643 2.645 1.00 4.32 C
1337
+ ATOM 100 O ILE A 25 2.315 13.523 3.578 1.00 4.72 O
1338
+ ATOM 101 N CYS A 26 4.032 12.764 2.313 1.00 3.92 N
1339
+ ATOM 102 CA CYS A 26 4.180 11.549 3.187 1.00 4.37 C
1340
+ ATOM 103 C CYS A 26 4.632 11.944 4.596 1.00 3.95 C
1341
+ ATOM 104 O CYS A 26 4.227 11.252 5.547 1.00 4.74 O
1342
+ ATOM 105 N ALA A 27 5.408 13.012 4.694 1.00 3.89 N
1343
+ ATOM 106 CA ALA A 27 5.879 13.502 6.026 1.00 4.43 C
1344
+ ATOM 107 C ALA A 27 4.696 13.908 6.882 1.00 4.26 C
1345
+ ATOM 108 O ALA A 27 4.528 13.422 8.025 1.00 5.44 O
1346
+ ATOM 109 N THR A 28 3.827 14.802 6.358 1.00 4.53 N
1347
+ ATOM 110 CA THR A 28 2.691 15.221 7.194 1.00 5.08 C
1348
+ ATOM 111 C THR A 28 1.672 14.132 7.434 1.00 4.62 C
1349
+ ATOM 112 O THR A 28 0.947 14.112 8.468 1.00 7.80 O
1350
+ ATOM 113 N TYR A 29 1.621 13.190 6.511 1.00 5.01 N
1351
+ ATOM 114 CA TYR A 29 0.715 12.045 6.657 1.00 6.60 C
1352
+ ATOM 115 C TYR A 29 1.125 11.125 7.815 1.00 4.92 C
1353
+ ATOM 116 O TYR A 29 0.286 10.632 8.545 1.00 7.13 O
1354
+ ATOM 117 N THR A 30 2.470 10.984 7.995 1.00 5.31 N
1355
+ ATOM 118 CA THR A 30 2.986 9.994 8.950 1.00 5.70 C
1356
+ ATOM 119 C THR A 30 3.609 10.505 10.230 1.00 6.28 C
1357
+ ATOM 120 O THR A 30 3.766 9.715 11.186 1.00 8.77 O
1358
+ ATOM 121 N GLY A 31 3.984 11.764 10.241 1.00 4.99 N
1359
+ ATOM 122 CA GLY A 31 4.769 12.336 11.360 1.00 5.50 C
1360
+ ATOM 123 C GLY A 31 6.255 12.243 11.106 1.00 4.19 C
1361
+ ATOM 124 O GLY A 31 7.037 12.750 11.954 1.00 6.12 O
1362
+ ATOM 125 N CYS A 32 6.710 11.631 9.992 1.00 4.30 N
1363
+ ATOM 126 CA CYS A 32 8.140 11.694 9.635 1.00 4.89 C
1364
+ ATOM 127 C CYS A 32 8.500 13.141 9.206 1.00 5.50 C
1365
+ ATOM 128 O CYS A 32 7.581 13.949 8.944 1.00 5.82 O
1366
+ ATOM 129 N ILE A 33 9.793 13.410 9.173 1.00 6.02 N
1367
+ ATOM 130 CA ILE A 33 10.280 14.760 8.823 1.00 5.24 C
1368
+ ATOM 131 C ILE A 33 11.346 14.658 7.743 1.00 5.16 C
1369
+ ATOM 132 O ILE A 33 11.971 13.583 7.552 1.00 7.19 O
1370
+ ATOM 133 N ILE A 34 11.490 15.773 7.038 1.00 5.52 N
1371
+ ATOM 134 CA ILE A 34 12.552 15.877 6.036 1.00 6.82 C
1372
+ ATOM 135 C ILE A 34 13.590 16.917 6.560 1.00 6.92 C
1373
+ ATOM 136 O ILE A 34 13.168 18.006 6.945 1.00 9.22 O
1374
+ ATOM 137 N ILE A 35 14.856 16.493 6.536 1.00 7.06 N
1375
+ ATOM 138 CA ILE A 35 15.930 17.454 6.941 1.00 7.52 C
1376
+ ATOM 139 C ILE A 35 16.913 17.550 5.819 1.00 6.63 C
1377
+ ATOM 140 O ILE A 35 17.097 16.660 4.970 1.00 7.90 O
1378
+ ATOM 141 N PRO A 36 17.664 18.669 5.806 1.00 8.07 N
1379
+ ATOM 142 CA PRO A 36 18.635 18.861 4.738 1.00 8.78 C
1380
+ ATOM 143 C PRO A 36 19.925 18.042 4.949 1.00 8.31 C
1381
+ ATOM 144 O PRO A 36 20.593 17.742 3.945 1.00 9.09 O
1382
+ ATOM 145 N GLY A 37 20.172 17.730 6.217 1.00 8.48 N
1383
+ ATOM 146 CA GLY A 37 21.452 16.969 6.513 1.00 9.20 C
1384
+ ATOM 147 C GLY A 37 21.143 15.478 6.427 1.00 10.41 C
1385
+ ATOM 148 O GLY A 37 20.138 15.023 5.878 1.00 12.06 O
1386
+ ATOM 149 N ALA A 38 22.055 14.701 7.032 1.00 9.24 N
1387
+ ATOM 150 CA ALA A 38 22.019 13.242 7.020 1.00 9.24 C
1388
+ ATOM 151 C ALA A 38 21.944 12.628 8.396 1.00 9.60 C
1389
+ ATOM 152 O ALA A 38 21.869 11.387 8.435 1.00 13.65 O
1390
+ ATOM 153 N THR A 39 21.894 13.435 9.436 1.00 8.70 N
1391
+ ATOM 154 CA THR A 39 21.936 12.911 10.809 1.00 9.46 C
1392
+ ATOM 155 C THR A 39 20.615 13.191 11.521 1.00 8.32 C
1393
+ ATOM 156 O THR A 39 20.357 14.317 11.948 1.00 9.89 O
1394
+ ATOM 157 N CYS A 40 19.827 12.110 11.642 1.00 7.64 N
1395
+ ATOM 158 CA CYS A 40 18.504 12.312 12.298 1.00 8.05 C
1396
+ ATOM 159 C CYS A 40 18.684 12.451 13.784 1.00 7.63 C
1397
+ ATOM 160 O CYS A 40 19.533 11.718 14.362 1.00 9.64 O
1398
+ ATOM 161 N PRO A 41 17.880 13.266 14.426 1.00 8.00 N
1399
+ ATOM 162 CA PRO A 41 17.924 13.421 15.877 1.00 8.96 C
1400
+ ATOM 163 C PRO A 41 17.392 12.206 16.594 1.00 9.06 C
1401
+ ATOM 164 O PRO A 41 16.652 11.368 16.033 1.00 8.82 O
1402
+ ATOM 165 N GLY A 42 17.728 12.124 17.884 1.00 7.55 N
1403
+ ATOM 166 CA GLY A 42 17.334 10.956 18.691 1.00 8.00 C
1404
+ ATOM 167 C GLY A 42 15.875 10.688 18.871 1.00 7.22 C
1405
+ ATOM 168 O GLY A 42 15.434 9.550 19.166 1.00 8.41 O
1406
+ ATOM 169 N ASP A 43 15.036 11.747 18.715 1.00 5.54 N
1407
+ ATOM 170 CA ASP A 43 13.564 11.573 18.836 1.00 5.85 C
1408
+ ATOM 171 C ASP A 43 12.936 11.227 17.470 1.00 5.87 C
1409
+ ATOM 172 O ASP A 43 11.720 11.040 17.428 1.00 7.29 O
1410
+ ATOM 173 N TYR A 44 13.725 11.174 16.425 1.00 5.22 N
1411
+ ATOM 174 CA TYR A 44 13.257 10.745 15.081 1.00 5.56 C
1412
+ ATOM 175 C TYR A 44 14.275 9.687 14.612 1.00 4.61 C
1413
+ ATOM 176 O TYR A 44 14.930 9.862 13.568 1.00 6.04 O
1414
+ ATOM 177 N ALA A 45 14.342 8.640 15.422 1.00 4.76 N
1415
+ ATOM 178 CA ALA A 45 15.445 7.667 15.246 1.00 5.89 C
1416
+ ATOM 179 C ALA A 45 15.171 6.533 14.280 1.00 6.67 C
1417
+ ATOM 180 O ALA A 45 16.093 5.705 14.039 1.00 7.56 O
1418
+ ATOM 181 N ASN A 46 13.966 6.502 13.739 1.00 5.80 N
1419
+ ATOM 182 CA ASN A 46 13.512 5.395 12.878 1.00 6.15 C
1420
+ ATOM 183 C ASN A 46 13.311 5.853 11.455 1.00 6.61 C
1421
+ ATOM 184 O ASN A 46 13.733 6.929 11.026 1.00 7.18 O
1422
+ END`;
1423
+
1424
+ const PLDDT = [
1425
+ 0.45,
1426
+ 0.515,
1427
+ 0.557,
1428
+ 0.569,
1429
+ 0.567,
1430
+ 0.578,
1431
+ 0.618,
1432
+ 0.681,
1433
+ 0.742,
1434
+ 0.777,
1435
+ 0.782,
1436
+ 0.773,
1437
+ null,
1438
+ null,
1439
+ null,
1440
+ null,
1441
+ 0.933,
1442
+ 0.924,
1443
+ 0.902,
1444
+ 0.892,
1445
+ 0.91,
1446
+ 0.947,
1447
+ 0.98,
1448
+ 0.98,
1449
+ 0.961,
1450
+ 0.92,
1451
+ 0.892,
1452
+ 0.892,
1453
+ 0.911,
1454
+ 0.927,
1455
+ 0.915,
1456
+ 0.873,
1457
+ 0.818,
1458
+ 0.776,
1459
+ 0.762,
1460
+ 0.769,
1461
+ 0.772,
1462
+ 0.748,
1463
+ 0.694,
1464
+ 0.629,
1465
+ 0.578,
1466
+ 0.556,
1467
+ 0.556,
1468
+ 0.552,
1469
+ 0.522,
1470
+ 0.463,
1471
+ ];
1472
+
1473
+ // The three residues are named as the file numbers them. The second takes a
1474
+ // color of its own; the others take the viewer's highlight palette in turn.
1475
+ const HIGHLIGHTS: ResidueHighlight[] = [
1476
+ { chainId: "A", seqId: 3 },
1477
+ { chainId: "A", seqId: 26, color: "#9C27B0" },
1478
+ { chainId: "A", seqId: 40 },
1479
+ ];
1480
+
1481
+ function App() {
1482
+ const [representation, setRepresentation] =
1483
+ useState<StructureRepresentation>("cartoon");
1484
+ const [colorBy, setColorBy] = useState<StructureColorBy>("plddt");
1485
+
1486
+ return (
1487
+ <div
1488
+ className="app"
1489
+ style={{ display: "flex", flexDirection: "column", gap: 8, height: 520 }}
1490
+ >
1491
+ <div style={{ display: "flex", gap: 8 }}>
1492
+ <Button
1493
+ sdsStyle="outline"
1494
+ sdsType="secondary"
1495
+ size="small"
1496
+ onClick={() =>
1497
+ setRepresentation((current) =>
1498
+ current === "cartoon" ? "surface" : "cartoon"
1499
+ )
1500
+ }
1501
+ >
1502
+ {representation === "cartoon" ? "Show surface" : "Show cartoon"}
1503
+ </Button>
1504
+ <Button
1505
+ sdsStyle="outline"
1506
+ sdsType="secondary"
1507
+ size="small"
1508
+ onClick={() =>
1509
+ setColorBy((current) => (current === "plddt" ? "chain" : "plddt"))
1510
+ }
1511
+ >
1512
+ {colorBy === "plddt" ? "Color by chain" : "Color by confidence"}
1513
+ </Button>
1514
+ </div>
1515
+ <div style={{ flex: 1, minHeight: 0 }}>
1516
+ <ProteinStructureViewer
1517
+ structure={PDB}
1518
+ plddt={PLDDT}
1519
+ colorBy={colorBy}
1520
+ representation={representation}
1521
+ highlights={HIGHLIGHTS}
1522
+ orientation="facing"
1523
+ />
1524
+ </div>
1525
+ </div>
1526
+ );
1527
+ }
1528
+
1529
+ export default App;
1530
+ ```
1531
+
1532
+ ### Camera
1533
+
1534
+ `orientation` turns the camera to look at the highlighted residues: `"facing"` looks at them from outside the structure, down the line from its center through theirs; `"opposite"` looks from the far side; `"side"` looks across that line, which puts an interface in profile; and `"overview"` looks down the default axis at the whole structure. It is applied when a structure loads and whenever it changes - not when the highlights do. `projection` sets the camera's projection.
1535
+
1536
+ `onCameraChange` reports the camera each time it comes to rest, whether after a drag, a zoom, a selection framing it or a structure fitting it, as a `CameraState`. Handing that back as `initialCamera` starts the next structure loaded exactly there, in place of fitting it. `onStructureLoad` is told of every structure that loads, reloads included, which is what a "loading" and "ready" state listens for.
1537
+
1203
1538
  ### Structure only
1204
1539
 
1205
1540
  Three props hide the chrome layered around the 3D view. `showSequenceViewer` drops the sequence panel, `showLegend` drops the stats and the color key, and `showAxes` drops the orientation widget and its reset-camera button. Turn off all three when the surrounding page supplies its own controls.
@@ -1461,12 +1796,28 @@ Passing `download` adds a capture button beneath the reset-camera control, which
1461
1796
 
1462
1797
  The image is rendered in its own pass at the size asked for rather than scaled up from the canvas, so it comes out as sharp as the resolution says whatever size the viewer happens to be on screen - and a large one costs time rather than sharpness, which is why the default sits in the middle.
1463
1798
 
1464
- | Name | Type | Default | Description |
1465
- | ----------------- | ------------------------------------------ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1466
- | `resolution` | `"low" \| "medium" \| "high" \| "maximum"` | `"medium"` | 1280x720, 1920x1080, 3840x2160 and 7680x4320 respectively. Also exported as `DOWNLOAD_RESOLUTIONS`, for labelling a control of your own. |
1467
- | `backgroundColor` | `string` | - (transparent) | Background behind the structure, as `#RRGGBB`. Omit for a transparent one, which is what a figure usually wants. The viewer's own canvas color is deliberately not inherited, since an image tends to outlive the theme it was captured under. |
1468
- | `showAxes` | `boolean` | `false` | Draw the orientation axes into the image. Independent of the viewer's own `showAxes`: the widget orients a reader who can turn the structure, and earns its place less in a still, so it can be on screen without being in the capture or the other way about. |
1469
- | `filename` | `string` | - | Name for the file, without an extension. Defaults to the one Mol\* derives from the loaded structure. |
1799
+ | Field | Type | Default | Description |
1800
+ | ----------------- | ---------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1801
+ | `resolution` | `"low" \| "medium" \| "high" \| "maximum"` | `"medium"` | 1280x720, 1920x1080, 3840x2160 and 7680x4320 respectively. Also exported as `DOWNLOAD_RESOLUTIONS`, for labelling a control of your own. |
1802
+ | `backgroundColor` | `string` | - (transparent) | Background behind the structure, as `#RRGGBB`. Omit for a transparent one, which is what a figure usually wants. The viewer's own canvas color is deliberately not inherited, since an image tends to outlive the theme it was captured under. |
1803
+ | `showAxes` | `boolean` | `false` | Draw the orientation axes into the image. Independent of the viewer's own `showAxes`: the widget orients a reader who can turn the structure, and earns its place less in a still, so it can be on screen without being in the capture or the other way about. |
1804
+ | `filename` | `string` | - | Name for the file, without an extension. Defaults to the one Mol\* derives from the loaded structure. |
1805
+ | `render` | `(plugin: PluginUIContext) => Promise<Blob>` | - | Renders the image in place of the viewer's own capture, and resolves with a PNG. `resolution`, `backgroundColor` and `showAxes` describe the viewer's capture, so they are not applied to this one. |
1806
+ | `deliver` | `(image: Blob, filename: string) => void \| Promise<void>` | - | Receives the PNG in place of a browser download, with the name it would have been saved under, `.png` included. |
1807
+
1808
+ The last two take the capture over, and either can be given without the other. `deliver` is for a page that cannot start a download itself: a sandboxed iframe blocks the one a click would start, so the image is handed to a bridge to its host instead. `render` is for an image the presets do not describe - bounded to a size, or keeping the viewport's aspect. A failure in either is reported to `onError`.
1809
+
1810
+ **React TypeScript**
1811
+
1812
+ ```tsx
1813
+ <ProteinStructureViewer
1814
+ structure={PDB}
1815
+ download={{
1816
+ filename: "barnase-barstar",
1817
+ deliver: (image, filename) => host.saveFile(image, filename),
1818
+ }}
1819
+ />
1820
+ ```
1470
1821
 
1471
1822
  ## Configuring Mol\*
1472
1823
 
@@ -1506,42 +1857,343 @@ Two things to know about how it is applied. List-valued keys - `behaviors`, `con
1506
1857
 
1507
1858
  And it is read once, when the plugin is created - except for `canvas3d`, which is re-applied whenever it changes. Creating the plugin throws away the camera, so the rest is deliberately not reactive; pass a `key` to remount the viewer if you need to change it.
1508
1859
 
1860
+ ## Building on the viewer
1861
+
1862
+ `onReady` hands over the Mol\* plugin once a structure is loaded, and again for each structure that replaces it, along with the structure the viewer parsed. That is the way into anything the props do not cover: drawing a representation of your own, registering a color theme, or driving the camera. It is awaited before the viewer starts answering clicks and applying its coloring, so whatever it builds is in place before either reaches it.
1863
+
1864
+ To draw the whole scene yourself, set `sceneMode="external"`. The viewer then parses the structure and stops there: nothing is drawn, colored, hidden or framed, and the canvas is yours. Everything that is not drawing keeps working - the sequence panel, selection, hover, the legend and the camera controls. The chain legend's toggles report through `onChainVisibilityChange` without hiding anything, since what hiding a chain means is now yours to decide, and the legend describes the props rather than what you drew, so pass it the colors you draw with. Mol\* frames the camera on the first representation drawn into the empty scene.
1865
+
1866
+ **Example: ExternalSceneProteinStructureViewer**
1867
+
1868
+ ```tsx
1869
+ // With `sceneMode="external"` the viewer parses the structure and leaves the
1870
+ // canvas to you. `onReady` hands over the Mol* plugin and the parsed structure,
1871
+ // and whatever it draws is the scene - here a molecular surface colored by
1872
+ // hydrophobicity, which no prop of the viewer's asks for.
1873
+ //
1874
+ // Everything that is not drawing works as usual: the sequence panel, hovering
1875
+ // and selecting residues, and the camera controls. Mol* frames the camera on
1876
+ // the first representation drawn into the empty scene.
1877
+ //
1878
+ // The structure is crambin (PDB 1CRN), trimmed to its backbone atoms.
1879
+
1880
+ import { LoadedStructureInfo, ProteinStructureViewer } from "@czi-sds/data-viz";
1881
+ import type { PluginUIContext } from "molstar/lib/mol-plugin-ui/context";
1882
+
1883
+ const PDB = `
1884
+ ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N
1885
+ ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C
1886
+ ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C
1887
+ ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O
1888
+ ATOM 5 N THR A 2 15.115 11.555 5.265 1.00 7.81 N
1889
+ ATOM 6 CA THR A 2 13.856 11.469 6.066 1.00 8.31 C
1890
+ ATOM 7 C THR A 2 14.164 10.785 7.379 1.00 5.80 C
1891
+ ATOM 8 O THR A 2 14.993 9.862 7.443 1.00 6.94 O
1892
+ ATOM 9 N CYS A 3 13.488 11.241 8.417 1.00 5.24 N
1893
+ ATOM 10 CA CYS A 3 13.660 10.707 9.787 1.00 5.39 C
1894
+ ATOM 11 C CYS A 3 12.269 10.431 10.323 1.00 4.45 C
1895
+ ATOM 12 O CYS A 3 11.393 11.308 10.185 1.00 6.54 O
1896
+ ATOM 13 N CYS A 4 12.019 9.272 10.928 1.00 3.90 N
1897
+ ATOM 14 CA CYS A 4 10.646 8.991 11.408 1.00 4.24 C
1898
+ ATOM 15 C CYS A 4 10.654 8.793 12.919 1.00 3.72 C
1899
+ ATOM 16 O CYS A 4 11.659 8.296 13.491 1.00 5.30 O
1900
+ ATOM 17 N PRO A 5 9.561 9.108 13.563 1.00 3.96 N
1901
+ ATOM 18 CA PRO A 5 9.448 9.034 15.012 1.00 4.25 C
1902
+ ATOM 19 C PRO A 5 9.288 7.670 15.606 1.00 4.96 C
1903
+ ATOM 20 O PRO A 5 9.490 7.519 16.819 1.00 7.44 O
1904
+ ATOM 21 N SER A 6 8.875 6.686 14.796 1.00 4.83 N
1905
+ ATOM 22 CA SER A 6 8.673 5.314 15.279 1.00 4.45 C
1906
+ ATOM 23 C SER A 6 8.753 4.376 14.083 1.00 4.99 C
1907
+ ATOM 24 O SER A 6 8.726 4.858 12.923 1.00 4.61 O
1908
+ ATOM 25 N ILE A 7 8.881 3.075 14.358 1.00 4.94 N
1909
+ ATOM 26 CA ILE A 7 8.912 2.083 13.258 1.00 6.33 C
1910
+ ATOM 27 C ILE A 7 7.581 2.090 12.506 1.00 5.32 C
1911
+ ATOM 28 O ILE A 7 7.670 2.031 11.245 1.00 6.85 O
1912
+ ATOM 29 N VAL A 8 6.458 2.162 13.159 1.00 5.02 N
1913
+ ATOM 30 CA VAL A 8 5.145 2.209 12.453 1.00 6.93 C
1914
+ ATOM 31 C VAL A 8 5.115 3.379 11.461 1.00 5.39 C
1915
+ ATOM 32 O VAL A 8 4.664 3.268 10.343 1.00 6.30 O
1916
+ ATOM 33 N ALA A 9 5.606 4.546 11.941 1.00 3.73 N
1917
+ ATOM 34 CA ALA A 9 5.598 5.767 11.082 1.00 3.56 C
1918
+ ATOM 35 C ALA A 9 6.441 5.527 9.850 1.00 4.13 C
1919
+ ATOM 36 O ALA A 9 6.052 5.933 8.744 1.00 4.36 O
1920
+ ATOM 37 N ARG A 10 7.647 4.909 10.005 1.00 3.73 N
1921
+ ATOM 38 CA ARG A 10 8.496 4.609 8.837 1.00 3.38 C
1922
+ ATOM 39 C ARG A 10 7.798 3.609 7.876 1.00 3.47 C
1923
+ ATOM 40 O ARG A 10 7.878 3.778 6.651 1.00 4.67 O
1924
+ ATOM 41 N SER A 11 7.186 2.582 8.445 1.00 5.19 N
1925
+ ATOM 42 CA SER A 11 6.500 1.584 7.565 1.00 4.60 C
1926
+ ATOM 43 C SER A 11 5.382 2.313 6.773 1.00 4.84 C
1927
+ ATOM 44 O SER A 11 5.213 2.016 5.557 1.00 5.84 O
1928
+ ATOM 45 N ASN A 12 4.648 3.182 7.446 1.00 3.54 N
1929
+ ATOM 46 CA ASN A 12 3.545 3.935 6.751 1.00 4.57 C
1930
+ ATOM 47 C ASN A 12 4.107 4.851 5.691 1.00 4.14 C
1931
+ ATOM 48 O ASN A 12 3.536 5.001 4.617 1.00 5.52 O
1932
+ ATOM 49 N PHE A 13 5.259 5.498 6.005 1.00 3.43 N
1933
+ ATOM 50 CA PHE A 13 5.929 6.358 5.055 1.00 3.49 C
1934
+ ATOM 51 C PHE A 13 6.304 5.578 3.799 1.00 3.40 C
1935
+ ATOM 52 O PHE A 13 6.136 6.072 2.653 1.00 4.07 O
1936
+ ATOM 53 N ASN A 14 6.900 4.390 3.989 1.00 3.64 N
1937
+ ATOM 54 CA ASN A 14 7.331 3.607 2.791 1.00 4.31 C
1938
+ ATOM 55 C ASN A 14 6.116 3.210 1.915 1.00 3.98 C
1939
+ ATOM 56 O ASN A 14 6.240 3.144 0.684 1.00 6.22 O
1940
+ ATOM 57 N VAL A 15 4.993 2.927 2.571 1.00 3.76 N
1941
+ ATOM 58 CA VAL A 15 3.782 2.599 1.742 1.00 3.98 C
1942
+ ATOM 59 C VAL A 15 3.296 3.871 1.004 1.00 3.80 C
1943
+ ATOM 60 O VAL A 15 2.947 3.817 -0.189 1.00 4.85 O
1944
+ ATOM 61 N CYS A 16 3.321 4.987 1.720 1.00 3.79 N
1945
+ ATOM 62 CA CYS A 16 2.890 6.285 1.126 1.00 3.54 C
1946
+ ATOM 63 C CYS A 16 3.687 6.597 -0.111 1.00 3.48 C
1947
+ ATOM 64 O CYS A 16 3.200 7.147 -1.103 1.00 4.63 O
1948
+ ATOM 65 N ARG A 17 4.997 6.227 -0.100 1.00 3.99 N
1949
+ ATOM 66 CA ARG A 17 5.895 6.489 -1.213 1.00 3.83 C
1950
+ ATOM 67 C ARG A 17 5.738 5.560 -2.409 1.00 3.79 C
1951
+ ATOM 68 O ARG A 17 6.228 5.901 -3.507 1.00 5.39 O
1952
+ ATOM 69 N LEU A 18 5.051 4.411 -2.204 1.00 4.70 N
1953
+ ATOM 70 CA LEU A 18 4.933 3.431 -3.326 1.00 5.46 C
1954
+ ATOM 71 C LEU A 18 4.397 4.014 -4.620 1.00 5.13 C
1955
+ ATOM 72 O LEU A 18 4.988 3.755 -5.687 1.00 5.55 O
1956
+ ATOM 73 N PRO A 19 3.329 4.795 -4.543 1.00 4.28 N
1957
+ ATOM 74 CA PRO A 19 2.792 5.376 -5.797 1.00 5.38 C
1958
+ ATOM 75 C PRO A 19 3.573 6.540 -6.322 1.00 6.30 C
1959
+ ATOM 76 O PRO A 19 3.260 7.045 -7.422 1.00 9.62 O
1960
+ ATOM 77 N GLY A 20 4.565 7.047 -5.559 1.00 4.94 N
1961
+ ATOM 78 CA GLY A 20 5.366 8.191 -6.018 1.00 5.39 C
1962
+ ATOM 79 C GLY A 20 5.007 9.481 -5.280 1.00 5.03 C
1963
+ ATOM 80 O GLY A 20 5.535 10.510 -5.730 1.00 7.34 O
1964
+ ATOM 81 N THR A 21 4.181 9.438 -4.262 1.00 4.10 N
1965
+ ATOM 82 CA THR A 21 3.767 10.609 -3.513 1.00 3.94 C
1966
+ ATOM 83 C THR A 21 5.017 11.397 -3.042 1.00 3.96 C
1967
+ ATOM 84 O THR A 21 5.947 10.757 -2.523 1.00 5.82 O
1968
+ ATOM 85 N PRO A 22 4.971 12.703 -3.176 1.00 5.04 N
1969
+ ATOM 86 CA PRO A 22 6.143 13.513 -2.696 1.00 4.69 C
1970
+ ATOM 87 C PRO A 22 6.400 13.233 -1.225 1.00 4.19 C
1971
+ ATOM 88 O PRO A 22 5.485 13.061 -0.382 1.00 4.47 O
1972
+ ATOM 89 N GLU A 23 7.728 13.297 -0.921 1.00 5.16 N
1973
+ ATOM 90 CA GLU A 23 8.114 13.103 0.500 1.00 5.31 C
1974
+ ATOM 91 C GLU A 23 7.427 14.073 1.410 1.00 4.11 C
1975
+ ATOM 92 O GLU A 23 7.036 13.682 2.540 1.00 5.11 O
1976
+ ATOM 93 N ALA A 24 7.212 15.334 0.966 1.00 4.56 N
1977
+ ATOM 94 CA ALA A 24 6.614 16.317 1.913 1.00 4.49 C
1978
+ ATOM 95 C ALA A 24 5.212 15.936 2.350 1.00 4.10 C
1979
+ ATOM 96 O ALA A 24 4.782 16.166 3.495 1.00 5.64 O
1980
+ ATOM 97 N ILE A 25 4.445 15.318 1.405 1.00 4.37 N
1981
+ ATOM 98 CA ILE A 25 3.074 14.894 1.756 1.00 5.44 C
1982
+ ATOM 99 C ILE A 25 3.085 13.643 2.645 1.00 4.32 C
1983
+ ATOM 100 O ILE A 25 2.315 13.523 3.578 1.00 4.72 O
1984
+ ATOM 101 N CYS A 26 4.032 12.764 2.313 1.00 3.92 N
1985
+ ATOM 102 CA CYS A 26 4.180 11.549 3.187 1.00 4.37 C
1986
+ ATOM 103 C CYS A 26 4.632 11.944 4.596 1.00 3.95 C
1987
+ ATOM 104 O CYS A 26 4.227 11.252 5.547 1.00 4.74 O
1988
+ ATOM 105 N ALA A 27 5.408 13.012 4.694 1.00 3.89 N
1989
+ ATOM 106 CA ALA A 27 5.879 13.502 6.026 1.00 4.43 C
1990
+ ATOM 107 C ALA A 27 4.696 13.908 6.882 1.00 4.26 C
1991
+ ATOM 108 O ALA A 27 4.528 13.422 8.025 1.00 5.44 O
1992
+ ATOM 109 N THR A 28 3.827 14.802 6.358 1.00 4.53 N
1993
+ ATOM 110 CA THR A 28 2.691 15.221 7.194 1.00 5.08 C
1994
+ ATOM 111 C THR A 28 1.672 14.132 7.434 1.00 4.62 C
1995
+ ATOM 112 O THR A 28 0.947 14.112 8.468 1.00 7.80 O
1996
+ ATOM 113 N TYR A 29 1.621 13.190 6.511 1.00 5.01 N
1997
+ ATOM 114 CA TYR A 29 0.715 12.045 6.657 1.00 6.60 C
1998
+ ATOM 115 C TYR A 29 1.125 11.125 7.815 1.00 4.92 C
1999
+ ATOM 116 O TYR A 29 0.286 10.632 8.545 1.00 7.13 O
2000
+ ATOM 117 N THR A 30 2.470 10.984 7.995 1.00 5.31 N
2001
+ ATOM 118 CA THR A 30 2.986 9.994 8.950 1.00 5.70 C
2002
+ ATOM 119 C THR A 30 3.609 10.505 10.230 1.00 6.28 C
2003
+ ATOM 120 O THR A 30 3.766 9.715 11.186 1.00 8.77 O
2004
+ ATOM 121 N GLY A 31 3.984 11.764 10.241 1.00 4.99 N
2005
+ ATOM 122 CA GLY A 31 4.769 12.336 11.360 1.00 5.50 C
2006
+ ATOM 123 C GLY A 31 6.255 12.243 11.106 1.00 4.19 C
2007
+ ATOM 124 O GLY A 31 7.037 12.750 11.954 1.00 6.12 O
2008
+ ATOM 125 N CYS A 32 6.710 11.631 9.992 1.00 4.30 N
2009
+ ATOM 126 CA CYS A 32 8.140 11.694 9.635 1.00 4.89 C
2010
+ ATOM 127 C CYS A 32 8.500 13.141 9.206 1.00 5.50 C
2011
+ ATOM 128 O CYS A 32 7.581 13.949 8.944 1.00 5.82 O
2012
+ ATOM 129 N ILE A 33 9.793 13.410 9.173 1.00 6.02 N
2013
+ ATOM 130 CA ILE A 33 10.280 14.760 8.823 1.00 5.24 C
2014
+ ATOM 131 C ILE A 33 11.346 14.658 7.743 1.00 5.16 C
2015
+ ATOM 132 O ILE A 33 11.971 13.583 7.552 1.00 7.19 O
2016
+ ATOM 133 N ILE A 34 11.490 15.773 7.038 1.00 5.52 N
2017
+ ATOM 134 CA ILE A 34 12.552 15.877 6.036 1.00 6.82 C
2018
+ ATOM 135 C ILE A 34 13.590 16.917 6.560 1.00 6.92 C
2019
+ ATOM 136 O ILE A 34 13.168 18.006 6.945 1.00 9.22 O
2020
+ ATOM 137 N ILE A 35 14.856 16.493 6.536 1.00 7.06 N
2021
+ ATOM 138 CA ILE A 35 15.930 17.454 6.941 1.00 7.52 C
2022
+ ATOM 139 C ILE A 35 16.913 17.550 5.819 1.00 6.63 C
2023
+ ATOM 140 O ILE A 35 17.097 16.660 4.970 1.00 7.90 O
2024
+ ATOM 141 N PRO A 36 17.664 18.669 5.806 1.00 8.07 N
2025
+ ATOM 142 CA PRO A 36 18.635 18.861 4.738 1.00 8.78 C
2026
+ ATOM 143 C PRO A 36 19.925 18.042 4.949 1.00 8.31 C
2027
+ ATOM 144 O PRO A 36 20.593 17.742 3.945 1.00 9.09 O
2028
+ ATOM 145 N GLY A 37 20.172 17.730 6.217 1.00 8.48 N
2029
+ ATOM 146 CA GLY A 37 21.452 16.969 6.513 1.00 9.20 C
2030
+ ATOM 147 C GLY A 37 21.143 15.478 6.427 1.00 10.41 C
2031
+ ATOM 148 O GLY A 37 20.138 15.023 5.878 1.00 12.06 O
2032
+ ATOM 149 N ALA A 38 22.055 14.701 7.032 1.00 9.24 N
2033
+ ATOM 150 CA ALA A 38 22.019 13.242 7.020 1.00 9.24 C
2034
+ ATOM 151 C ALA A 38 21.944 12.628 8.396 1.00 9.60 C
2035
+ ATOM 152 O ALA A 38 21.869 11.387 8.435 1.00 13.65 O
2036
+ ATOM 153 N THR A 39 21.894 13.435 9.436 1.00 8.70 N
2037
+ ATOM 154 CA THR A 39 21.936 12.911 10.809 1.00 9.46 C
2038
+ ATOM 155 C THR A 39 20.615 13.191 11.521 1.00 8.32 C
2039
+ ATOM 156 O THR A 39 20.357 14.317 11.948 1.00 9.89 O
2040
+ ATOM 157 N CYS A 40 19.827 12.110 11.642 1.00 7.64 N
2041
+ ATOM 158 CA CYS A 40 18.504 12.312 12.298 1.00 8.05 C
2042
+ ATOM 159 C CYS A 40 18.684 12.451 13.784 1.00 7.63 C
2043
+ ATOM 160 O CYS A 40 19.533 11.718 14.362 1.00 9.64 O
2044
+ ATOM 161 N PRO A 41 17.880 13.266 14.426 1.00 8.00 N
2045
+ ATOM 162 CA PRO A 41 17.924 13.421 15.877 1.00 8.96 C
2046
+ ATOM 163 C PRO A 41 17.392 12.206 16.594 1.00 9.06 C
2047
+ ATOM 164 O PRO A 41 16.652 11.368 16.033 1.00 8.82 O
2048
+ ATOM 165 N GLY A 42 17.728 12.124 17.884 1.00 7.55 N
2049
+ ATOM 166 CA GLY A 42 17.334 10.956 18.691 1.00 8.00 C
2050
+ ATOM 167 C GLY A 42 15.875 10.688 18.871 1.00 7.22 C
2051
+ ATOM 168 O GLY A 42 15.434 9.550 19.166 1.00 8.41 O
2052
+ ATOM 169 N ASP A 43 15.036 11.747 18.715 1.00 5.54 N
2053
+ ATOM 170 CA ASP A 43 13.564 11.573 18.836 1.00 5.85 C
2054
+ ATOM 171 C ASP A 43 12.936 11.227 17.470 1.00 5.87 C
2055
+ ATOM 172 O ASP A 43 11.720 11.040 17.428 1.00 7.29 O
2056
+ ATOM 173 N TYR A 44 13.725 11.174 16.425 1.00 5.22 N
2057
+ ATOM 174 CA TYR A 44 13.257 10.745 15.081 1.00 5.56 C
2058
+ ATOM 175 C TYR A 44 14.275 9.687 14.612 1.00 4.61 C
2059
+ ATOM 176 O TYR A 44 14.930 9.862 13.568 1.00 6.04 O
2060
+ ATOM 177 N ALA A 45 14.342 8.640 15.422 1.00 4.76 N
2061
+ ATOM 178 CA ALA A 45 15.445 7.667 15.246 1.00 5.89 C
2062
+ ATOM 179 C ALA A 45 15.171 6.533 14.280 1.00 6.67 C
2063
+ ATOM 180 O ALA A 45 16.093 5.705 14.039 1.00 7.56 O
2064
+ ATOM 181 N ASN A 46 13.966 6.502 13.739 1.00 5.80 N
2065
+ ATOM 182 CA ASN A 46 13.512 5.395 12.878 1.00 6.15 C
2066
+ ATOM 183 C ASN A 46 13.311 5.853 11.455 1.00 6.61 C
2067
+ ATOM 184 O ASN A 46 13.733 6.929 11.026 1.00 7.18 O
2068
+ END`;
2069
+
2070
+ // Called for every structure loaded into the viewer. What is drawn on one goes
2071
+ // with it when the next is loaded, so there is nothing to clean up here.
2072
+ async function drawSurface(
2073
+ plugin: PluginUIContext,
2074
+ { structure }: LoadedStructureInfo
2075
+ ) {
2076
+ await plugin.builders.structure.representation.addRepresentation(structure, {
2077
+ type: "molecular-surface",
2078
+ color: "hydrophobicity",
2079
+ });
2080
+ }
2081
+
2082
+ function App() {
2083
+ return (
2084
+ <div className="app" style={{ height: 420 }}>
2085
+ <ProteinStructureViewer
2086
+ structure={PDB}
2087
+ sceneMode="external"
2088
+ onReady={drawSurface}
2089
+ showLegend={false}
2090
+ />
2091
+ </div>
2092
+ );
2093
+ }
2094
+
2095
+ export default App;
2096
+ ```
2097
+
2098
+ Whatever is built on a structure goes with it when the next one is loaded, so build it again in the next `onReady` rather than holding on to it. A component keyed `polymer-<chainId>` or `ligand-<chainId>` is dimmed along with its chain while another chain's name is pointed at.
2099
+
2100
+ `onDispose` is called before the viewer disposes of a plugin it handed over - including one whose `onReady` has not finished - so whatever was built on it can be let go. `onError` is told when creating the plugin, loading a structure or capturing an image fails, in place of the message the viewer would otherwise log; a rejected `onReady` counts as a failed load.
2101
+
2102
+ ## Rendering without React
2103
+
2104
+ The scene the viewer draws is available on its own, for a page that does not show the viewer: a report with a picture of the structure, a static export, or a Mol\* viewer of your own. It takes the options the props take, with the same meaning, and draws them by the same code, so what it draws matches the viewer given the same props. Import it from its own entry point, which leaves out React and the component library:
2105
+
2106
+ **TypeScript**
2107
+
2108
+ ```ts
2109
+ import {
2110
+ applyStructureScene,
2111
+ renderStructureImage,
2112
+ } from "@czi-sds/data-viz/ProteinStructureScene";
2113
+ ```
2114
+
2115
+ `renderStructureImage` renders a PNG of exactly `width` by `height` pixels. It creates a plugin offscreen for the one image and disposes of it once the image is taken, whether or not that succeeded, so nothing is left on the page. The camera is placed as the viewer would place it when the structure loads, without the animation. Leave out `backgroundColor` for a transparent background.
2116
+
2117
+ **TypeScript**
2118
+
2119
+ ```ts
2120
+ const image: Blob = await renderStructureImage({
2121
+ structure: pdb,
2122
+ plddt: scores,
2123
+ highlights: [{ chainId: "A", seqId: 27 }],
2124
+ orientation: "facing",
2125
+ width: 800,
2126
+ height: 600,
2127
+ backgroundColor: "#FFFFFF",
2128
+ });
2129
+ ```
2130
+
2131
+ It needs a DOM and WebGL: a browser, or headless Chromium on a server. Where there is no WebGL it rejects rather than returning a blank image.
2132
+
2133
+ `applyStructureScene` draws the scene on a Mol\* plugin you created and resolves with a handle once the structure is drawn and the camera is on it. `update` applies changed options in place and leaves the camera where it is, except for a new `structure`, which is loaded and framed like the first. `getCamera` reads the camera in the form `initialCamera` takes, and `dispose` stops the scene touching the plugin, which stays yours.
2134
+
2135
+ **TypeScript**
2136
+
2137
+ ```ts
2138
+ const scene = await applyStructureScene(plugin, { structure: pdb });
2139
+
2140
+ await scene.update({ representation: "surface", hiddenChains: ["B"] });
2141
+ const camera = scene.getCamera();
2142
+
2143
+ scene.dispose();
2144
+ ```
2145
+
2146
+ The scene clears the plugin's state to load a structure, so give it a plugin of its own rather than one showing something else. Its color themes are registered once per plugin, so applying a scene again on the same plugin is fine. A structure that fails to load rejects the promise; a representation that cannot be drawn, such as a surface too large to compute, is reported to `onError` with the phase `"representation"` and the cartoon is drawn in its place.
2147
+
1509
2148
  ## Props
1510
2149
 
1511
2150
  The viewer spreads any remaining props onto its root div, so standard HTML attributes such as `className`, `id`, and `data-testid` work as usual.
1512
2151
 
1513
- | Name | Type | Default | Description |
1514
- | ------------------------------- | ----------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1515
- | `structure` | `string` | - (required) | The structure to render, as raw PDB or mmCIF (PDBx) text. |
1516
- | `plddt` | `number[] \| null` | - | Per-residue pLDDT confidence on a 0-1 scale, in chain order. When supplied, the structure is colored by confidence unless `residueOverlay` takes over. Residues past the end of the array fall back to mid confidence. |
1517
- | `residueOverlay` | `ResidueValueOverlay \| null` | - | Per-residue values painted over the structure, replacing pLDDT coloring while set. See the table below for its shape. |
1518
- | `selection` | `StructureSelection \| null` | - | What is selected. Leave undefined to let the viewer own it, so a click zooms in on a residue with no state on your side; passing it takes that over, and a click then moves the camera only once `onSelectionChange` is echoed back. Either way the camera frames whatever it covers, and clearing it zooms back out. Residues are drawn in ball-and-stick; a whole chain dims the chains around it instead. See the table below for its shape. |
1519
- | `hiddenChains` | `string[]` | - | Chains hidden from the 3D view, by `chainId`. Leave undefined to let the chain legend's toggles own visibility; passing it takes that over, and the toggles then only report through `onChainVisibilityChange`. |
1520
- | `chainColors` | `Record<string, string>` | - | Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to the viewer's palette. Only visible while chain coloring is what is on screen, which is when neither `plddt` nor `residueOverlay` is set. |
1521
- | `showChainLegend` | `boolean` | `true` | Show the chain legend, which lists each chain with its color and a visibility toggle. Ignored on a single-chain structure, where there is nothing to tell apart or hide. |
1522
- | `disableChainHighlightOnHover` | `boolean` | `false` | Stop other chains from dimming in the 3D view while a chain's name is pointed at, in the legend or above its grid in the sequence panel. Turn it off where the movement is more distracting than the answer is useful. |
1523
- | `download` | `StructureDownload \| null` | - | Adds a capture button beneath the reset-camera control, which downloads a PNG of the structure. Omit for no button. See _Downloading an image_ above. |
1524
- | `molstarSpec` | `Partial<PluginUISpec>` | - | Mol* plugin spec laid over the viewer's own, which is how the whole of Mol*'s configuration is reachable without a prop here for each setting. Anything named wins; list-valued keys are appended to. Read once at creation, except `canvas3d`, which is re-applied when it changes. See _Configuring Mol\*_ above. |
1525
- | `stats` | `(StructureStat \| null)[]` | - | Up to three whole-structure stats shown along the bottom. A `null` entry reserves its column without rendering anything, so the columns never shift as values come and go. |
1526
- | `backgroundColor` | `string` | - | Canvas background, as `#RRGGBB`. Defaults to the SDS theme's base background, so the canvas follows the surrounding page in both modes. |
1527
- | `sequenceViewerBackgroundColor` | `string` | - | Sequence panel background, as any CSS color. Defaults to the SDS theme's primary surface, so the panel follows the surrounding page in both modes. |
1528
- | `showAxes` | `boolean` | `true` | Show the orientation axes widget and the reset-camera button. |
1529
- | `showSequenceViewer` | `boolean` | `true` | Show the sequence panel pinned along the bottom of the viewer. |
1530
- | `showLegend` | `boolean` | `true` | Show the stats and color scale legend overlaid on the viewer. |
1531
- | `onResidueClick` | `function` | - | `(residue: ResidueRef) => void`. Called with the residue under the pointer: `index` (0-based, across the whole structure), `compId`, `chainId`, `seqId` and `insCode`. What the click _selected_ comes through `onSelectionChange`, which a drag makes a range. |
1532
- | `onResidueHover` | `function` | - | `(residue: ResidueRef \| null) => void`. Called as the pointer moves over residues, and with `null` when it leaves the structure. |
1533
- | `onSelectionChange` | `function` | - | `(selection: StructureSelection \| null) => void`. Called with the new selection whenever the user makes one - clicking a residue, dragging across the sequence, clicking a chain caption - and with `null` when they click empty space to clear it. A whole-chain selection arrives as `{ chains: [id] }` rather than as every index on it. Fires whether or not `selection` is controlled, so a consumer can follow the viewer's own selection without owning it. |
1534
- | `onChainsChange` | `function` | - | `(chains: ChainRef[]) => void`. Called with the chains found in the structure, whenever a structure is loaded. Fires with `[]` when the structure holds none. |
1535
- | `onChainVisibilityChange` | `function` | - | `(hiddenChains: string[]) => void`. Called with the chains now hidden when a visibility toggle is used. Fires whether or not `hiddenChains` is controlled, so a consumer can follow the viewer's own state without owning it. |
2152
+ | Name | Type | Default | Description |
2153
+ | ------------------------------- | ------------------------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2154
+ | `structure` | `string` | - (required) | The structure to render, as raw PDB or mmCIF (PDBx) text. |
2155
+ | `plddt` | `(number \| null)[] \| null` | - | Per-residue pLDDT confidence on a 0-1 scale, in chain order. When supplied, the structure is colored by confidence unless `residueOverlay` takes over. A `null`, and every residue past the end of the array, reads as unscored and is painted neutral. |
2156
+ | `colorBy` | `"chain" \| "plddt" \| "overlay"` | - | What paints the structure. Left undefined it follows what is supplied: `residueOverlay`, then `plddt`, then chain colors. A theme with nothing to paint with leaves every residue neutral. |
2157
+ | `representation` | `"cartoon" \| "surface"` | `"cartoon"` | How the polymer is drawn. `"surface"` is one molecular surface over the visible chains. Switching leaves the camera where it is. |
2158
+ | `highlights` | `ResidueHighlight[]` | - | Residues picked out in colors of their own, by chain, number and insertion code, painted over whatever colors the rest and drawn in ball-and-stick over the cartoon. See the table below for its shape. |
2159
+ | `residueOverlay` | `ResidueValueOverlay \| null` | - | Per-residue values painted over the structure, replacing pLDDT coloring while set. See the table below for its shape. |
2160
+ | `selection` | `StructureSelection \| null` | - | What is selected. Leave undefined to let the viewer own it, so a click zooms in on a residue with no state on your side; passing it takes that over, and a click then moves the camera only once `onSelectionChange` is echoed back. Either way the camera frames whatever it covers, and clearing it zooms back out. Residues are drawn in ball-and-stick; a whole chain dims the chains around it instead. See the table below for its shape. |
2161
+ | `hiddenChains` | `string[]` | - | Chains hidden from the 3D view, by `chainId`. Leave undefined to let the chain legend's toggles own visibility; passing it takes that over, and the toggles then only report through `onChainVisibilityChange`. |
2162
+ | `chainColors` | `Record<string, string>` | - | Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to the viewer's palette. Only visible while chain coloring is what is on screen: when `colorBy` says so or, left undefined, when neither `plddt` nor `residueOverlay` is set. |
2163
+ | `showChainLegend` | `boolean` | `true` | Show the chain legend, which lists each chain with its color and a visibility toggle. Ignored on a single-chain structure, where there is nothing to tell apart or hide. |
2164
+ | `disableChainHighlightOnHover` | `boolean` | `false` | Stop other chains from dimming in the 3D view while a chain's name is pointed at, in the legend or above its grid in the sequence panel. Turn it off where the movement is more distracting than the answer is useful. |
2165
+ | `download` | `StructureDownload \| null` | - | Adds a capture button beneath the reset-camera control, which downloads a PNG of the structure. Omit for no button. See _Downloading an image_ above. |
2166
+ | `molstarSpec` | `Partial<PluginUISpec>` | - | Mol* plugin spec laid over the viewer's own, which is how the whole of Mol*'s configuration is reachable without a prop here for each setting. Anything named wins; list-valued keys are appended to. Read once at creation, except `canvas3d`, which is re-applied when it changes. See _Configuring Mol\*_ above. |
2167
+ | `stats` | `(StructureStat \| null)[]` | - | Up to three whole-structure stats shown along the bottom. A `null` entry reserves its column without rendering anything, so the columns never shift as values come and go. |
2168
+ | `backgroundColor` | `string` | - | Canvas background, as `#RRGGBB`. Defaults to the SDS theme's base background, so the canvas follows the surrounding page in both modes. |
2169
+ | `sequenceViewerBackgroundColor` | `string` | - | Sequence panel background, as any CSS color. Defaults to the SDS theme's primary surface, so the panel follows the surrounding page in both modes. |
2170
+ | `showAxes` | `boolean` | `true` | Show the orientation axes widget and the reset-camera button. |
2171
+ | `showSequenceViewer` | `boolean` | `true` | Show the sequence panel pinned along the bottom of the viewer. |
2172
+ | `showLegend` | `boolean` | `true` | Show the stats and color scale legend overlaid on the viewer. |
2173
+ | `onResidueClick` | `function` | - | `(residue: ResidueRef) => void`. Called with the residue under the pointer: `index` (0-based, across the whole structure), `compId`, `chainId`, `seqId` and `insCode`. What the click _selected_ comes through `onSelectionChange`, which a drag makes a range. |
2174
+ | `onResidueHover` | `function` | - | `(residue: ResidueRef \| null) => void`. Called as the pointer moves over residues, and with `null` when it leaves the structure. |
2175
+ | `onSelectionChange` | `function` | - | `(selection: StructureSelection \| null) => void`. Called with the new selection whenever the user makes one - clicking a residue, dragging across the sequence, clicking a chain caption - and with `null` when they click empty space to clear it. A whole-chain selection arrives as `{ chains: [id] }` rather than as every index on it. Fires whether or not `selection` is controlled, so a consumer can follow the viewer's own selection without owning it. |
2176
+ | `onChainsChange` | `function` | - | `(chains: ChainRef[]) => void`. Called with the chains found in the structure, whenever a structure is loaded. Fires with `[]` when the structure holds none. |
2177
+ | `onChainVisibilityChange` | `function` | - | `(hiddenChains: string[]) => void`. Called with the chains now hidden when a visibility toggle is used. Fires whether or not `hiddenChains` is controlled, so a consumer can follow the viewer's own state without owning it. |
2178
+ | `projection` | `"perspective" \| "orthographic"` | - | The camera's projection. Left undefined, Mol\*'s own default stands. |
2179
+ | `initialCamera` | `CameraState \| null` | - | Where the camera starts on each structure loaded, in place of fitting it. Takes what `onCameraChange` reports. |
2180
+ | `orientation` | `"overview" \| "facing" \| "opposite" \| "side"` | - | Turns the camera to look at the highlighted residues. Applied when a structure loads, unless `initialCamera` is set, and whenever it changes. |
2181
+ | `onCameraChange` | `function` | - | `(camera: CameraState) => void`. Called with the camera each time it comes to rest after moving. |
2182
+ | `onStructureLoad` | `function` | - | `(info: StructureLoadInfo) => void`. Called for every structure that loads, reloads included, with its atom and residue counts and its chains. |
2183
+ | `sceneMode` | `"managed" \| "external"` | `"managed"` | Who draws the structure. `"external"` parses it and leaves the canvas empty for a scene drawn in `onReady`; see Building on the viewer. Read once, when the plugin is created. |
2184
+ | `onReady` | `function` | - | `(plugin: PluginUIContext, loaded: LoadedStructureInfo) => void \| Promise<void>`. Called with the Mol\* plugin once a structure is loaded, and again for each structure that replaces it. Awaited before the viewer answers clicks or applies its coloring. Not called for a structure that failed to load. |
2185
+ | `onError` | `function` | - | `(error: unknown, phase: "init" \| "load" \| "capture" \| "representation") => void`. Called when creating the plugin, loading a structure, capturing an image or drawing a representation fails, in place of the viewer's console message. A rejected `onReady` is a `"load"` failure. |
2186
+ | `onDispose` | `function` | - | `() => void`. Called before the viewer disposes of a plugin it handed to `onReady`, including one whose `onReady` has not finished. |
1536
2187
 
1537
2188
  ### StructureSelection
1538
2189
 
1539
2190
  What is selected, in the two ways a caller might say it. The two combine: `{ chains: ["A"], residues: [150] }` takes all of chain A plus one residue elsewhere. Both fields are optional; `null` in place of the whole object selects nothing.
1540
2191
 
1541
- | Name | Type | Default | Description |
1542
- | ---------- | ---------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1543
- | `residues` | `number[]` | - | 0-based residue indices, counting residues in file order across the whole structure - the same index `plddt` and `residueOverlay` are keyed by. |
1544
- | `chains` | `string[]` | - | Whole chains by `chainId`, each standing for every residue on it. Kept as named rather than expanded into indices, so a whole-chain selection survives a round trip through a consumer's state at its original size. |
2192
+ | Field | Type | Default | Description |
2193
+ | ----------- | ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2194
+ | `residues` | `number[]` | - | 0-based residue indices, counting residues in file order across the whole structure - the same index `plddt` and `residueOverlay` are keyed by. |
2195
+ | `chains` | `string[]` | - | Whole chains by `chainId`, each standing for every residue on it. Kept as named rather than expanded into indices, so a whole-chain selection survives a round trip through a consumer's state at its original size. |
2196
+ | `addresses` | `ResidueAddress[]` | - | Residues by the chain, number and insertion code the file gives them, for a caller that knows a residue by its address rather than its position. They join `residues`; an address the structure does not have selects nothing. The viewer reports its own selections as `residues`. |
1545
2197
 
1546
2198
  ### ChainRef
1547
2199
 
@@ -1549,7 +2201,7 @@ A chain the viewer found in the structure it loaded, reported through `onChainsC
1549
2201
 
1550
2202
  It describes the chain's polymer. The ligands and ions sitting on the chain are drawn, and are hidden and selected along with it, but are not counted here or spanned by its range - they are no part of the sequence. A chain holding nothing but heteroatoms is left out altogether, having no sequence to describe, though it is still drawn.
1551
2203
 
1552
- | Name | Type | Default | Description |
2204
+ | Field | Type | Default | Description |
1553
2205
  | -------------- | -------- | ------------ | -------------------------------------------------------- |
1554
2206
  | `chainId` | `string` | - (required) | Chain as named in the file (`auth_asym_id`), e.g. `"A"`. |
1555
2207
  | `label` | `string` | - (required) | Chain as the sequence panel captions it. |
@@ -1559,7 +2211,7 @@ It describes the chain's polymer. The ligands and ions sitting on the chain are
1559
2211
 
1560
2212
  ### ResidueValueOverlay
1561
2213
 
1562
- | Name | Type | Default | Description |
2214
+ | Field | Type | Default | Description |
1563
2215
  | -------------- | ----------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1564
2216
  | `values` | `Map<number, number>` | - (required) | 0-based residue index to value. Residues absent from the map read as `0`, so they render in the neutral gray rather than at the bottom of the scale. |
1565
2217
  | `max` | `number` | - (required) | The value mapped to the top of the color scale. |
@@ -1572,7 +2224,80 @@ It describes the chain's polymer. The ligands and ions sitting on the chain are
1572
2224
 
1573
2225
  ### StructureStat
1574
2226
 
1575
- | Name | Type | Default | Description |
2227
+ | Field | Type | Default | Description |
1576
2228
  | ------- | -------- | ------------ | ------------------------------------------------ |
1577
2229
  | `value` | `string` | - (required) | The stat's value, already formatted for display. |
1578
2230
  | `label` | `string` | - (required) | The caption shown beneath the value. |
2231
+
2232
+ ### ResidueHighlight
2233
+
2234
+ A residue by its address - a `ResidueAddress`, which is the same three fields without `color` - and the color it is picked out in. `ResidueRef` reports the same three, so a residue the viewer reported can be handed straight back.
2235
+
2236
+ | Field | Type | Default | Description |
2237
+ | --------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------------------------- |
2238
+ | `chainId` | `string` | - (required) | Chain as named in the file (`auth_asym_id`). |
2239
+ | `seqId` | `number` | - (required) | Residue number as written in the file. |
2240
+ | `insCode` | `string` | - | Insertion code, when the residue has one. A blank one and none are the same. |
2241
+ | `color` | `string` | - | As `#RRGGBB`. Highlights that name none take the next color of `HIGHLIGHT_COLOR_PALETTE`, in the order they are given. |
2242
+
2243
+ ### CameraState
2244
+
2245
+ Everything that places the camera, enough to put it back exactly where it was: what `onCameraChange` reports and `initialCamera` takes.
2246
+
2247
+ | Field | Type | Default | Description |
2248
+ | -------------------------- | ----------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
2249
+ | `position`, `target`, `up` | `[number, number, number]` | - (required) | Where the camera is, what it looks at, and which way is up. |
2250
+ | `fov` | `number` | - (required) | Field of view, in radians. |
2251
+ | `radius`, `radiusMax` | `number` | - (required) | The sphere around `target` the camera frames, and the whole scene's, which bounds how far it clips. |
2252
+ | `projection` | `"perspective" \| "orthographic"` | - (required) | The camera's projection. |
2253
+ | `viewport` | `{ width: number; height: number }` | - | Size of the canvas the camera framed, in pixels, for rendering an image at the same aspect. Ignored when the state is applied. |
2254
+
2255
+ ### StructureLoadInfo
2256
+
2257
+ What `onStructureLoad` reports for each structure loaded.
2258
+
2259
+ | Field | Type | Default | Description |
2260
+ | -------------- | ------------ | ------------ | -------------------------------------------------------------- |
2261
+ | `atomCount` | `number` | - (required) | Atoms Mol\* parsed. |
2262
+ | `residueCount` | `number` | - (required) | Polymer residues across every chain, as the chains count them. |
2263
+ | `chains` | `ChainRef[]` | - (required) | The polymer chains found. |
2264
+
2265
+ ### LoadedStructureInfo
2266
+
2267
+ What `onReady` is handed alongside the plugin.
2268
+
2269
+ | Field | Type | Default | Description |
2270
+ | ----------- | ----------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
2271
+ | `structure` | `StateObjectSelector<PluginStateObject.Molecule.Structure>` | - (required) | The parsed structure's cell in the plugin's state tree, to build components and representations on. They go with it when the next structure is loaded. |
2272
+ | `atomCount` | `number` | - (required) | Atoms Mol\* parsed, for checking the parse against a count you hold for the file before trusting what is drawn. |
2273
+ | `chains` | `ChainRef[]` | - (required) | The polymer chains found, as `onChainsChange` reports them. |
2274
+
2275
+ ### StructureSceneOptions
2276
+
2277
+ What `applyStructureScene` draws. `structure`, `plddt`, `residueOverlay`, `colorBy`, `chainColors`, `representation`, `highlights`, `hiddenChains`, `initialCamera`, `orientation` and `projection` mean what the props of the same names mean, with the same defaults. Beyond those:
2278
+
2279
+ | Field | Type | Default | Description |
2280
+ | --------- | --------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
2281
+ | `mode` | `"light" \| "dark"` | `"light"` | Which of the neutral grays paints a residue without a value. The viewer takes it from the SDS theme. |
2282
+ | `onError` | `(error: unknown, phase: ViewerErrorPhase) => void` | - | Told when a representation cannot be drawn, with the phase `"representation"`. Without it the error is logged. |
2283
+
2284
+ ### StructureSceneHandle
2285
+
2286
+ What `applyStructureScene` resolves with.
2287
+
2288
+ | Field | Type | Description |
2289
+ | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
2290
+ | `info` | `StructureLoadInfo` | What the structure last loaded holds. |
2291
+ | `update` | `(options: Partial<StructureSceneOptions>) => Promise<void>` | Applies the options given in place, keeping the rest and leaving the camera where it is. A new `structure` is loaded and the camera placed on it. |
2292
+ | `getCamera` | `() => CameraState \| undefined` | Where the camera is now, in the form `initialCamera` takes. |
2293
+ | `dispose` | `() => void` | Stops the scene touching the plugin. The plugin, and what was drawn on it, stay yours. |
2294
+
2295
+ ### RenderStructureImageOptions
2296
+
2297
+ What `renderStructureImage` takes: everything in `StructureSceneOptions`, and the image to draw it into.
2298
+
2299
+ | Field | Type | Default | Description |
2300
+ | ----------------- | -------- | ------------ | ---------------------------------------------- |
2301
+ | `width` | `number` | - (required) | Width of the image, in pixels. |
2302
+ | `height` | `number` | - (required) | Height of the image, in pixels. |
2303
+ | `backgroundColor` | `string` | transparent | Background behind the structure, as `#RRGGBB`. |
@@ -7,7 +7,7 @@
7
7
  "type": "string"
8
8
  },
9
9
  "chainColors": {
10
- "description": "Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to\nthe viewer's palette. Only visible while chain coloring is what is on\nscreen, which is when neither `plddt` nor `residueOverlay` is set.",
10
+ "description": "Color per chain, by `chainId`, as `#RRGGBB`. Chains left out fall back to\nthe viewer's palette. Only visible while chain coloring is what is on\nscreen: when `colorBy` says so, or, left undefined, when neither `plddt`\nnor `residueOverlay` is set.",
11
11
  "isRequired": false,
12
12
  "type": "Record<string, string>"
13
13
  },
@@ -26,6 +26,43 @@
26
26
  "isRequired": false,
27
27
  "type": "Partial<PluginUISpec>"
28
28
  },
29
+ "sceneMode": {
30
+ "defaultValue": "managed",
31
+ "description": "Who draws the structure.\n\n`\"managed\"` draws each chain as a cartoon and its ligands as\nball-and-stick, colors them from `plddt`, `residueOverlay` and\n`chainColors`, hides the chains `hiddenChains` names, and frames the camera\non each structure it loads.\n\n`\"external\"` parses the structure and stops there: nothing is drawn,\ncolored, hidden or framed, and a consumer draws its own scene on the\nstructure `onReady` hands it. The sequence panel, selection, hover, legend\nand camera controls work as before; the legend describes the props rather\nthan what the consumer drew, and its chain toggles report through\n`onChainVisibilityChange` without hiding anything. Mol* frames the camera\non the first representation drawn into the empty scene.\n\nRead once, when the plugin is created.",
32
+ "isRequired": false,
33
+ "type": "\"managed\" | \"external\""
34
+ },
35
+ "colorBy": {
36
+ "description": "What paints the structure. Left undefined it follows what is supplied: a\n`residueOverlay` when there is one, then `plddt`, then the chain colors.\nNaming one makes it paint whatever else is set, which is how a toggle\nbetween confidence and chain coloring keeps both props in place. A theme\nwith nothing to paint with leaves every residue neutral.",
37
+ "isRequired": false,
38
+ "type": "\"overlay\" | \"plddt\" | \"chain\""
39
+ },
40
+ "highlights": {
41
+ "description": "Residues picked out in colors of their own, by the address the file gives\nthem. They paint over whatever colors the rest - chain, pLDDT or overlay -\nand are drawn in ball-and-stick over the cartoon; on a surface, the\nsurface itself carries them. Separate from `selection`: highlighting a\nresidue neither selects it nor moves the camera.",
42
+ "isRequired": false,
43
+ "type": "ResidueHighlight[]"
44
+ },
45
+ "initialCamera": {
46
+ "description": "Where the camera starts on each structure loaded, in place of fitting it\nto the structure. Applied once per load; moving the camera afterwards is\nthe user's.",
47
+ "isRequired": false,
48
+ "type": "CameraState | null"
49
+ },
50
+ "orientation": {
51
+ "description": "Turns the camera to look at the highlighted residues from one side or\nanother. Applied when a structure is loaded, unless `initialCamera` is\nset, and whenever it changes - not when the highlights do.",
52
+ "isRequired": false,
53
+ "type": "\"overview\" | \"facing\" | \"opposite\" | \"side\""
54
+ },
55
+ "projection": {
56
+ "description": "The camera's projection. Left undefined, Mol*'s own default stands.",
57
+ "isRequired": false,
58
+ "type": "\"perspective\" | \"orthographic\""
59
+ },
60
+ "representation": {
61
+ "defaultValue": "cartoon",
62
+ "description": "How the polymer is drawn. Ligands stay ball-and-stick either way.\nSwitching leaves the camera where it is.",
63
+ "isRequired": false,
64
+ "type": "\"cartoon\" | \"surface\""
65
+ },
29
66
  "disableChainHighlightOnHover": {
30
67
  "defaultValue": false,
31
68
  "description": "Stop other chains from dimming in the 3D view while a chain's name is\npointed at, in the legend or above its grid in the sequence panel.\n\nThe dim is on by default, since on a complex it is how a reader finds out\nwhich chain is which. Turn it off where the movement is more distracting\nthan the answer is useful - a grid of viewers a pointer crosses on its way\nsomewhere else, or a page driving its own highlighting through `selection`.",
@@ -66,17 +103,6 @@
66
103
  "isRequired": false,
67
104
  "type": "(StructureStat | null)[]"
68
105
  },
69
- "resolution": {
70
- "defaultValue": "medium",
71
- "description": "1280x720, 1920x1080, 3840x2160 and 7680x4320 respectively. Also exported as DOWNLOAD_RESOLUTIONS, for labelling a control of your own.",
72
- "isRequired": false,
73
- "type": "\"low\" | \"medium\" | \"high\" | \"maximum\""
74
- },
75
- "filename": {
76
- "description": "Name for the file, without an extension. Defaults to the one Mol* derives from the loaded structure.",
77
- "isRequired": false,
78
- "type": "string"
79
- },
80
106
  "structure": {
81
107
  "defaultValue": "- (required)",
82
108
  "description": "Structure to render, as raw PDB or mmCIF (PDBx) text.",
@@ -84,9 +110,9 @@
84
110
  "type": "string"
85
111
  },
86
112
  "plddt": {
87
- "description": "Per-residue pLDDT confidence on a 0-1 scale, ordered by residue. When\nsupplied the structure is colored by pLDDT unless `residueOverlay` takes\nover.",
113
+ "description": "Per-residue pLDDT confidence on a 0-1 scale, ordered by residue. When\nsupplied the structure is colored by pLDDT unless `residueOverlay` takes\nover. A `null` entry, and every residue past the end, reads as unscored\nand is painted neutral rather than at the bottom of the scale.",
88
114
  "isRequired": false,
89
- "type": "number[] | null"
115
+ "type": "(number | null)[] | null"
90
116
  },
91
117
  "residueOverlay": {
92
118
  "description": "Per-residue values that override pLDDT coloring while set.",
@@ -123,85 +149,30 @@
123
149
  "isRequired": false,
124
150
  "type": "(hiddenChains: string[]) => void"
125
151
  },
126
- "residues": {
127
- "description": "0-based residue indices, counting residues in file order across the whole structure - the same index plddt and residueOverlay are keyed by.",
152
+ "onCameraChange": {
153
+ "description": "Called with the camera each time it comes to rest after moving, whether a\ndrag, a zoom, a selection framing it, or a new structure fitting it. The\nstate can be handed back as `initialCamera` to restore the view.",
128
154
  "isRequired": false,
129
- "type": "number[]"
155
+ "type": "(camera: CameraState) => void"
130
156
  },
131
- "chains": {
132
- "description": "Whole chains by chainId, each standing for every residue on it. Kept as named rather than expanded into indices, so a whole-chain selection survives a round trip through a consumer's state at its original size.",
157
+ "onStructureLoad": {
158
+ "description": "Called for every structure that loads, reloads included - unlike\n`onChainsChange`, which stays quiet when the chains come back the same.\nWhat a consumer tracking \"loading\" and \"ready\" states listens for.",
133
159
  "isRequired": false,
134
- "type": "string[]"
160
+ "type": "(info: StructureLoadInfo) => void"
135
161
  },
136
- "chainId": {
137
- "defaultValue": "- (required)",
138
- "description": "Chain as named in the file (auth_asym_id), e.g. \"A\".",
162
+ "onReady": {
163
+ "description": "Called with the Mol* plugin once a structure is loaded into it, and again\nfor each structure that replaces it, which is how a consumer reaches the\nplugin to draw on it or drive it directly.\n\nCalled once the viewer has drawn its own scene, and awaited before it\nstarts answering clicks and hovers, so a scene built here is in place\nbefore a click reaches it. The viewer only ever recolors, hides or\nreplaces the components it built itself, so representations added here\nare left as they were made. Not called for a structure that failed to\nload, or for a plugin the viewer disposed of first.",
139
164
  "isRequired": false,
140
- "type": "string"
165
+ "type": "(plugin: PluginUIContext, loaded: LoadedStructureInfo) => void | Promise<void>"
141
166
  },
142
- "startIndex": {
143
- "defaultValue": "- (required)",
144
- "description": "Lowest 0-based residue index of the chain's polymer.",
167
+ "onError": {
168
+ "description": "Called when creating the plugin, loading a structure, capturing an image or\ndrawing a representation fails, in place of the message the viewer would\notherwise log. A rejected `onReady` is reported as a `\"load\"` failure.\nNothing is reported for a plugin the viewer has already disposed of.",
145
169
  "isRequired": false,
146
- "type": "number"
170
+ "type": "(error: unknown, phase: ViewerErrorPhase) => void"
147
171
  },
148
- "endIndex": {
149
- "defaultValue": "- (required)",
150
- "description": "Highest 0-based residue index of the chain's polymer.",
172
+ "onDispose": {
173
+ "description": "Called before the viewer disposes of a plugin it handed to `onReady`,\nincluding one whose `onReady` has not finished, so that whatever was built\non it can be let go.",
151
174
  "isRequired": false,
152
- "type": "number"
153
- },
154
- "residueCount": {
155
- "defaultValue": "- (required)",
156
- "description": "Polymer residues the chain holds.",
157
- "isRequired": false,
158
- "type": "number"
159
- },
160
- "values": {
161
- "defaultValue": "- (required)",
162
- "description": "0-based residue index to value. Residues absent from the map read as 0, so they render in the neutral gray rather than at the bottom of the scale.",
163
- "isRequired": false,
164
- "type": "Map<number, number>"
165
- },
166
- "max": {
167
- "defaultValue": "- (required)",
168
- "description": "The value mapped to the top of the color scale.",
169
- "isRequired": false,
170
- "type": "number"
171
- },
172
- "min": {
173
- "defaultValue": 0,
174
- "description": "Values at or below this render in a neutral gray rather than on the scale.",
175
- "isRequired": false,
176
- "type": "number"
177
- },
178
- "colorScale": {
179
- "defaultValue": "PLASMA_COLOR_SCALE",
180
- "description": "Scale used to color residues and to draw the legend.",
181
- "isRequired": false,
182
- "type": "ColorScale"
183
- },
184
- "tooltip": {
185
- "description": "Help tooltip title on the legend caption. A string is enough for the common case; use tooltipProps for a subtitle, a custom body, or placement. Overrides tooltipProps.title when both are set.",
186
- "isRequired": false,
187
- "type": "string"
188
- },
189
- "tooltipProps": {
190
- "description": "Props forwarded to the SDS Tooltip on the legend caption. The trigger is the caption's help icon, so children is omitted.",
191
- "isRequired": false,
192
- "type": "Partial<Omit<TooltipProps, \"children\">>"
193
- },
194
- "readoutLabel": {
195
- "defaultValue": "Value",
196
- "description": "Label for the per-residue readout that replaces a stat slot on hover.",
197
- "isRequired": false,
198
- "type": "string"
199
- },
200
- "value": {
201
- "defaultValue": "- (required)",
202
- "description": "The stat's value, already formatted for display.",
203
- "isRequired": false,
204
- "type": "string"
175
+ "type": "() => void"
205
176
  }
206
177
  }
207
178
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@czi-sds/mcp",
3
3
  "description": "The official MCP server for SDS",
4
- "version": "0.20.1",
4
+ "version": "0.20.2",
5
5
  "main": "dist/stdio.js",
6
6
  "files": [
7
7
  "dist",
@@ -66,5 +66,5 @@
66
66
  "turndown": "^7.2.4",
67
67
  "typescript": "^5.9.2"
68
68
  },
69
- "gitHead": "52f0027db4ead40a4a311a27aefd762ed8823d47"
69
+ "gitHead": "af9ead042355f832da2c98e7dc3ecaafd1ea1664"
70
70
  }