Skip to content

Commit bc268b9

Browse files
authoredMar 10, 2025
Refactoring, streamline genome list (#1670)
* Refactoring, streamline genome list
1 parent 99a96b6 commit bc268b9

13 files changed

+246
-165
lines changed
 

‎src/main/java/org/broad/igv/feature/genome/Genome.java

+32-11
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public class Genome {
7474
private static final int MAX_WHOLE_GENOME_LONG = 100;
7575
private static Logger log = LogManager.getLogger(Genome.class);
7676

77-
GenomeConfig config;
77+
7878
private String id;
7979
private String displayName;
8080
private List<String> chromosomeNames;
@@ -98,9 +98,21 @@ public class Genome {
9898
private String defaultPos;
9999
private String nameSet;
100100
private List<Hub> trackHubs;
101+
private GenomeConfig config;
102+
103+
104+
private static Genome nullGenome = null;
105+
106+
public synchronized static Genome nullGenome() {
107+
if (nullGenome == null) {
108+
nullGenome = new Genome("None", Arrays.asList(new Chromosome(0, "", 0)));
109+
}
110+
return nullGenome;
111+
}
101112

102-
public Genome(GenomeConfig config) throws IOException {
103113

114+
public Genome(GenomeConfig config) throws IOException {
115+
this.config = config;
104116
id = config.getId();
105117
displayName = config.getName();
106118
nameSet = config.getNameSet();
@@ -180,7 +192,7 @@ public Genome(GenomeConfig config) throws IOException {
180192
}
181193
} else {
182194
// No chromosome list. Try to fetch chromosome names from the sequence
183-
if(this.chromosomeNames.isEmpty()) {
195+
if (this.chromosomeNames.isEmpty()) {
184196
this.chromosomeNames = sequence.getChromosomeNames();
185197
}
186198
}
@@ -228,8 +240,8 @@ public Genome(GenomeConfig config) throws IOException {
228240
// TODO -- no place to go
229241
}
230242

231-
if(config.getHubs() != null) {
232-
for(String hubUrl : config.getHubs()) {
243+
if (config.getHubs() != null) {
244+
for (String hubUrl : config.getHubs()) {
233245
try {
234246
trackHubs.add(HubParser.loadHub(hubUrl, getUCSCId()));
235247
} catch (Exception e) {
@@ -315,7 +327,7 @@ public String getCanonicalChrName(String str) {
315327
try {
316328
ChromAlias aliasRecord = chromAliasSource.search(str);
317329

318-
if(aliasRecord == null && !str.equals(str.toLowerCase())) {
330+
if (aliasRecord == null && !str.equals(str.toLowerCase())) {
319331
aliasRecord = chromAliasSource.search(str.toLowerCase());
320332
}
321333

@@ -817,12 +829,21 @@ public List<Hub> getTrackHubs() {
817829
return trackHubs;
818830
}
819831

820-
public synchronized static Genome nullGenome() {
821-
if(nullGenome == null) {
822-
nullGenome = new Genome("None", Arrays.asList(new Chromosome(0, "", 0)));
832+
public void addTrackHub(Hub hub) {
833+
834+
if(!trackHubs.stream().anyMatch(h -> h.getUrl().equals(hub.getUrl()))) {
835+
trackHubs.add(hub);
836+
if (config.isFromJson()) {
837+
config.addHub(hub.getUrl());
838+
}
823839
}
824-
return nullGenome;
825840
}
826841

827-
private static Genome nullGenome = null;
842+
public boolean isFromJson() {
843+
return config != null && config.isFromJson();
844+
}
845+
846+
public GenomeConfig getConfig() {
847+
return config;
848+
}
828849
}

‎src/main/java/org/broad/igv/feature/genome/load/GenomeConfig.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ public class GenomeConfig implements Cloneable {
6161
private Sequence sequence;
6262
private LinkedHashMap<String, List<Cytoband>> cytobands;
6363
private List<List<String>> chromAliases;
64+
private boolean fromJson = false; // Until proven otherwise
6465

6566
public static GenomeConfig fromJson(String json) {
6667
if (json.contains("chromosomeOrder")) {
6768
json = fixChromosomeOrder(json);
6869
}
69-
return (new Gson()).fromJson(json, GenomeConfig.class);
70+
GenomeConfig config = (new Gson()).fromJson(json, GenomeConfig.class);
71+
config.fromJson = true;
72+
return config;
7073
}
7174

7275
public GenomeConfig() {
@@ -84,6 +87,13 @@ public void setHubs(List<String> hubs) {
8487
this.hubs = hubs;
8588
}
8689

90+
public void addHub(String hub) {
91+
if (hubs == null) {
92+
hubs = new ArrayList();
93+
}
94+
hubs.add(hub);
95+
}
96+
8797
public String getId() {
8898
return id;
8999
}
@@ -339,4 +349,7 @@ private static String fixChromosomeOrder(String jsonString) {
339349
return (new Gson()).toJson(obj);
340350
}
341351

352+
public boolean isFromJson() {
353+
return fromJson;
354+
}
342355
}

‎src/main/java/org/broad/igv/feature/genome/load/HubGenomeLoader.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class HubGenomeLoader extends GenomeLoader {
3131
static Logger log = LogManager.getLogger(HubGenomeLoader.class);
3232

3333
public static boolean isHubURL(String obj) {
34-
return obj.endsWith("/hub.txt");
34+
return obj != null && obj.toLowerCase().endsWith("hub.txt"); // <= very crude, perhaps read the first line
3535
}
3636

3737
public static String convertToHubURL(String accension) {
@@ -90,9 +90,22 @@ protected void done() {
9090
};
9191

9292
worker.execute();
93+
}
9394

95+
/**
96+
* Shortcut method provided to support load-from-url. The hub must be read and parsed to determine if it is an
97+
* assembly hub. This method avoids the need to load and parse again.
98+
*
99+
* @param hub
100+
* @throws IOException
101+
*/
102+
public static void loadAssemblyHub(Hub hub) throws IOException {
103+
final GenomeConfig config = getGenomeConfig(hub);
104+
File genomeFile = GenomeDownloadUtils.saveLocalGenome(config);
105+
GenomeManager.getInstance().loadGenome(genomeFile.getAbsolutePath());
94106
}
95107

108+
96109
private static GenomeConfig getGenomeConfig(Hub hub) throws IOException {
97110

98111
GenomeConfig config = hub.getGenomeConfig();

‎src/main/java/org/broad/igv/feature/genome/load/JsonGenomeLoader.java

-4
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,9 @@ public Genome loadGenome() throws IOException {
6363
public GenomeConfig loadGenomeConfig() throws IOException {
6464

6565
try (InputStream is = ParsingUtils.openInputStream(genomePath)) {
66-
6766
String jsonString = ParsingUtils.readContentsFromStream(is);
68-
6967
GenomeConfig genomeConfig = GenomeConfig.fromJson(jsonString);
70-
7168
fixPaths(genomeConfig);
72-
7369
return genomeConfig;
7470

7571
}

‎src/main/java/org/broad/igv/ucsc/hub/Hub.java

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public class Hub {
5050
}
5151
}
5252

53+
public boolean isAssemblyHub() {
54+
return genomeStanza.hasProperty("twoBitPath");
55+
}
56+
5357

5458
public String getShortLabel() {
5559
return hubStanza.hasProperty("shortLabel") ? hubStanza.getProperty("shortLabel") : this.url;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.broad.igv.ucsc.hub;
2+
3+
import org.broad.igv.ui.IGV;
4+
5+
public class HubLoader {
6+
7+
8+
static void loadHub(Hub hub) {
9+
10+
11+
}
12+
}

‎src/main/java/org/broad/igv/ucsc/hub/HubParser.java

+13-8
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ public static Hub loadAssemblyHub(String url) throws IOException {
2525

2626
public static Hub loadHub(String url, String genomeId) throws IOException {
2727

28-
boolean assemblyHub = genomeId == null;
29-
30-
int idx = url.lastIndexOf("/");
31-
3228
// Load stanzas from the hub.txt file, which might be all stanzas if 'useOneFile' is on
3329
List<Stanza> stanzas = HubParser.loadStanzas(url);
3430

@@ -51,6 +47,14 @@ public static Hub loadHub(String url, String genomeId) throws IOException {
5147
throw new RuntimeException("Unexpected hub file -- expected 'genome' stanza but found " + stanzas.get(1).type);
5248
}
5349
genomeStanza = stanzas.get(1);
50+
51+
if(!genomeStanza.hasProperty("twoBitPath")) {
52+
// Not an assembly hub, validate genome
53+
if(!genomeStanza.getProperty("genome").equals(genomeId)) {
54+
throw new RuntimeException("Hub file does not contain tracks for genome " + genomeId);
55+
}
56+
}
57+
5458
trackStanzas = new ArrayList<>(stanzas.subList(2, stanzas.size()));
5559

5660
} else {
@@ -63,6 +67,7 @@ public static Hub loadHub(String url, String genomeId) throws IOException {
6367
List<Stanza> genomeStanzaList = HubParser.loadStanzas(hubStanza.getProperty("genomesFile"));
6468

6569
// Find stanza for requested genome, or if no requested genome the first.
70+
6671
for (Stanza s : genomeStanzaList) {
6772
if (genomeId == null || genomeId.equals(s.getProperty("genome"))) {
6873
stanzas.add(s);
@@ -71,16 +76,16 @@ public static Hub loadHub(String url, String genomeId) throws IOException {
7176
break;
7277
}
7378
}
79+
if(trackDbURL == null) {
80+
throw new RuntimeException("Hub file does not contain tracks for genome " + genomeId);
81+
}
7482
}
7583

7684
// Assembly hub validation
77-
if (assemblyHub) {
85+
if (genomeId == null ) {
7886
if (!genomeStanza.hasProperty("twoBitPath")) {
7987
throw new RuntimeException("Assembly hubs must specify 'twoBitPath'");
8088
}
81-
if (!genomeStanza.hasProperty("groups")) {
82-
throw new RuntimeException("Assembly hubs must specify 'groups'");
83-
}
8489
}
8590

8691
if (genomeStanza.hasProperty("groups")) {

‎src/main/java/org/broad/igv/ucsc/hub/TrackDbHub.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
public class TrackDbHub {
1313

1414

15-
static Set supportedTypes = new HashSet(Arrays.asList("bigBed", "bigWig", "bigGenePred", "vcfTabix", "refgene", "bam", "sampleInfo", "vcf.list"));
15+
static Set supportedTypes = new HashSet(Arrays.asList("bigbed", "bigwig", "biggenepred", "vcftabix", "refgene",
16+
"bam", "sampleinfo", "vcf.list", "ucscsnp", "bed", "tdf", "gff", "gff3", "gtf"));
1617

1718
static Set filterTracks = new HashSet(Arrays.asList("cytoBandIdeo", "assembly", "gap", "gapOverlap", "allGaps",
1819
"cpgIslandExtUnmasked", "windowMasker"));
@@ -99,7 +100,7 @@ public List<TrackConfigContainer> getGroupedTrackConfigurations(String hubName)
99100

100101
} else if (!filterTracks.contains(s.name) &&
101102
s.hasProperty("bigDataUrl") &&
102-
supportedTypes.contains(s.format())) {
103+
supportedTypes.contains(s.format().toLowerCase())) {
103104

104105
final TrackConfig trackConfig = getTrackConfig(s);
105106
if (parent != null) {

0 commit comments

Comments
 (0)
Please sign in to comment.