Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring, streamline genome list #1670

Merged
merged 2 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions src/main/java/org/broad/igv/feature/genome/Genome.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class Genome {
private static final int MAX_WHOLE_GENOME_LONG = 100;
private static Logger log = LogManager.getLogger(Genome.class);

GenomeConfig config;

private String id;
private String displayName;
private List<String> chromosomeNames;
Expand All @@ -98,9 +98,21 @@ public class Genome {
private String defaultPos;
private String nameSet;
private List<Hub> trackHubs;
private GenomeConfig config;


private static Genome nullGenome = null;

public synchronized static Genome nullGenome() {
if (nullGenome == null) {
nullGenome = new Genome("None", Arrays.asList(new Chromosome(0, "", 0)));
}
return nullGenome;
}

public Genome(GenomeConfig config) throws IOException {

public Genome(GenomeConfig config) throws IOException {
this.config = config;
id = config.getId();
displayName = config.getName();
nameSet = config.getNameSet();
Expand Down Expand Up @@ -180,7 +192,7 @@ public Genome(GenomeConfig config) throws IOException {
}
} else {
// No chromosome list. Try to fetch chromosome names from the sequence
if(this.chromosomeNames.isEmpty()) {
if (this.chromosomeNames.isEmpty()) {
this.chromosomeNames = sequence.getChromosomeNames();
}
}
Expand Down Expand Up @@ -228,8 +240,8 @@ public Genome(GenomeConfig config) throws IOException {
// TODO -- no place to go
}

if(config.getHubs() != null) {
for(String hubUrl : config.getHubs()) {
if (config.getHubs() != null) {
for (String hubUrl : config.getHubs()) {
try {
trackHubs.add(HubParser.loadHub(hubUrl, getUCSCId()));
} catch (Exception e) {
Expand Down Expand Up @@ -315,7 +327,7 @@ public String getCanonicalChrName(String str) {
try {
ChromAlias aliasRecord = chromAliasSource.search(str);

if(aliasRecord == null && !str.equals(str.toLowerCase())) {
if (aliasRecord == null && !str.equals(str.toLowerCase())) {
aliasRecord = chromAliasSource.search(str.toLowerCase());
}

Expand Down Expand Up @@ -817,12 +829,21 @@ public List<Hub> getTrackHubs() {
return trackHubs;
}

public synchronized static Genome nullGenome() {
if(nullGenome == null) {
nullGenome = new Genome("None", Arrays.asList(new Chromosome(0, "", 0)));
public void addTrackHub(Hub hub) {

if(!trackHubs.stream().anyMatch(h -> h.getUrl().equals(hub.getUrl()))) {
trackHubs.add(hub);
if (config.isFromJson()) {
config.addHub(hub.getUrl());
}
}
return nullGenome;
}

private static Genome nullGenome = null;
public boolean isFromJson() {
return config != null && config.isFromJson();
}

public GenomeConfig getConfig() {
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ public class GenomeConfig implements Cloneable {
private Sequence sequence;
private LinkedHashMap<String, List<Cytoband>> cytobands;
private List<List<String>> chromAliases;
private boolean fromJson = false; // Until proven otherwise

public static GenomeConfig fromJson(String json) {
if (json.contains("chromosomeOrder")) {
json = fixChromosomeOrder(json);
}
return (new Gson()).fromJson(json, GenomeConfig.class);
GenomeConfig config = (new Gson()).fromJson(json, GenomeConfig.class);
config.fromJson = true;
return config;
}

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

public void addHub(String hub) {
if (hubs == null) {
hubs = new ArrayList();
}
hubs.add(hub);
}

public String getId() {
return id;
}
Expand Down Expand Up @@ -339,4 +349,7 @@ private static String fixChromosomeOrder(String jsonString) {
return (new Gson()).toJson(obj);
}

public boolean isFromJson() {
return fromJson;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class HubGenomeLoader extends GenomeLoader {
static Logger log = LogManager.getLogger(HubGenomeLoader.class);

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

public static String convertToHubURL(String accension) {
Expand Down Expand Up @@ -90,9 +90,22 @@ protected void done() {
};

worker.execute();
}

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


private static GenomeConfig getGenomeConfig(Hub hub) throws IOException {

GenomeConfig config = hub.getGenomeConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,9 @@ public Genome loadGenome() throws IOException {
public GenomeConfig loadGenomeConfig() throws IOException {

try (InputStream is = ParsingUtils.openInputStream(genomePath)) {

String jsonString = ParsingUtils.readContentsFromStream(is);

GenomeConfig genomeConfig = GenomeConfig.fromJson(jsonString);

fixPaths(genomeConfig);

return genomeConfig;

}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/broad/igv/ucsc/hub/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public class Hub {
}
}

public boolean isAssemblyHub() {
return genomeStanza.hasProperty("twoBitPath");
}


public String getShortLabel() {
return hubStanza.hasProperty("shortLabel") ? hubStanza.getProperty("shortLabel") : this.url;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/broad/igv/ucsc/hub/HubLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.broad.igv.ucsc.hub;

import org.broad.igv.ui.IGV;

public class HubLoader {


static void loadHub(Hub hub) {


}
}
21 changes: 13 additions & 8 deletions src/main/java/org/broad/igv/ucsc/hub/HubParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ public static Hub loadAssemblyHub(String url) throws IOException {

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

boolean assemblyHub = genomeId == null;

int idx = url.lastIndexOf("/");

// Load stanzas from the hub.txt file, which might be all stanzas if 'useOneFile' is on
List<Stanza> stanzas = HubParser.loadStanzas(url);

Expand All @@ -51,6 +47,14 @@ public static Hub loadHub(String url, String genomeId) throws IOException {
throw new RuntimeException("Unexpected hub file -- expected 'genome' stanza but found " + stanzas.get(1).type);
}
genomeStanza = stanzas.get(1);

if(!genomeStanza.hasProperty("twoBitPath")) {
// Not an assembly hub, validate genome
if(!genomeStanza.getProperty("genome").equals(genomeId)) {
throw new RuntimeException("Hub file does not contain tracks for genome " + genomeId);
}
}

trackStanzas = new ArrayList<>(stanzas.subList(2, stanzas.size()));

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

// Find stanza for requested genome, or if no requested genome the first.

for (Stanza s : genomeStanzaList) {
if (genomeId == null || genomeId.equals(s.getProperty("genome"))) {
stanzas.add(s);
Expand All @@ -71,16 +76,16 @@ public static Hub loadHub(String url, String genomeId) throws IOException {
break;
}
}
if(trackDbURL == null) {
throw new RuntimeException("Hub file does not contain tracks for genome " + genomeId);
}
}

// Assembly hub validation
if (assemblyHub) {
if (genomeId == null ) {
if (!genomeStanza.hasProperty("twoBitPath")) {
throw new RuntimeException("Assembly hubs must specify 'twoBitPath'");
}
if (!genomeStanza.hasProperty("groups")) {
throw new RuntimeException("Assembly hubs must specify 'groups'");
}
}

if (genomeStanza.hasProperty("groups")) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/broad/igv/ucsc/hub/TrackDbHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
public class TrackDbHub {


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

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

} else if (!filterTracks.contains(s.name) &&
s.hasProperty("bigDataUrl") &&
supportedTypes.contains(s.format())) {
supportedTypes.contains(s.format().toLowerCase())) {

final TrackConfig trackConfig = getTrackConfig(s);
if (parent != null) {
Expand Down
Loading
Loading