diff --git a/src/main/java/org/broad/igv/feature/genome/Genome.java b/src/main/java/org/broad/igv/feature/genome/Genome.java index 990bd1ffd..ca2f145e4 100644 --- a/src/main/java/org/broad/igv/feature/genome/Genome.java +++ b/src/main/java/org/broad/igv/feature/genome/Genome.java @@ -55,6 +55,7 @@ import org.broad.igv.track.TribbleFeatureSource; import org.broad.igv.ucsc.Hub; import org.broad.igv.ucsc.twobit.TwoBitSequence; +import org.broad.igv.util.ParsingUtils; import org.broad.igv.util.ResourceLocator; import org.broad.igv.util.liftover.Liftover; @@ -242,6 +243,7 @@ public Genome(String id, List chromosomes) { chromosomeMap.put(chromosome.getName(), chromosome); } this.longChromosomeNames = computeLongChromosomeNames(); + this.homeChromosome = this.longChromosomeNames.size() > 1 ? Globals.CHR_ALL : chromosomeNames.get(0); this.chromAliasSource = (new ChromAliasDefaults(id, chromosomeNames)); } @@ -623,18 +625,15 @@ public long getWGLength() { } - // TODO A hack (obviously), we need to record a species in the genome definitions to support old style - // blat servers. + // Species mapping to support old style blat servers. This should not be needed for current IGV releases. private static Map ucscSpeciesMap; private static synchronized String getSpeciesForID(String id) { if (ucscSpeciesMap == null) { ucscSpeciesMap = new HashMap<>(); - InputStream is = null; + try (InputStream is = Genome.class.getResourceAsStream("speciesMapping.txt")) { - try { - is = Genome.class.getResourceAsStream("speciesMapping.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String nextLine; @@ -649,14 +648,7 @@ private static synchronized String getSpeciesForID(String id) { } } catch (IOException e) { log.error("Error reading species mapping table", e); - } finally { - if (is != null) try { - is.close(); - } catch (IOException e) { - log.error("", e); - } } - } for (Map.Entry entry : ucscSpeciesMap.entrySet()) { @@ -685,18 +677,6 @@ public List getAnnotationResources() { return annotationResources; } - /** - * Mock genome for unit tests - */ - - private Genome(String id) { - this.id = id; - } - - public boolean getShowWholeGenomeView() { - return showWholeGenomeView; - } - public Map getLiftoverMap() { return liftoverMap; } @@ -809,4 +789,12 @@ public void setHub(Hub hub) { this.hub = hub; } + public synchronized static Genome nullGenome() { + if(nullGenome == null) { + nullGenome = new Genome("None", Arrays.asList(new Chromosome(0, "", 0))); + } + return nullGenome; + } + + private static Genome nullGenome = null; } diff --git a/src/main/java/org/broad/igv/feature/genome/GenomeManager.java b/src/main/java/org/broad/igv/feature/genome/GenomeManager.java index 3783b7aa7..41f227fc7 100644 --- a/src/main/java/org/broad/igv/feature/genome/GenomeManager.java +++ b/src/main/java/org/broad/igv/feature/genome/GenomeManager.java @@ -134,21 +134,11 @@ public static File getGenomeFile(String genomePath) throws MalformedURLException return archiveFile; } - public void setCurrentGenome(Genome genome) { - if (genome != null) { - PreferencesManager.getPreferences().setLastGenome(genome.getId()); - } + // Setter provided for unit tests + public void setCurrentGenomeForTest(Genome genome) { this.currentGenome = genome; - if (genome != null) { - if (IGV.hasInstance()) { - IGV.getInstance().getSession().clearHistory(); - FrameManager.getDefaultFrame().setChromosomeName(genome.getHomeChromosome(), true); - IGVEventBus.getInstance().post(new GenomeChangeEvent(genome)); - } - } } - public void loadGenomeById(String genomeId) throws IOException { final Genome currentGenome = getCurrentGenome(); if (currentGenome != null && genomeId.equals(currentGenome.getId())) { @@ -176,6 +166,8 @@ public void loadGenomeById(String genomeId) throws IOException { /** * The main load method -- loads a genome from a file or url path. Note this is a long running operation and * should not be done on the Swing event thread as it will block the UI. + *

+ * NOTE: The member 'currentGenome' is set here as a side effect. * * @param genomePath * @return @@ -214,26 +206,8 @@ public Genome loadGenome(String genomePath) throws IOException { IGV.getInstance().resetSession(null); } - GenomeListItem genomeListItem = new GenomeListItem(newGenome.getDisplayName(), genomePath, newGenome.getId()); - final Set serverGenomeIDs = genomeListManager.getServerGenomeIDs(); - - boolean userDefined = !serverGenomeIDs.contains(newGenome.getId()); - genomeListManager.addGenomeItem(genomeListItem, userDefined); - - setCurrentGenome(newGenome); - - // hasInstance() test needed for unit tests - if (IGV.hasInstance()) { - IGV.getInstance().goToLocus(newGenome.getHomeChromosome()); // newGenome.getDefaultPos()); - loadGenomeAnnotations(newGenome); - IGV.getInstance().resetFrames(); - } - - if (PreferencesManager.getPreferences().getAsBoolean(Constants.CIRC_VIEW_ENABLED) && CircularViewUtilities.ping()) { - CircularViewUtilities.changeGenome(newGenome); - } + setCurrentGenome(genomePath, newGenome); - // log.warn("Genome loaded. id= " + newGenome.getId()); return currentGenome; } catch (SocketException e) { @@ -246,6 +220,33 @@ public Genome loadGenome(String genomePath) throws IOException { } } + public void setCurrentGenome(String genomePath, Genome newGenome) { + + GenomeListItem genomeListItem = new GenomeListItem(newGenome.getDisplayName(), genomePath, newGenome.getId()); + final Set serverGenomeIDs = genomeListManager.getServerGenomeIDs(); + + boolean userDefined = !serverGenomeIDs.contains(newGenome.getId()); + genomeListManager.addGenomeItem(genomeListItem, userDefined); + + this.currentGenome = newGenome; + + // hasInstance() check to filters unit test + if (IGV.hasInstance()) { + IGV.getInstance().goToLocus(newGenome.getHomeChromosome()); // newGenome.getDefaultPos()); + FrameManager.getDefaultFrame().setChromosomeName(newGenome.getHomeChromosome(), true); + + loadGenomeAnnotations(newGenome); + IGV.getInstance().resetFrames(); + IGV.getInstance().getSession().clearHistory(); + + PreferencesManager.getPreferences().setLastGenome(newGenome.getId()); + if (PreferencesManager.getPreferences().getAsBoolean(Constants.CIRC_VIEW_ENABLED) && CircularViewUtilities.ping()) { + CircularViewUtilities.changeGenome(newGenome); + } + IGVEventBus.getInstance().post(new GenomeChangeEvent(newGenome)); + } + } + /** * Load and initialize the track objects from the genome's track resource locators. Does not add the tracks * to the IGV instance. @@ -458,7 +459,7 @@ private static void updateSequenceMapFile() { public void refreshHostedGenome(String genomeId) { Map itemMap = GenomeListManager.getInstance().getServerGenomeMap(); - if(itemMap.containsKey(genomeId)) { + if (itemMap.containsKey(genomeId)) { downloadGenome(itemMap.get(genomeId), false); } } diff --git a/src/main/java/org/broad/igv/feature/genome/load/JsonGenomeLoader.java b/src/main/java/org/broad/igv/feature/genome/load/JsonGenomeLoader.java index bc06d5278..3ce550622 100644 --- a/src/main/java/org/broad/igv/feature/genome/load/JsonGenomeLoader.java +++ b/src/main/java/org/broad/igv/feature/genome/load/JsonGenomeLoader.java @@ -13,11 +13,13 @@ import org.broad.igv.logging.Logger; import org.broad.igv.track.TribbleFeatureSource; import org.broad.igv.util.FileUtils; +import org.broad.igv.util.HttpUtils; import org.broad.igv.util.ParsingUtils; import org.broad.igv.util.ResourceLocator; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -35,17 +37,16 @@ public JsonGenomeLoader(String genomePath) { @Override public Genome loadGenome() throws IOException { - BufferedReader reader = null; - try { - reader = ParsingUtils.openBufferedReader(genomePath); - String jsonString = ParsingUtils.readContentsAsString(genomePath); + try (InputStream is = ParsingUtils.openInputStream(genomePath + "..")){ + + String jsonString = ParsingUtils.readContentsFromStream(is); if (jsonString.contains("chromosomeOrder")) { jsonString = fixChromosomeOrder(jsonString); } - GenomeConfig genomeConfig = GenomeConfig.fromJson (jsonString); + GenomeConfig genomeConfig = GenomeConfig.fromJson(jsonString); fixPaths(genomeConfig); @@ -68,8 +69,6 @@ public Genome loadGenome() throws IOException { return genome; - } finally { - reader.close(); } } @@ -168,10 +167,9 @@ private void addToFeatureDB(List locators, Genome genome) { } private String stripQuotes(String str) { - if(str.startsWith("\"")) { + if (str.startsWith("\"")) { return str.substring(1, str.length() - 1); // Assume also ends with - } - else { + } else { return str; } } diff --git a/src/main/java/org/broad/igv/track/SequenceTrack.java b/src/main/java/org/broad/igv/track/SequenceTrack.java index 4d11c7d74..55db8d7eb 100644 --- a/src/main/java/org/broad/igv/track/SequenceTrack.java +++ b/src/main/java/org/broad/igv/track/SequenceTrack.java @@ -236,7 +236,12 @@ public void load(ReferenceFrame referenceFrame) { end = Math.min(end + w / 2 + 2, chromosomeLength); Genome genome = currentGenome; - String sequence = new String(genome.getSequence(chr, start, end)); + byte [] seqBytes = genome.getSequence(chr, start, end); + if(seqBytes == null) { + return; + + } + String sequence = new String(seqBytes); int mod = start % 3; int n1 = normalize3(3 - mod); diff --git a/src/main/java/org/broad/igv/ui/IGV.java b/src/main/java/org/broad/igv/ui/IGV.java index 63344ddc6..1e9a8664d 100644 --- a/src/main/java/org/broad/igv/ui/IGV.java +++ b/src/main/java/org/broad/igv/ui/IGV.java @@ -62,7 +62,6 @@ import org.broad.igv.session.autosave.SessionAutosaveManager; import org.broad.igv.track.*; import org.broad.igv.ui.WaitCursorManager.CursorToken; -import org.broad.igv.ui.commandbar.GenomeListManager; import org.broad.igv.ui.dnd.GhostGlassPane; import org.broad.igv.ui.panel.*; import org.broad.igv.ui.util.*; @@ -1942,21 +1941,26 @@ public void run() { } catch (Exception e) { MessageUtils.showErrorMessage("Error loading genome " + genomeId + "
" + e.getMessage(), e); genomeLoaded = false; - } + } if (!genomeLoaded) { - // If the error is with the default genome try refreshing it. - if(genomeId.equals(GenomeListManager.DEFAULT_GENOME.getId())) { - GenomeManager.getInstance().refreshHostedGenome(genomeId); - } + Genome genome = Genome.nullGenome(); + GenomeManager.getInstance().setCurrentGenome("", genome); - genomeId = GenomeListManager.DEFAULT_GENOME.getId(); - try { - GenomeManager.getInstance().loadGenomeById(genomeId); - } catch (IOException e) { - MessageUtils.showErrorMessage("Error loading genome: " + genomeId, e); - log.error("Error loading genome: " + genomeId, e); - } + + //GenomeManager.getInstance().setCurrentGenome(Genome.NoneGenome()); + // If the error is with the default genome try refreshing it. +// if(genomeId.equals(GenomeListManager.DEFAULT_GENOME.getId())) { +// GenomeManager.getInstance().refreshHostedGenome(genomeId); +// } +// +// genomeId = GenomeListManager.DEFAULT_GENOME.getId(); +// try { +// GenomeManager.getInstance().loadGenomeById(genomeId); +// } catch (IOException e) { +// MessageUtils.showErrorMessage("Error loading genome: " + genomeId, e); +// log.error("Error loading genome: " + genomeId, e); +// } } } diff --git a/src/main/java/org/broad/igv/ui/commandbar/IGVCommandBar.java b/src/main/java/org/broad/igv/ui/commandbar/IGVCommandBar.java index 771c3cb89..8c988de06 100644 --- a/src/main/java/org/broad/igv/ui/commandbar/IGVCommandBar.java +++ b/src/main/java/org/broad/igv/ui/commandbar/IGVCommandBar.java @@ -180,24 +180,30 @@ public void selectGenome(String genomeId) { public void updateCurrentCoordinates() { if (IGV.hasInstance()) { - String p = ""; - ReferenceFrame defaultFrame = FrameManager.getDefaultFrame(); - final String chrName = defaultFrame.getChrName(); - if (!Globals.CHR_ALL.equals(chrName) && !FrameManager.isGeneListMode()) { - p = defaultFrame.getFormattedLocusString(); - } - final String position = p; - final History history = IGV.getInstance().getSession().getHistory(); - UIUtilities.invokeOnEventThread(new Runnable() { - public void run() { + if(GenomeManager.getInstance().getCurrentGenome() == Genome.nullGenome()) { + UIUtilities.invokeOnEventThread(() -> { + searchTextField.setText(""); + }); + + } else { + String p = ""; + ReferenceFrame defaultFrame = FrameManager.getDefaultFrame(); + final String chrName = defaultFrame.getChrName(); + if (!Globals.CHR_ALL.equals(chrName) && !FrameManager.isGeneListMode()) { + p = defaultFrame.getFormattedLocusString(); + } + final String position = p; + final History history = IGV.getInstance().getSession().getHistory(); + + UIUtilities.invokeOnEventThread(() -> { searchTextField.setText(position); forwardButton.setEnabled(history.canGoForward()); backButton.setEnabled(history.canGoBack()); roiToggleButton.setEnabled(!Globals.CHR_ALL.equals(chrName)); zoomControl.setEnabled(!Globals.CHR_ALL.equals(chrName) && !FrameManager.isGeneListMode()); - } - }); + }); + } } } diff --git a/src/main/java/org/broad/igv/ui/panel/ZoomSliderPanel.java b/src/main/java/org/broad/igv/ui/panel/ZoomSliderPanel.java index d75964f29..52ff49439 100644 --- a/src/main/java/org/broad/igv/ui/panel/ZoomSliderPanel.java +++ b/src/main/java/org/broad/igv/ui/panel/ZoomSliderPanel.java @@ -106,7 +106,7 @@ public ZoomSliderPanel(ReferenceFrame referenceFrame) { } private void updateTickCount() { - int tmp = getReferenceFrame().getMaxZoom() + 1; + int tmp = Math.max(0, getReferenceFrame().getMaxZoom() + 1); if (tmp != numZoomLevels) { numZoomLevels = tmp; zoomLevelRects = new Rectangle[numZoomLevels]; diff --git a/src/main/java/org/broad/igv/util/ParsingUtils.java b/src/main/java/org/broad/igv/util/ParsingUtils.java index 93bd4f6c3..06e4685aa 100644 --- a/src/main/java/org/broad/igv/util/ParsingUtils.java +++ b/src/main/java/org/broad/igv/util/ParsingUtils.java @@ -147,10 +147,6 @@ public static String readContentsFromStream(InputStream is) throws IOException { return new String(bytes, "UTF-8"); } - public static String readContentsAsString(String path) throws IOException { - return readContentsFromStream(openInputStream(path)); - } - /** * Parse the string and return the result as an integer. This method supports scientific notation for integers, * which Integer.parseInt() does not. diff --git a/src/test/java/org/broad/igv/AbstractHeadlessTest.java b/src/test/java/org/broad/igv/AbstractHeadlessTest.java index 12356a83e..cf93f3ca9 100644 --- a/src/test/java/org/broad/igv/AbstractHeadlessTest.java +++ b/src/test/java/org/broad/igv/AbstractHeadlessTest.java @@ -58,14 +58,14 @@ public class AbstractHeadlessTest { @BeforeClass public static void setUpClass() throws Exception { setUpHeadless(); - GenomeManager.getInstance().setCurrentGenome(null); + GenomeManager.getInstance().setCurrentGenomeForTest(null); genome = TestUtils.loadGenome(); } @AfterClass public static void tearDownClass() throws Exception { TestUtils.clearOutputDir(); - GenomeManager.getInstance().setCurrentGenome(null); + GenomeManager.getInstance().setCurrentGenomeForTest(null); } @Before