gramene-search 2.38.1 → 2.38.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.
package/dist/index.js CHANGED
@@ -9074,6 +9074,28 @@ const $64fad37f770d2bfe$var$TBROWSE_BASE_ZONES = [
9074
9074
  (0, $gXNCa$tbrowse.msaZone),
9075
9075
  (0, $gXNCa$tbrowse.neighborhoodZone)
9076
9076
  ];
9077
+ // A gene's tree is either the main Compara tree (homology.gene_tree) or, for
9078
+ // genomes in a clade-specific tree set, homology.<tree_set> — e.g. wheat genes
9079
+ // carry homology.wheat = {id: 'EplWheatGT_…'}. Solr indexes the tree id under
9080
+ // the same name (gene_tree, wheat, oat, …), so `field` is also the fq field.
9081
+ // Null when the gene has homologues but no tree at all.
9082
+ const $64fad37f770d2bfe$var$NOT_TREE_KEYS = [
9083
+ 'homologous_genes',
9084
+ 'supertree'
9085
+ ];
9086
+ function $64fad37f770d2bfe$var$geneTreeRef(gene) {
9087
+ const h = gene && gene.homology;
9088
+ if (!h) return null;
9089
+ if (h.gene_tree && h.gene_tree.id) return {
9090
+ field: 'gene_tree',
9091
+ id: h.gene_tree.id
9092
+ };
9093
+ const key = Object.keys(h).find((k)=>!$64fad37f770d2bfe$var$NOT_TREE_KEYS.includes(k) && h[k] && typeof h[k] === 'object' && typeof h[k].id === 'string');
9094
+ return key ? {
9095
+ field: key,
9096
+ id: h[key].id
9097
+ } : null;
9098
+ }
9077
9099
  class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$react))).Component {
9078
9100
  constructor(props){
9079
9101
  super(props);
@@ -9196,8 +9218,9 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9196
9218
  const id = this.getGeneId();
9197
9219
  if (!this.props.geneDocs.hasOwnProperty(id)) return;
9198
9220
  const gene = this.props.geneDocs[id];
9199
- if (!gene.homology) return;
9200
- const treeId = gene.homology.gene_tree.id;
9221
+ const ref = $64fad37f770d2bfe$var$geneTreeRef(gene);
9222
+ if (!ref) return;
9223
+ const treeId = ref.id;
9201
9224
  const raw = this.props.grameneTrees[treeId];
9202
9225
  if (!raw || !raw.taxon_id) return;
9203
9226
  const adapted = (0, $gXNCa$tbrowse.fromGrameneGenetree)([
@@ -9247,8 +9270,9 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9247
9270
  const id = this.getGeneId();
9248
9271
  if (!this.props.geneDocs.hasOwnProperty(id)) return;
9249
9272
  const gene = this.props.geneDocs[id];
9250
- if (!gene.homology) return;
9251
- const treeId = gene.homology.gene_tree.id;
9273
+ const ref = $64fad37f770d2bfe$var$geneTreeRef(gene);
9274
+ if (!ref) return;
9275
+ const treeId = ref.id;
9252
9276
  const raw = this.props.grameneTrees[treeId];
9253
9277
  if (!raw || !raw.taxon_id) return;
9254
9278
  // Lazily compute the adapted tbrowse data the same way renderTBrowse
@@ -9260,13 +9284,13 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9260
9284
  raw
9261
9285
  ]);
9262
9286
  }
9263
- this.fetchNeighborhood(treeId);
9287
+ this.fetchNeighborhood(treeId, ref.field);
9264
9288
  // Only pay for gene-structure data when the genome zone is actually enabled.
9265
9289
  if (this.isGenomeZoneEnabled()) this.fetchGeneStructures(treeId, this._tbrowseData.tree);
9266
9290
  // Same for the per-gene expression attributes zone.
9267
- if (this.isExpressionZoneEnabled()) this.fetchExprAttrs(treeId, this._tbrowseData.tree);
9291
+ if (this.isExpressionZoneEnabled()) this.fetchExprAttrs(treeId, this._tbrowseData.tree, ref.field);
9268
9292
  }
9269
- fetchNeighborhood(treeId) {
9293
+ fetchNeighborhood(treeId, field = 'gene_tree') {
9270
9294
  if (this._neighborhoodFetchedFor === treeId) return;
9271
9295
  this._neighborhoodFetchedFor = treeId;
9272
9296
  this.setState({
@@ -9274,8 +9298,13 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9274
9298
  });
9275
9299
  const api = this.props.grameneAPI;
9276
9300
  const url = new URL(`${api}/search`);
9277
- url.searchParams.set('fl', 'id,name,gene_tree,gene_idx,region,start,end,strand,biotype,system_name,description');
9278
- url.searchParams.set('fq', `{!graph from=compara_neighbors_10 to=compara_idx_multi maxDepth=1}gene_tree:${treeId}`);
9301
+ const fl = 'id,name,gene_tree,gene_idx,region,start,end,strand,biotype,system_name,description';
9302
+ url.searchParams.set('fl', field === 'gene_tree' ? fl : `${fl},${field}`);
9303
+ // cache=false: as a cached fq the graph query caches its seed inside its own
9304
+ // filterCache computeIfAbsent, and Solr's FastLRUCache throws "Recursive
9305
+ // update" (HTTP 500) whenever the two keys collide — for some trees, until
9306
+ // the seed happens to be cached by another request.
9307
+ url.searchParams.set('fq', `{!graph from=compara_neighbors_10 to=compara_idx_multi maxDepth=1 cache=false}${field}:${treeId}`);
9279
9308
  url.searchParams.set('rows', '100000');
9280
9309
  url.searchParams.set('start', '0');
9281
9310
  fetch(url.toString(), {
@@ -9287,6 +9316,11 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9287
9316
  return res.json();
9288
9317
  }).then((json)=>{
9289
9318
  if (this._neighborhoodFetchedFor !== treeId) return;
9319
+ // The neighborhood zone colours genes by family from doc.gene_tree; in
9320
+ // a clade tree set the family id lives under the set's own field.
9321
+ if (field !== 'gene_tree' && json && json.response && Array.isArray(json.response.docs)) json.response.docs.forEach((d)=>{
9322
+ if (d[field] && !d.gene_tree) d.gene_tree = d[field];
9323
+ });
9290
9324
  this.setState({
9291
9325
  neighborhood: (0, $gXNCa$tbrowse.fromGrameneNeighborhood)(json),
9292
9326
  neighborhoodTreeId: treeId,
@@ -9344,13 +9378,13 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9344
9378
  });
9345
9379
  }
9346
9380
  // Fetch the expression attributes (expr_*__attr_*) for this tree's genes in a
9347
- // single query: scope by gene_tree and the `expression_attributes` capability
9381
+ // single query: scope by the tree's field and the `expression_attributes` capability
9348
9382
  // so only genes that actually have the data come back (rows high enough to
9349
9383
  // cover the whole tree). Uses /search (not /genes, whose trimmed docs omit the
9350
9384
  // attr fields) with an fl glob so the columns are discovered from the data
9351
9385
  // rather than hard-coded. `tree` is still needed to map gene ids to leaf node
9352
9386
  // ids (see buildExprByNode).
9353
- fetchExprAttrs(treeId, tree) {
9387
+ fetchExprAttrs(treeId, tree, field = 'gene_tree') {
9354
9388
  if (this._exprAttrsFetchedFor === treeId) return;
9355
9389
  this._exprAttrsFetchedFor = treeId;
9356
9390
  this.setState({
@@ -9359,7 +9393,7 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9359
9393
  const api = this.props.grameneAPI;
9360
9394
  const url = new URL(`${api}/search`);
9361
9395
  url.searchParams.set('q', '*:*');
9362
- url.searchParams.append('fq', `gene_tree:${treeId}`);
9396
+ url.searchParams.append('fq', `${field}:${treeId}`);
9363
9397
  url.searchParams.append('fq', 'capabilities:expression_attributes');
9364
9398
  url.searchParams.set('fl', 'id,expr_*__attr_*');
9365
9399
  url.searchParams.set('rows', '10000');
@@ -9436,7 +9470,7 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9436
9470
  });
9437
9471
  }
9438
9472
  renderTBrowse() {
9439
- const treeId = this.gene.homology.gene_tree.id;
9473
+ const treeId = this.treeRef.id;
9440
9474
  // Adapted tbrowse data is computed lazily in maybeFetchTbrowseData
9441
9475
  // (called from lifecycle). If the user just flipped to tbrowse and
9442
9476
  // the lifecycle hasn't fired yet, compute it once here without
@@ -9545,7 +9579,7 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9545
9579
  filterAllHomologs() {
9546
9580
  this.props.doReplaceGrameneFilters((0, $047461923b1badda$export$964d88edb00bbcaa)({
9547
9581
  category: 'Gene Tree',
9548
- fq_field: 'gene_tree',
9582
+ fq_field: this.treeRef.field,
9549
9583
  fq_value: this.tree._id,
9550
9584
  name: `Homologs of ${this.gene.name}`
9551
9585
  }));
@@ -9598,14 +9632,14 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9598
9632
  }
9599
9633
  }
9600
9634
  explorations() {
9601
- let x = [
9635
+ let x = this.tree ? [
9602
9636
  {
9603
9637
  name: 'Homologs',
9604
9638
  category: 'Gene Tree',
9605
9639
  count: this.tree.geneCount,
9606
9640
  handleClick: this.filterAllHomologs.bind(this)
9607
9641
  }
9608
- ];
9642
+ ] : [];
9609
9643
  if (this.orthologs) x.push({
9610
9644
  name: 'Orthologs',
9611
9645
  category: 'Gene Tree',
@@ -9643,7 +9677,29 @@ class $64fad37f770d2bfe$var$Homology extends (0, ($parcel$interopDefault($gXNCa$
9643
9677
  const id = this.props.searchResult.id;
9644
9678
  if (!this.props.geneDocs.hasOwnProperty(id)) return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $gXNCa$reactbootstrap.Spinner), {});
9645
9679
  this.gene = this.props.geneDocs[id];
9646
- const treeId = this.gene.homology.gene_tree.id;
9680
+ this.treeRef = $64fad37f770d2bfe$var$geneTreeRef(this.gene);
9681
+ if (!this.treeRef) {
9682
+ // Homologues but no tree (some pan-genome assemblies): offer the
9683
+ // ortholog/paralog searches instead of a phylogram.
9684
+ this.tree = undefined;
9685
+ this.orthologs = this.orthologList();
9686
+ this.paralogs = this.paralogList();
9687
+ const explorations = this.explorations();
9688
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)((0, $5c2c79352d3d7b81$export$47eb42ff093406d4), {
9689
+ children: [
9690
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $5c2c79352d3d7b81$export$393edc798c47379d), {
9691
+ children: "No gene tree is available for this gene."
9692
+ }, "description"),
9693
+ explorations.length > 0 && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $5c2c79352d3d7b81$export$900f1bfcd1cb6476), {
9694
+ explorations: explorations
9695
+ }, "explore"),
9696
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)((0, $5c2c79352d3d7b81$export$b2e089eb3692b073), {
9697
+ links: this.links()
9698
+ }, "links")
9699
+ ]
9700
+ });
9701
+ }
9702
+ const treeId = this.treeRef.id;
9647
9703
  if (!this.props.grameneTrees.hasOwnProperty(treeId)) this.props.doRequestGrameneTree(treeId);
9648
9704
  else {
9649
9705
  const tree = this.props.grameneTrees[treeId];