Skip to content

Commit 991f01e

Browse files
committed
Additional track hub support: (#1651)
* Additional track hub support: * Fix bugs preventing loading of CHM13 / hs1 hub. Fixes #1643 * Enable addition of hubs as a track source to any IGV genome * UI improvements to track selection dialog
1 parent 3bf983d commit 991f01e

25 files changed

+1538
-1164
lines changed

src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
opens org.broad.igv.feature.genome.load to com.google.gson;
1313
opens org.broad.igv.feature to com.google.gson;
1414
exports org.broad.igv.ucsc;
15+
exports org.broad.igv.ucsc.hub;
1516

1617
requires com.google.common;
1718
requires commons.math3;

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

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
import org.broad.igv.logging.Logger;
5454
import org.broad.igv.track.FeatureTrack;
5555
import org.broad.igv.track.TribbleFeatureSource;
56-
import org.broad.igv.ucsc.Hub;
56+
import org.broad.igv.ucsc.hub.Hub;
57+
import org.broad.igv.ucsc.hub.HubParser;
5758
import org.broad.igv.ucsc.twobit.TwoBitSequence;
5859
import org.broad.igv.util.ResourceLocator;
5960
import org.broad.igv.util.liftover.Liftover;
@@ -96,14 +97,16 @@ public class Genome {
9697
private String homeChromosome;
9798
private String defaultPos;
9899
private String nameSet;
99-
private Hub hub;
100+
private Hub genomeHub;
101+
private List<Hub> trackHubs;
100102

101103
public Genome(GenomeConfig config) throws IOException {
102104

103105
id = config.getId();
104106
displayName = config.getName();
105107
nameSet = config.getNameSet();
106108
blatDB = config.getBlatDB();
109+
trackHubs = new ArrayList<>();
107110
if (config.getUcsdID() == null) {
108111
ucscID = ucsdIDMap.containsKey(id) ? ucsdIDMap.get(id) : id;
109112
} else {
@@ -226,6 +229,16 @@ public Genome(GenomeConfig config) throws IOException {
226229
// TODO -- no place to go
227230
}
228231

232+
if(config.getHubs() != null) {
233+
for(String hubUrl : config.getHubs()) {
234+
try {
235+
trackHubs.add(HubParser.loadHub(hubUrl, getId()));
236+
} catch (IOException e) {
237+
log.error("Error loading hub", e);
238+
}
239+
}
240+
}
241+
229242

230243
addTracks(config);
231244

@@ -254,6 +267,8 @@ public Genome(String id, List<Chromosome> chromosomes) {
254267
this.longChromosomeNames = computeLongChromosomeNames();
255268
this.homeChromosome = this.longChromosomeNames.size() > 1 ? Globals.CHR_ALL : chromosomeNames.get(0);
256269
this.chromAliasSource = (new ChromAliasDefaults(id, chromosomeNames));
270+
271+
this.trackHubs = new ArrayList<>();
257272
}
258273

259274
private void addTracks(GenomeConfig config) {
@@ -794,12 +809,18 @@ public List<String> computeLongChromosomeNames() {
794809

795810
}
796811

797-
public Hub getHub() {
798-
return hub;
812+
public Hub getGenomeHub() {
813+
return genomeHub;
814+
}
815+
816+
public void setGenomeHub(Hub genomeHub) {
817+
this.genomeHub = genomeHub;
818+
// A genome hub is by definition also a track hub
819+
this.trackHubs.add(genomeHub);
799820
}
800821

801-
public void setHub(Hub hub) {
802-
this.hub = hub;
822+
public List<Hub> getTrackHubs() {
823+
return trackHubs;
803824
}
804825

805826
public synchronized static Genome nullGenome() {

src/main/java/org/broad/igv/feature/genome/GenomeManager.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ public boolean loadGenomeById(String genomeId) throws IOException {
142142
return loadGenome(genomePath) != null; // monitor[0]);
143143
}
144144

145-
146145
/**
147146
* The main load method -- loads a genome from a file or url path. Note this is a long running operation and
148147
* should not be done on the Swing event thread as it will block the UI.

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class GenomeConfig implements Cloneable {
5454

5555
private List<TrackConfig> tracks;
5656

57-
private List<TrackConfig> annotations; // Backward compatibility, synonym for tracks
57+
private List<String> hubs;
5858

5959
// The properties below support the legacy ".genome" file, which directly loads resources from a zip archive.
6060

@@ -72,6 +72,14 @@ public static GenomeConfig fromJson(String json) {
7272
public GenomeConfig() {
7373
}
7474

75+
public List<String> getHubs() {
76+
return hubs;
77+
}
78+
79+
public void setHubs(List<String> hubs) {
80+
this.hubs = hubs;
81+
}
82+
7583
public String getId() {
7684
return id;
7785
}
@@ -257,7 +265,7 @@ public void setChromSizesURL(String chromSizesURL) {
257265
}
258266

259267
public List<TrackConfig> getTrackConfigs() {
260-
return tracks != null ? tracks : annotations;
268+
return tracks;
261269
}
262270

263271
public void setTracks(List<TrackConfig> tracks) {

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import org.broad.igv.Globals;
44
import org.broad.igv.feature.genome.Genome;
55
import org.broad.igv.prefs.PreferencesManager;
6-
import org.broad.igv.ucsc.Hub;
7-
import org.broad.igv.ucsc.TrackConfigGroup;
6+
import org.broad.igv.ucsc.hub.Hub;
7+
import org.broad.igv.ucsc.hub.HubParser;
8+
import org.broad.igv.ucsc.hub.TrackConfigGroup;
89
import org.broad.igv.ui.IGV;
9-
import org.broad.igv.ucsc.HubTrackSelectionDialog;
10+
import org.broad.igv.ucsc.hub.TrackHubSelectionDialog;
1011

1112
import java.io.IOException;
1213
import java.util.*;
@@ -44,9 +45,9 @@ public static String convertToHubURL(String accension) {
4445
@Override
4546
public Genome loadGenome() throws IOException {
4647

47-
Hub hub = Hub.loadHub(this.hubURL);
48+
Hub hub = HubParser.loadAssemblyHub(this.hubURL);
4849

49-
GenomeConfig config = hub.getGenomeConfig(false);
50+
GenomeConfig config = hub.getGenomeConfig();
5051

5152
// Potentially override default tracks from hub with user selections
5253

@@ -60,7 +61,6 @@ public Genome loadGenome() throws IOException {
6061
List<TrackConfig> selectedTracks = groupedTrackConfigurations.stream()
6162
.flatMap(group -> group.tracks.stream())
6263
.filter(trackConfig -> selectedTrackNames.contains(trackConfig.getName()))
63-
.sorted(Comparator.comparingInt(TrackConfig::getOrder))
6464
.collect(Collectors.toList());
6565
config.setTracks(selectedTracks);
6666
}
@@ -69,7 +69,7 @@ public Genome loadGenome() throws IOException {
6969
else if (IGV.hasInstance() && !Globals.isBatch() && !Globals.isHeadless() && !Globals.isTesting()) {
7070

7171
int count = 0;
72-
for(TrackConfigGroup g : groupedTrackConfigurations) {
72+
for (TrackConfigGroup g : groupedTrackConfigurations) {
7373
count += g.tracks.size();
7474
}
7575

@@ -79,7 +79,7 @@ else if (IGV.hasInstance() && !Globals.isBatch() && !Globals.isHeadless() && !Gl
7979
groupedTrackConfigurations.stream().filter(g -> g.label.startsWith("Gene")).collect(Collectors.toList());
8080

8181

82-
HubTrackSelectionDialog dlg = new HubTrackSelectionDialog(filteredGroups, IGV.getInstance().getMainFrame());
82+
TrackHubSelectionDialog dlg = new TrackHubSelectionDialog(hub, filteredGroups, IGV.getInstance().getMainFrame());
8383
dlg.setVisible(true);
8484

8585
List<TrackConfig> selectedTracks = dlg.getSelectedConfigs();
@@ -91,7 +91,7 @@ else if (IGV.hasInstance() && !Globals.isBatch() && !Globals.isHeadless() && !Gl
9191
}
9292

9393
Genome genome = new Genome(config);
94-
genome.setHub(hub);
94+
genome.setGenomeHub(hub);
9595

9696
return genome;
9797

src/main/java/org/broad/igv/feature/genome/load/TrackConfig.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
/**
44
* A static json-like object, emulates javascript equivalent. Created to ease port of session code from javascript.
5-
*
65
*/
76

87
public class TrackConfig implements Cloneable {
98

109
private String id;
1110
private String name;
11+
private String longLabel;
1212
private String url;
1313
private String indexURL;
1414
private String trixURL;
@@ -26,20 +26,21 @@ public class TrackConfig implements Cloneable {
2626
private Boolean visible;
2727
private String infoURL;
2828
private String searchIndex;
29-
3029
private String group;
31-
private Integer order;
3230
private Integer visibilityWindow;
3331
private Boolean indexed;
3432
private Boolean hidden;
3533
private String html;
3634
private String panelName;
3735

36+
private String stanzaParent; // For supporting track hubs
37+
3838
public TrackConfig() {
3939
}
4040

4141
/**
4242
* The only required property of a track configuration is a URL (which can be an actual URL or a static file path)
43+
*
4344
* @param url
4445
*/
4546
public TrackConfig(String url) {
@@ -62,6 +63,14 @@ public void setName(String name) {
6263
this.name = name;
6364
}
6465

66+
public String getLongLabel() {
67+
return longLabel;
68+
}
69+
70+
public void setLongLabel(String longLabel) {
71+
this.longLabel = longLabel;
72+
}
73+
6574
public String getUrl() {
6675
return url;
6776
}
@@ -206,14 +215,6 @@ public void setGroup(String group) {
206215
this.group = group;
207216
}
208217

209-
public Integer getOrder() {
210-
return order;
211-
}
212-
213-
public void setOrder(Integer order) {
214-
this.order = order;
215-
}
216-
217218
public Integer getVisibilityWindow() {
218219
return visibilityWindow;
219220
}
@@ -254,6 +255,14 @@ public void setPanelName(String panelName) {
254255
this.panelName = panelName;
255256
}
256257

258+
public String getStanzaParent() {
259+
return stanzaParent;
260+
}
261+
262+
public void setStanzaParent(String stanzaParent) {
263+
this.stanzaParent = stanzaParent;
264+
}
265+
257266
@Override
258267
protected TrackConfig clone() throws CloneNotSupportedException {
259268
return (TrackConfig) super.clone();

src/main/java/org/broad/igv/track/FeatureTrack.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ public String getValueStringAt(String chr, double position, int mouseX, int mous
389389

390390
StringBuffer buf = new StringBuffer();
391391
boolean firstFeature = true;
392-
int maxNumber = IGV.getInstance().isShowDetailsOnClick() ? 100 : 10;
392+
int maxNumber = 10;
393393
int n = 1;
394394
for (Feature feature : allFeatures) {
395395
if (feature != null && feature instanceof IGVFeature) {
@@ -409,7 +409,7 @@ public String getValueStringAt(String chr, double position, int mouseX, int mous
409409
}
410410
firstFeature = false;
411411
if (n > maxNumber) {
412-
buf.append("<hr><br<b>>+ " + (allFeatures.size() - maxNumber) + " more ...</b>");
412+
buf.append("<hr><br<b>+ " + (allFeatures.size() - maxNumber) + " more</b>");
413413
break;
414414
}
415415
}

0 commit comments

Comments
 (0)