Skip to content

Commit

Permalink
Recognize #gffTags directive in bed files and treat "name" property a…
Browse files Browse the repository at this point in the history
…ccordingly, consistent with IGV desktop. See #1550
  • Loading branch information
jrobinso committed Jan 23, 2025
1 parent 696a29f commit 4ca37f4
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
47 changes: 47 additions & 0 deletions dev/annotation/gffTags.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="author" content="Jim Robinson">
<link rel="shortcut icon" href="https://igv.org/web/https://igv.org/web/img/favicon.ico">
<title>igv.js</title>
</head>

<body>

<p>

<h1>Test of a CSI index with a gtf file</h1>

<div id="igvDiv" style="padding-top: 10px;padding-bottom: 10px; border:1px solid lightgray"></div>

<script type="module">

import igv from "../../js/index.js";

var options =
{
genome: "hg19",
locus: "chr1:1000-2000",
tracks:
[
{
name: "gff tags",
format: "bed",
url: `../../test/data/bed/gfftags.bed`,
}
]
};

var igvDiv = document.getElementById("igvDiv");

igv.createBrowser(igvDiv, options)
.then(function (browser) {
console.log("Created IGV browser");
})


</script>

</body>

</html>
11 changes: 8 additions & 3 deletions js/feature/decode/ucsc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {IGVColor} from "../../../node_modules/igv-utils/src/index.js"
import DecodeError from "./decodeError.js"

import {parseAttributeString} from "../gff/parseAttributeString.js"
import GFFHelper from "../gff/gffHelper.js"


/**
Expand Down Expand Up @@ -36,12 +37,16 @@ function decodeBed(tokens, header, maxColumnCount = Number.MAX_SAFE_INTEGER) {
feature.attributes = {}
for (let kv of attributeKVs) {
feature.attributes[kv[0]] = kv[1]
if (header.nameField != undefined && kv[0] === header.nameField) {
feature.name = kv[1]
if(gffTags) {
if (header.nameField != undefined && kv[0] === header.nameField) {
feature.name = kv[1]
} else if (!feature.name && GFFHelper.gffNameFields.has(kv[0])) {
feature.name = kv[1];
}
}
}
}
if (!feature.name) {
if (!feature.name && !gffTags) {
feature.name = tokens[3] === '.' ? '' : tokens[3]
}
}
Expand Down
5 changes: 2 additions & 3 deletions js/feature/gff/gffHelper.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {isExon, isTranscript, isTranscriptPart} from "./so.js"
import {GFFFeature, GFFTranscript} from "./gffFeature.js"

const gffNameFields = ["Name", "transcript_id", "gene_name", "gene", "gene_id", "alias", "locus", "name" ]

class GFFHelper {

static gffNameFields = new Set(["Name", "transcript_id", "gene_name", "gene", "gene_id", "alias", "locus", "name" ])
constructor(options) {
this.format = options.format
this.nameField = options.nameField
Expand Down Expand Up @@ -201,11 +201,10 @@ class GFFHelper {
// Find name (label) property
for (let f of features) {
if(typeof f.getAttributeValue === 'function') {

if (this.nameField) {
f.name = f.getAttributeValue(this.nameField)
} else {
for (let nameField of gffNameFields) {
for (let nameField of GFFHelper.gffNameFields) {
const v = f.getAttributeValue(nameField)
if (v) {
f.name = v
Expand Down
2 changes: 1 addition & 1 deletion test/data/bed/gfftags.bed
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#gffTags
track name="chr1" description="chr1 Annotations" itemRgb="On"
chr1 1088 1128 Key1=INS230;Key2=Foo 0 + 1088 1088 65,105,225
chr1 1088 1128 Key1=INS230;Key2=Foo;Name=INS230 0 + 1088 1088 65,105,225
chr1 133 2809 Key2=Bar;Key1=terminator 0 + 133 133 65,105,225
chr1 1301 1746 Key1=M13 origin;Key2=Baz 0 + 1301 1301 65,105,225
chr1 1301 1746 Key1=M13 origin;Key2=Baz 0 + 1301 1301 65,105,225

0 comments on commit 4ca37f4

Please sign in to comment.