getLiftoverMap() {
return liftoverMap;
}
@@ -809,4 +795,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 3783b7aa74..6d1a13abec 100644
--- a/src/main/java/org/broad/igv/feature/genome/GenomeManager.java
+++ b/src/main/java/org/broad/igv/feature/genome/GenomeManager.java
@@ -134,48 +134,46 @@ 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));
- }
- }
}
+ /**
+ * Load a genome by ID, which might be a file path or URL
+ *
+ * @param genomeId - ID for an IGV hosted genome, or file path or url
+ * @return boolean flag indicating success
+ * @throws IOException
+ */
+ public boolean loadGenomeById(String genomeId) throws IOException {
- public void loadGenomeById(String genomeId) throws IOException {
final Genome currentGenome = getCurrentGenome();
if (currentGenome != null && genomeId.equals(currentGenome.getId())) {
- return; // Already loaded
+ return false;
}
- String genomePath = null;
+ String genomePath;
if (org.broad.igv.util.ParsingUtils.fileExists(genomeId)) {
genomePath = genomeId;
} else {
GenomeListItem item = genomeListManager.getGenomeListItem(genomeId);
if (item == null) {
MessageUtils.showMessage("Could not locate genome with ID: " + genomeId);
- return;
+ return false;
} else {
genomePath = item.getPath();
}
}
-
- loadGenome(genomePath); // monitor[0]);
-
+ return loadGenome(genomePath) != null; // monitor[0]);
}
/**
* 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 +212,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();
- }
+ setCurrentGenome(genomePath, newGenome);
- if (PreferencesManager.getPreferences().getAsBoolean(Constants.CIRC_VIEW_ENABLED) && CircularViewUtilities.ping()) {
- CircularViewUtilities.changeGenome(newGenome);
- }
-
- // log.warn("Genome loaded. id= " + newGenome.getId());
return currentGenome;
} catch (SocketException e) {
@@ -246,6 +226,37 @@ 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();
+
+ if(newGenome != Genome.nullGenome()) {
+ // This should only occur on startup failure
+ 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 +469,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/GenomeServerException.java b/src/main/java/org/broad/igv/feature/genome/GenomeServerException.java
deleted file mode 100644
index 30dc81f96d..0000000000
--- a/src/main/java/org/broad/igv/feature/genome/GenomeServerException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2007-2015 Broad Institute
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package org.broad.igv.feature.genome;
-
-
-/**
- * @author eflakes
- */
-public class GenomeServerException extends GenomeException {
-
- public GenomeServerException(String message) {
- super(message);
- }
-
- public GenomeServerException(String message, Throwable e) {
- super(message, e);
- }
-}
\ No newline at end of file
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 bc06d52787..c4c87db379 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/session/SessionWriter.java b/src/main/java/org/broad/igv/session/SessionWriter.java
index b86f7c84a3..c60785742d 100644
--- a/src/main/java/org/broad/igv/session/SessionWriter.java
+++ b/src/main/java/org/broad/igv/session/SessionWriter.java
@@ -25,6 +25,7 @@
package org.broad.igv.session;
+import org.broad.igv.feature.genome.Genome;
import org.broad.igv.feature.genome.GenomeListItem;
import org.broad.igv.logging.*;
import org.broad.igv.feature.RegionOfInterest;
@@ -426,13 +427,16 @@ public Collection getResourceLocatorSet() {
if (currentTrackFileLocators != null) {
// Filter data files that are included in genome annotations
- List genomeResources = GenomeManager.getInstance().getCurrentGenome().getAnnotationResources();
- Set absoluteGenomeAnnotationPaths = genomeResources == null ? Collections.emptySet() :
- genomeResources.stream().map(rl -> rl.getPath()).collect(Collectors.toSet());
-
- for (ResourceLocator locator : currentTrackFileLocators) {
- if (!absoluteGenomeAnnotationPaths.contains(locator.getPath())) {
- locators.add(locator);
+ final Genome currentGenome = GenomeManager.getInstance().getCurrentGenome();
+ if(currentGenome != null) {
+ List genomeResources = currentGenome.getAnnotationResources();
+ Set absoluteGenomeAnnotationPaths = genomeResources == null ? Collections.emptySet() :
+ genomeResources.stream().map(rl -> rl.getPath()).collect(Collectors.toSet());
+
+ for (ResourceLocator locator : currentTrackFileLocators) {
+ if (!absoluteGenomeAnnotationPaths.contains(locator.getPath())) {
+ locators.add(locator);
+ }
}
}
}
diff --git a/src/main/java/org/broad/igv/track/SequenceTrack.java b/src/main/java/org/broad/igv/track/SequenceTrack.java
index 4d11c7d747..55db8d7eb4 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 63344ddc6b..a9ad28bf21 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.*;
@@ -1926,8 +1925,7 @@ public void run() {
if (igvArgs.getGenomeId() != null) {
String genomeId = igvArgs.getGenomeId();
try {
- GenomeManager.getInstance().loadGenomeById(genomeId);
- genomeLoaded = true;
+ genomeLoaded = GenomeManager.getInstance().loadGenomeById(genomeId);
} catch (IOException e) {
MessageUtils.showErrorMessage("Error loading genome: " + genomeId, e);
log.error("Error loading genome: " + genomeId, e);
@@ -1937,26 +1935,30 @@ public void run() {
if (igvArgs.getSessionFile() == null && !loadAutosave && !genomeLoaded) {
String genomeId = preferences.getDefaultGenome();
try {
- GenomeManager.getInstance().loadGenomeById(genomeId);
- genomeLoaded = true;
+ genomeLoaded = GenomeManager.getInstance().loadGenomeById(genomeId);
} 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/GenomeComboBox.java b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
index 9bb1fedafe..9a2dc7839e 100644
--- a/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
+++ b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
@@ -6,7 +6,6 @@
import org.broad.igv.event.IGVEventBus;
import org.broad.igv.feature.genome.GenomeListItem;
import org.broad.igv.feature.genome.GenomeManager;
-import org.broad.igv.feature.genome.GenomeServerException;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.UIConstants;
import org.broad.igv.ui.util.MessageUtils;
@@ -21,7 +20,6 @@
import java.io.File;
import java.io.IOException;
import java.util.*;
-import java.util.List;
/**
* Created by jrobinso on 7/6/17.
@@ -96,29 +94,24 @@ private void loadGenomeListItem(final GenomeListItem genomeListItem) {
return;
}
- final Runnable runnable = new Runnable() {
+ final Runnable runnable = () -> {
- public void run() {
+ if (genomeListItem != null && genomeListItem.getPath() != null) {
- if (genomeListItem != null && genomeListItem.getPath() != null) {
-
- //log.warn("Loading " + genomeListItem.getId());
-
- //User selected "more", pull up dialog and revert combo box
- if (genomeListItem == GenomeListItem.DOWNLOAD_ITEM) {
- loadGenomeFromServer();
- return;
- }
+ if (genomeListItem == GenomeListItem.DOWNLOAD_ITEM) {
+ loadGenomeFromServer();
+ } else {
+ boolean success = false;
+ Exception error = null;
try {
- GenomeManager.getInstance().loadGenomeById(genomeListItem.getId());
- } catch (GenomeServerException e) {
- log.error("Error loading genome: " + genomeListItem.getId() + " " + genomeListItem.getPath(), e);
- JOptionPane.showMessageDialog(
- IGV.getInstance().getMainFrame(),
- "Error loading genome: " + genomeListItem.getDisplayableName());
+ success = GenomeManager.getInstance().loadGenomeById(genomeListItem.getId());
} catch (Exception e) {
log.error(e);
+ error = e;
+ }
+
+ if (!success) {
int choice = JOptionPane.showConfirmDialog(
IGV.getInstance().getMainFrame(), "The genome [" + genomeListItem.getId() +
"] could not be read. Would you like to remove the selected entry?",
@@ -127,12 +120,9 @@ public void run() {
if (choice == JOptionPane.OK_OPTION) {
GenomeListManager.getInstance().removeGenomeListItem(genomeListItem);
refreshGenomeListComboBox();
- log.error("Error initializing genome", e);
+ log.error("Error initializing genome", error);
}
- } finally {
-
}
-
}
}
};
@@ -231,27 +221,27 @@ public static void loadGenomeFromServer() {
IGVEventBus.getInstance().post(new GenomeResetEvent());
} else {
GenomeListItem selectedValue = dialog.getSelectedValue();
- if (selectedValue != null) {
-
- try {
- GenomeManager.getInstance().loadGenome(selectedValue.getPath());
+ if (selectedValue != null) {
- GenomeListManager.getInstance().addServerGenomeItem(selectedValue);
+ try {
+ GenomeManager.getInstance().loadGenome(selectedValue.getPath());
- GenomeListManager.getInstance().removeUserDefinedGenome(selectedValue.getId());
+ GenomeListManager.getInstance().addServerGenomeItem(selectedValue);
- // If this is a .json genome, attempt to remove existing .genome files
- if(selectedValue.getPath().endsWith(".json")) {
- removeDotGenomeFile(selectedValue.getId());
- }
+ GenomeListManager.getInstance().removeUserDefinedGenome(selectedValue.getId());
- } catch (IOException e) {
- GenomeListManager.getInstance().removeGenomeListItem(selectedValue);
- MessageUtils.showErrorMessage("Error loading genome " + selectedValue.getDisplayableName(), e);
- log.error("Error loading genome " + selectedValue.getDisplayableName(), e);
+ // If this is a .json genome, attempt to remove existing .genome files
+ if (selectedValue.getPath().endsWith(".json")) {
+ removeDotGenomeFile(selectedValue.getId());
}
+ } catch (IOException e) {
+ GenomeListManager.getInstance().removeGenomeListItem(selectedValue);
+ MessageUtils.showErrorMessage("Error loading genome " + selectedValue.getDisplayableName(), e);
+ log.error("Error loading genome " + selectedValue.getDisplayableName(), e);
}
+
+ }
}
};
@@ -265,7 +255,7 @@ public static void loadGenomeFromServer() {
public static void removeDotGenomeFile(String id) {
try {
File dotGenomeFile = new File(DirectoryManager.getGenomeCacheDirectory(), id + ".genome");
- if(dotGenomeFile.exists()) {
+ if (dotGenomeFile.exists()) {
dotGenomeFile.delete();
}
} catch (Exception 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 771c3cb89b..8c988de069 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/ReferenceFrame.java b/src/main/java/org/broad/igv/ui/panel/ReferenceFrame.java
index 8e315fdd9f..2b070b06a1 100644
--- a/src/main/java/org/broad/igv/ui/panel/ReferenceFrame.java
+++ b/src/main/java/org/broad/igv/ui/panel/ReferenceFrame.java
@@ -641,13 +641,14 @@ public int getMidpoint() {
*/
public String getFormattedLocusString() {
-// if (zoom == 0) {
-// return getGenome().getChromosomeDisplayName(getChrName());
-// } else {
Range range = getCurrentRange();
- String c = getGenome().getChromosomeDisplayName(range.getChr());
- return Locus.getFormattedLocusString(c, range.getStart(), range.getEnd());
- // }
+ final Genome genome = getGenome();
+ if(genome != null) {
+ String c = genome.getChromosomeDisplayName(range.getChr());
+ return Locus.getFormattedLocusString(c, range.getStart(), range.getEnd());
+ } else {
+ return "";
+ }
}
public Range getCurrentRange() {
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 d75964f294..52ff494393 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 93bd4f6c34..06e4685aa3 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 12356a83e6..cf93f3ca90 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
From e658784e7dd4516cc4493bb481e6cbc3a5fdaf6c Mon Sep 17 00:00:00 2001
From: Louis Bergelson
Date: Fri, 13 Sep 2024 13:24:58 -0400
Subject: [PATCH 045/130] Update to Java 21 and gradle 8.10.1 (#1568)
* Update to Java 21 and gradle 8.10.1
* Move from Java 17 -> Java 21
* Update from gradle 8.0.2 -> 8.10.1
* Replace some deprecated gradle code with newer styles
* Something changed in the module resolution with this update which caused us to not be able to
resolve automatic modules.
* Introduced a new gradle plugin which fixes the problem and removed the manual module
path manipulation we were doing.
* update github actions
---
.github/workflows/gradle.yml | 18 +---
README.md | 2 +-
build.gradle | 109 +++++++++++++----------
gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 61608 bytes
gradle/wrapper/gradle-wrapper.properties | 2 +-
gradlew | 4 +-
6 files changed, 71 insertions(+), 64 deletions(-)
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index be85ad7178..767efaa8fb 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -22,10 +22,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
@@ -36,16 +36,6 @@ jobs:
- name: Test with Gradle Wrapper
run: ./gradlew test
- # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html).
- # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version.
- #
- # - name: Setup Gradle
- # uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
- # with:
- # gradle-version: '8.5'
- #
- # - name: Build with Gradle 8.5
- # run: gradle build
dependency-submission:
@@ -55,10 +45,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
diff --git a/README.md b/README.md
index 7352385162..ebb0415838 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ at [http://software.broadinstitute.org/software/igv/download](http://software.br
Builds are executed from the IGV project directory. Files will be created in the 'build' subdirectory.
-IGV requires **Java 17** to build and run. Later versions of Java should work but we build and test on **Java 17**.
+IGV requires **Java 21** to build and run. Later versions of Java should work but we build and test on **Java 21**.
NOTE: If on a Windows platform use ```./gradlew.bat'``` in the instructions below
diff --git a/build.gradle b/build.gradle
index 089ce3e033..1508dffb43 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,29 +21,34 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-apply plugin: 'java'
-apply plugin: 'maven-publish'
-apply plugin: 'application'
-
-import org.apache.tools.ant.filters.ReplaceTokens
-
-mainClassName = 'org.broad.igv.ui.Main'
-ext.moduleName = 'org.igv'
-
buildscript {
repositories {
mavenCentral()
}
}
+plugins {
+ id('java')
+ id('maven-publish')
+ id('application')
+ id("org.gradlex.extra-java-module-info") version("1.8")
+}
+
repositories {
mavenCentral()
mavenLocal()
}
+import org.apache.tools.ant.filters.ReplaceTokens
+
+application {
+ mainClass = 'org.broad.igv.ui.Main'
+ mainModule = 'org.igv'
+}
+
java {
toolchain {
- languageVersion = JavaLanguageVersion.of(17)
+ languageVersion = JavaLanguageVersion.of(21)
}
}
@@ -56,6 +61,10 @@ sourceSets {
}
}
+extraJavaModuleInfo {
+ deriveAutomaticModuleNamesFromFileNames.set(true)
+}
+
configurations {
implementation {
exclude group: 'com.google.code.findbugs', module: 'annotations'
@@ -130,12 +139,16 @@ dependencies {
)
testImplementation(
- [group: 'junit', name: 'junit', version: '4.13.1'],
+ [group: 'junit', name: 'junit', version: '4.13.2'],
[group: 'com.sparkjava', name: 'spark-core', version: '2.9.4'],
[group: 'org.glassfish.jersey.core', name: 'jersey-common', version: '2.34']
)
testRuntimeOnly(
- [group: 'org.junit.vintage', name:'junit-vintage-engine', version:'5.8.2']
+ [group: 'org.junit.vintage', name:'junit-vintage-engine', version:'5.8.2'] ,
+ //required by gradle 9+
+ //see https://docs.gradle.org/8.10.1/userguide/upgrading_version_8.html#test_framework_implementation_dependencies
+ [group: 'org.junit.platform', name:'junit-platform-launcher']
+
)
}
@@ -160,7 +173,7 @@ jar {
"Permissions": "all-permissions",
"Application-Name": "IGV",
"Built-By": System.getProperty('user.name'),
- "Main-Class": mainClassName,
+ "Main-Class": application.mainClass,
)
}
}
@@ -169,18 +182,9 @@ tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
-compileJava {
- inputs.property("moduleName", moduleName)
- doFirst {
- options.compilerArgs = [
- '--module-path', classpath.asPath,
- ]
- classpath = files()
- }
-}
-
-tasks.withType(Test) {
- systemProperties = System.getProperties()
+tasks.withType(Test).configureEach {
+ systemProperties.clear()
+ systemProperties.putAll( System.getProperties() )
systemProperties['java.awt.headless'] = 'true'
systemProperties['make.fail'] = 'false'
systemProperties['include.longrunning'] = 'false'
@@ -191,7 +195,8 @@ tasks.withType(Test) {
useJUnitPlatform()
}
-task createDist(type: Copy, dependsOn: jar) {
+tasks.register('createDist', Copy) {
+ dependsOn jar
from("web/IGV_64.png")
from("scripts") {
include '*.bat'
@@ -204,14 +209,14 @@ task createDist(type: Copy, dependsOn: jar) {
with copySpec {
from("${buildDir}/libs")
from("lib") {
- include '*.jar'
+ include '*.jar'
}
into "lib"
}
// Copies all Maven-fetched dependency jars
with copySpec {
from configurations.runtimeClasspath {
- exclude '**/*log4j*.jar'
+ exclude '**/*log4j*.jar'
}
into "lib"
duplicatesStrategy DuplicatesStrategy.EXCLUDE
@@ -226,14 +231,16 @@ tasks.distTar.enabled = false
tasks.startScripts.enabled = false
// Create the platform agnostic zip distribution
-task createDistZip(type: Zip, dependsOn: createDist) {
+tasks.register('createDistZip', Zip) {
+ dependsOn createDist
archiveFileName = "IGV_${version}.zip"
from("${buildDir}/IGV-dist")
into "IGV_${version}"
}
// Create a linux distribution for IGV , excluding igvtools. Basically identical to generic dist without window and mac scripts
-task createLinuxDistZip(type: Zip, dependsOn: createDist) {
+tasks.register('createLinuxDistZip', Zip) {
+ dependsOn createDist
archiveFileName = "IGV_Linux_${version}.zip"
from("${buildDir}/IGV-dist") {
exclude "*.bat"
@@ -245,9 +252,10 @@ task createLinuxDistZip(type: Zip, dependsOn: createDist) {
}
// Create a linux distrubtion with bundled Java
-task createLinuxWithJavaDistZip(type: Zip, dependsOn: createDist) {
+tasks.register('createLinuxWithJavaDistZip', Zip) {
+ dependsOn createDist
archiveFileName = "IGV_Linux_${version}_WithJava.zip"
- with copySpec { from jdkBundleLinux into "jdk-17" }
+ with copySpec { from jdkBundleLinux into "jdk-21" }
from("${buildDir}/IGV-dist") {
exclude "*.bat"
exclude "*.command"
@@ -262,7 +270,8 @@ task createLinuxWithJavaDistZip(type: Zip, dependsOn: createDist) {
}
}
-task createMacDistZip(type: Zip, dependsOn: createDist) {
+tasks.register('createMacDistZip', Zip) {
+ dependsOn createDist
archiveFileName = "IGV_MacApp_${version}.zip"
from("${buildDir}/IGV-dist") {
exclude "*.bat"
@@ -274,9 +283,10 @@ task createMacDistZip(type: Zip, dependsOn: createDist) {
into "IGV_MacApp_${version}"
}
-task createMacWithJavaDistZip(type: Zip, dependsOn: createDist) {
+tasks.register('createMacWithJavaDistZip', Zip) {
+ dependsOn createDist
archiveFileName = "IGV_MacApp_${version}_WithJava.zip"
- with copySpec { from jdkBundleMac into "jdk-17" }
+ with copySpec { from jdkBundleMac into "jdk-21" }
from("${buildDir}/IGV-dist") {
exclude "*.bat"
exclude "*_hidpi*"
@@ -291,7 +301,8 @@ task createMacWithJavaDistZip(type: Zip, dependsOn: createDist) {
}
}
-task createMacAppDist(type: Copy, dependsOn: createDist) {
+tasks.register('createMacAppDist', Copy) {
+ dependsOn createDist
with copySpec {
from("scripts/mac.app") {
exclude "Contents/Info.plist.template"
@@ -324,8 +335,9 @@ task createMacAppDist(type: Copy, dependsOn: createDist) {
}
}
-task createMacAppDistZip(type: Zip, dependsOn: createMacAppDist) {
- archiveFileName = "IGV_MacApp_${version}.zip"
+tasks.register('createMacAppDistZip', Zip) {
+ dependsOn createMacAppDist
+ archiveFileName = "IGV_MacApp_${version}.zip"
from("${buildDir}/IGV-MacApp-dist")
doLast {
@@ -333,9 +345,10 @@ task createMacAppDistZip(type: Zip, dependsOn: createMacAppDist) {
}
}
-task createMacAppWithJavaDistZip(type: Zip, dependsOn: createMacAppDist) {
+tasks.register('createMacAppWithJavaDistZip', Zip) {
+ dependsOn createMacAppDist
archiveFileName = "IGV_MacApp_${version}_WithJava.zip"
- with copySpec { from jdkBundleMac into "IGV_${version}.app/Contents/jdk-17" }
+ with copySpec { from jdkBundleMac into "IGV_${version}.app/Contents/jdk-21" }
from("${buildDir}/IGV-MacApp-dist")
doLast {
@@ -368,8 +381,9 @@ task createWinDist(type: Copy, dependsOn: createDist) {
into "${buildDir}/IGV-WinExe-dist"
}
-task createWinWithJavaDist(type: Copy, dependsOn: createWinDist) {
- with copySpec { from jdkBundleWindows into "IGV_${version}/jdk-17" }
+tasks.register('createWinWithJavaDist', Copy) {
+ dependsOn createWinDist
+ with copySpec { from jdkBundleWindows into "IGV_${version}/jdk-21" }
with copySpec {
from("${buildDir}/IGV-WinExe-dist/IGV_${version}") { exclude 'installer.nsi' }
into "IGV_${version}"
@@ -388,7 +402,8 @@ task createWinWithJavaDist(type: Copy, dependsOn: createWinDist) {
}
}
-task createWinExeDist(type: Exec, dependsOn: createWinDist) {
+tasks.register('createWinExeDist', Exec) {
+ dependsOn createWinDist
commandLine(makensisCommand, "-O${buildDir}/tmp/nsis-WithJava-build.log",
"${buildDir}/IGV-WinExe-dist/installer.nsi")
doLast {
@@ -398,7 +413,8 @@ task createWinExeDist(type: Exec, dependsOn: createWinDist) {
}
}
-task createWinWithJavaExeDist(type: Exec, dependsOn: createWinWithJavaDist) {
+tasks.register('createWinWithJavaExeDist', Exec) {
+ dependsOn createWinWithJavaDist
commandLine(makensisCommand, "-O${buildDir}/tmp/nsis-build.log",
"${buildDir}/IGV-WinExe-WithJava-dist/installer.nsi")
doLast {
@@ -411,7 +427,8 @@ task createWinWithJavaExeDist(type: Exec, dependsOn: createWinWithJavaDist) {
}
}
-task signWinExeDist(type: Exec, dependsOn: createWinExeDist) {
+tasks.register('signWinExeDist', Exec) {
+ dependsOn createWinExeDist
standardInput = new ByteArrayInputStream(keyPassword.getBytes());
commandLine(signcodeCommand, "-spc", spcFile, "-v", pvkFile, "-a", "sha512",
"-\$", "commercial", "-n", "IGV ${version}", "-i", "http://www.igv.org/",
@@ -450,7 +467,7 @@ task fullJar(type: Jar, dependsOn: jar) {
"Permissions": "all-permissions",
"Application-Name": "IGV",
"Built-By": System.getProperty('user.name'),
- "Main-Class": mainClassName,
+ "Main-Class": application.mainClass,
"Class-Path": configurations.runtimeClasspath.collect { it.getName() }.join(' ')
)
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..ccebba7710deaf9f98673a68957ea02138b60d0a 100644
GIT binary patch
delta 5094
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
delta 5107
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
I6Xdi10eY*&F8}}l
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index bdc9a83b1e..c44c2304cf 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 65dcd68d65..79a61d421c 100755
--- a/gradlew
+++ b/gradlew
@@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC3045
+ # shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
From b3689ee773d839b28ba880a3d778e1bf4cd89730 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Wed, 11 Sep 2024 11:10:06 -0700
Subject: [PATCH 046/130] remove test generated file
---
test/data/fasta/out_order.fa.fai | 2 --
1 file changed, 2 deletions(-)
delete mode 100644 test/data/fasta/out_order.fa.fai
diff --git a/test/data/fasta/out_order.fa.fai b/test/data/fasta/out_order.fa.fai
deleted file mode 100644
index 10ac8e6d4a..0000000000
--- a/test/data/fasta/out_order.fa.fai
+++ /dev/null
@@ -1,2 +0,0 @@
-chr5 142 6 56 57
-chr1 600 157 60 61
From bfd072fef49095a45c2bfd36c4f146f280e8035a Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Fri, 13 Sep 2024 21:11:09 -0700
Subject: [PATCH 047/130] Update jdk-17 references to jdk-21
---
scripts/igv-launcher.bat | 6 +++---
scripts/igv.bat | 6 +++---
scripts/igv.command | 4 ++--
scripts/igv.sh | 4 ++--
scripts/igv_hidpi.sh | 4 ++--
scripts/igvtools | 4 ++--
scripts/igvtools.bat | 6 +++---
scripts/igvtools_gui | 4 ++--
scripts/igvtools_gui.bat | 6 +++---
scripts/igvtools_gui.command | 4 ++--
scripts/igvtools_gui_hidpi | 4 ++--
scripts/readme.txt | 6 +++---
12 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/scripts/igv-launcher.bat b/scripts/igv-launcher.bat
index 31bff24297..3e4fdd3644 100755
--- a/scripts/igv-launcher.bat
+++ b/scripts/igv-launcher.bat
@@ -1,9 +1,9 @@
setlocal
-if exist jdk-17 (
+if exist jdk-21 (
echo "Using bundled JDK."
- set JAVA_HOME=jdk-17
- set JAVA_CMD=jdk-17\bin\javaw
+ set JAVA_HOME=jdk-21
+ set JAVA_CMD=jdk-21\bin\javaw
) else (
echo "Using system JDK."
set JAVA_CMD=java
diff --git a/scripts/igv.bat b/scripts/igv.bat
index 1d6a56141b..a40bccd121 100755
--- a/scripts/igv.bat
+++ b/scripts/igv.bat
@@ -3,10 +3,10 @@ setlocal
for %%x in (%0) do set BatchPath=%%~dpsx
for %%x in (%BatchPath%) do set BatchPath=%%~dpsx
-if exist %BatchPath%\jdk-17 (
+if exist %BatchPath%\jdk-21 (
echo "Using bundled JDK."
- set JAVA_HOME=%BatchPath%\jdk-17
- set JAVA_CMD=%BatchPath%\jdk-17\bin\javaw
+ set JAVA_HOME=%BatchPath%\jdk-21
+ set JAVA_CMD=%BatchPath%\jdk-21\bin\javaw
) else (
echo "Using system JDK."
set JAVA_CMD=java
diff --git a/scripts/igv.command b/scripts/igv.command
index 42b06562f5..14d0aff07e 100755
--- a/scripts/igv.command
+++ b/scripts/igv.command
@@ -13,9 +13,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK. IGV requires Java 17."
diff --git a/scripts/igv.sh b/scripts/igv.sh
index 41ea0ec06c..400457f09e 100755
--- a/scripts/igv.sh
+++ b/scripts/igv.sh
@@ -11,9 +11,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK. IGV requires Java 17."
diff --git a/scripts/igv_hidpi.sh b/scripts/igv_hidpi.sh
index 8d8c2cd55b..e6d3d69265 100755
--- a/scripts/igv_hidpi.sh
+++ b/scripts/igv_hidpi.sh
@@ -11,9 +11,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
diff --git a/scripts/igvtools b/scripts/igvtools
index 4c55f1dc5a..c9e7a06f94 100755
--- a/scripts/igvtools
+++ b/scripts/igvtools
@@ -2,9 +2,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
diff --git a/scripts/igvtools.bat b/scripts/igvtools.bat
index fee81c77be..5e90d8c87f 100755
--- a/scripts/igvtools.bat
+++ b/scripts/igvtools.bat
@@ -3,10 +3,10 @@ setlocal
for %%x in (%0) do set BatchPath=%%~dpsx
for %%x in (%BatchPath%) do set BatchPath=%%~dpsx
-if exist %BatchPath%\jdk-17 (
+if exist %BatchPath%\jdk-21 (
echo "Using bundled JDK."
- set JAVA_HOME=%BatchPath%\jdk-17
- set JAVA_CMD=%BatchPath%\jdk-17\bin\java
+ set JAVA_HOME=%BatchPath%\jdk-21
+ set JAVA_CMD=%BatchPath%\jdk-21\bin\java
) else (
echo "Using system JDK."
set JAVA_CMD=java
diff --git a/scripts/igvtools_gui b/scripts/igvtools_gui
index e12df3cc3d..843e033fca 100755
--- a/scripts/igvtools_gui
+++ b/scripts/igvtools_gui
@@ -2,9 +2,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
diff --git a/scripts/igvtools_gui.bat b/scripts/igvtools_gui.bat
index a66493a9ea..1a7dcbc27c 100755
--- a/scripts/igvtools_gui.bat
+++ b/scripts/igvtools_gui.bat
@@ -3,10 +3,10 @@ setlocal
for %%x in (%0) do set BatchPath=%%~dpsx
for %%x in (%BatchPath%) do set BatchPath=%%~dpsx
-if exist %BatchPath%\jdk-17 (
+if exist %BatchPath%\jdk-21 (
echo "Using bundled JDK."
- set JAVA_HOME=%BatchPath%\jdk-17
- set JAVA_CMD=%BatchPath%\jdk-17\bin\javaw
+ set JAVA_HOME=%BatchPath%\jdk-21
+ set JAVA_CMD=%BatchPath%\jdk-21\bin\javaw
) else (
echo "Using system JDK."
set JAVA_CMD=java
diff --git a/scripts/igvtools_gui.command b/scripts/igvtools_gui.command
index 05913030c3..0331d3668e 100755
--- a/scripts/igvtools_gui.command
+++ b/scripts/igvtools_gui.command
@@ -3,9 +3,9 @@ cd `dirname $0`
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
diff --git a/scripts/igvtools_gui_hidpi b/scripts/igvtools_gui_hidpi
index 37e5e62364..e1c2399759 100755
--- a/scripts/igvtools_gui_hidpi
+++ b/scripts/igvtools_gui_hidpi
@@ -2,9 +2,9 @@
prefix=`dirname $(readlink -f $0 || echo $0)`
# Check whether or not to use the bundled JDK
-if [ -d "${prefix}/jdk-17" ]; then
+if [ -d "${prefix}/jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/jdk-17"
+ JAVA_HOME="${prefix}/jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
diff --git a/scripts/readme.txt b/scripts/readme.txt
index 6d6ded2537..30dfbab3a0 100644
--- a/scripts/readme.txt
+++ b/scripts/readme.txt
@@ -75,14 +75,14 @@ command-line. To use the default Java, independently installed (java 11 require
java --module-path=lib -Xmx4g @igv.args --module=org.igv/org.broad.igv.ui.Main
-To use the java included with our packaged bundles substitute "./jdk-17/bin/java" for "java", as follows.
+To use the java included with our packaged bundles substitute "./jdk-21/bin/java" for "java", as follows.
- ./jdk-17/bin/java --module-path=lib -Xmx4g @igv.args --module=org.igv/org.broad.igv.ui.Main
+ ./jdk-21/bin/java --module-path=lib -Xmx4g @igv.args --module=org.igv/org.broad.igv.ui.Main
The above commands assume that you are launching IGV from the directory where it was unpacked.
Note that this lists the memory specification directly, and that the java_arguments file will be skipped.
-If you wish to use the java_arguments file (assuming one exists), modify the above to (substituting ./jdk-17/bin/java for java as required):
+If you wish to use the java_arguments file (assuming one exists), modify the above to (substituting ./jdk-21/bin/java for java as required):
java --module-path=lib @igv.args @"$HOME/.igv/java_arguments" --module=org.igv/org.broad.igv.ui.Main
From e16fd785a9231fa04b0a32c839612136870ccefa Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Sat, 14 Sep 2024 19:32:27 -0700
Subject: [PATCH 048/130] Update mac startup script for jdk 21
---
scripts/mac.app/Contents/MacOS/IGV.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/mac.app/Contents/MacOS/IGV.sh b/scripts/mac.app/Contents/MacOS/IGV.sh
index 59b8f56b53..27e23b09cd 100755
--- a/scripts/mac.app/Contents/MacOS/IGV.sh
+++ b/scripts/mac.app/Contents/MacOS/IGV.sh
@@ -18,9 +18,9 @@ prefix=`dirname $(readlink $0 || echo $0)`
# Check whether or not to use the bundled JDK
echo ${prefix}
-if [ -d "${prefix}/../jdk-17" ]; then
+if [ -d "${prefix}/../jdk-21" ]; then
echo echo "Using bundled JDK."
- JAVA_HOME="${prefix}/../jdk-17"
+ JAVA_HOME="${prefix}/../jdk-21"
PATH=$JAVA_HOME/bin:$PATH
else
echo "Using system JDK."
From 068e20a7a9df69bf31094364dfb61706fbe49079 Mon Sep 17 00:00:00 2001
From: Jim Robinson <933148+jrobinso@users.noreply.github.com>
Date: Sun, 15 Sep 2024 22:41:45 -0700
Subject: [PATCH 049/130] Replace compiled shell script MacOS launcher
---
scripts/mac.app/Contents/MacOS/IGV | Bin 50704 -> 102736 bytes
scripts/mac.app/Contents/MacOS/IGV.sh | 41 --------------------------
2 files changed, 41 deletions(-)
delete mode 100755 scripts/mac.app/Contents/MacOS/IGV.sh
diff --git a/scripts/mac.app/Contents/MacOS/IGV b/scripts/mac.app/Contents/MacOS/IGV
index 36ea038177338f1b8073a50d326b2260bfe3ba1a..daf1d8ecdf87e878399d5eb539cd1473a6fca348 100755
GIT binary patch
literal 102736
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
literal 50704
zcmeI5cT`hJxWI3aAW{q{B8nmwY}il)RFERk;L=vaRap$ZNN*}W3kp#}jH0W6owY0K
zA|hggV8bqAV=W8zph!_x5pj9nH#aC|eeb{b-g)QD-81(qGxNrtqPhii@(+R8E58upIs
zngvBDbhMvtFP!A&>cOtA9h+C%Ix0)tZ&+}xaL);a!BOp&^}mc~3~k9}$M#oP4D#1+
zGeBZqR%E|nUhOK9l=1?bTz0Hz%L^r5LSeYCFfK8|FDhIZ9UrU6i>)K~BsN}dn+xo=
zzUYEyi|L7q;t~o2eB*uFtTt}n?A#v&hygNI&{=|25Vpo%4WQsU#8y#%CbQCtmX&%fvh;suAe68?ojY*8v`Y_Z_gF$+g}FIpN!w$33_KJ
z#!$4Nj7*4&9T^_#H!>hGJOFIG4545io4#mIJytOOz{)oXcb3ODrHuxkF%%q|VK6IA
zqO)u5t1=WkI#{K+2E+U@PQ7)Thm|<46%?$)IY1_Gym7we0{M6(#>EFljBpqMd4>9s
zM$AAE7~c-~VBaAM8+p--5}*Vq0ZM=ppaduZN`Mle1SkPYfD)htC;>`<5}*Vq0ZM=p
zpaduZN`Mle1SkPYfD)htC;>`<5}*Vq0ZM=ppaduZN`Mmh|3bi1AbxR?+if=Fdy&gy
zMJE(#+zudk1==mM7)E?WARWsAJ5^Objr$rrs+?5rQ;^mSPjsubwblDv5U-CT!(cpt
zcyW_Bp-~{=HwnaidGg{$hPN8OXIqU_cm>@37_vkl?RFRxyEJnRyVQjDyaGNH8wt2L
zrFN+{%Rv!HT;$L`5mm8g)y9vD8=d{nI`9hgIF68-5d8L>TaKyPo}lpxy19Z7-*T4l
ztL)Rv)xlv)9QLW^>UL>3M7LpI9ckQtpyNDxg2Z|F!8{;oxqypbO~%wEE{)5o(Ga^d
zR-3ca9Kq|8g7aYh`}rP%7HQn#nd}h9K|;d0APCE2pronlr{a`daM~Nd!MO?3Ud6T)
zk(ST|dMzY6qQ~aibK6WLKy+S#mOk*{zqjXHa#X|=UqP=x;wgt34STc8j;R`G36`D3
z?_dK?oLzEBD^AUcOpVvaj$OZHHSP#Ndd!Cq;dX}~g9s!@1Qzs+>>tELgxm|h$(`K9
z@T5G5St_~)Rd`iz#UZ4kGO*1)2w<(nH&3RMVMT@Dlj}l1fkYGnZ3SXc1-K++F!3?$
zB007ID#XX+M2{wV7185~{v32zC>eAeg%KqDbWj;q%?4G6sAMRCxU>jImiv8aZDlhA
zi;<9A1rqHE@QreTq!XZN5{$bg7Ue^1o(QKSA-Z7Md4%D8PTm)OQoz#;`tkY;#0m9g
zGC}gB44tRAK^wBazh}#FXyyi
zoy~!t7^cV=Sjp>2W6}}UzX<0efAj-iA#{XYB0W`jTNX7{yQjBU!rjRV>2>i!v6BCAr2&ytomzyc{+a6x=Yl_hkSae`Eo>zz^ms?+QWMRShDO<=#S$5-Xr&
z3!2&G)JyW`@GF>NJeI`#)ACzjNESEBeIX$+|B-ywC$cWnoS@sXk~J6vb`ze;^3`mW
zC0k{rsImts_irY>da+d-aGOFe978UEDqaycV=8-grSP$zl-nQx!DU;P%Ev(#W|v`O
zi21qlRbapgkt-N?mM6uZNkQ|oq&Yh#Jf!8S#CwoqyNjMGgM$
zMPAI-EFd+96*YMD$ak|fb4bl=MGZ+_!qzyFnmR=drX-JHYli;2Cb$V%aCJycCrAo&
zBYkX0ADb6HWAbC0K%6B0FgTF#Tu)I<_U;sDz-5Pn$-aQ}Az(4_o>L^z6_coep^_Ir
zf=>iR&&}=HK+hcLDd9IJ%QOW3P3)0y7s-kFmtX^3f(?W}JQS4jn?Nwti=a6PmmkEfa!p7x#WKhT!7SU)renKW$f-L!n}*5ImD>#i
z03HI{hy{0_)WqP41T_NK402Vr<_ue-=tBs+{zzc&{C7>&2T~&@H4uzMBYg@;ADb$y
zk&c}U;w14u$LY6Q2G@2$A@Mm7q*wr;<;QReVty4ctWsuZg?URBR}~q=bOoG~YHwu<&Jz&?2==u;g5k&?F;9X7DcJ_)(;E+59fvVLZBpfX=oKiLDOey~kinilM
z;&Msic}ILN`65T0a7WyO=}Ts<->S==9XPO_Me|q{a{ziJ<0Q>T{8(>%SzZM2VP$AeI@z4kM}uVpCoLq
zIRD*C`7LO|n?AnzNI*yu>g9joaU#*KBRkHsULbaWw-5LL<3oBn@XrD{zQxOB(9u!C
z*u(ljYQfl8s_l=02d9A8r9!?9THt$43NDx&U*9BF^3Nb(LzGpsA2D1r?147;5lR`X
zN4+39Q60UPcqzK98-|8=Aozf4>(@*U53m*eWbkmv;jt@6Kkk2k3)}LN6WNbW(8~TK
zRN-fnqqq!cxWju>tBHyO!?c>HlDitYtCPD1xoeSoXL8pe_b%kFNACLMZb0rm$-Ni3
z8PM*Iey%P@
z%@Vass5zrngjxV<`KZO9b^x`dsAZ!jMJ)rhji{|cZ69jOQ7b@g0cz(_i$tv)wE)zr
zP@9cfEo$zl;g+eMjG89oTWyV+F>0ex8;ROr)a+0*Ld^{|JPPy&PPy&PPy&>K?D@N=eqN~gG+j?Nf!v)$K`frqV4$pISJg9OY>&otPqH@vA{E<#K-Y&epca2@^
z@UoM=i7ta=IrAH-ZWlw;Qg5B
zPCw^cbm`5TJ7A_}^PHh!E^9)cpAPFJyD?R~?4!q;=VSHP4RabP8*|0rwf${!1us
zw(r-@Ut#Ewu%OG($-N@HD}0|@b`4u(Av;p~d30Kzzi;+D9j1}Ja?}msqQ;9;#*~^z
z>{dVMHB(2lap|iyX@PS|a&J>{8S`t#&%I2-RX>#tov4?5v1F9t&iPplm8AuT?>#P739J{)8>Nx&
z5PJH>y1q^;s=KJHS#Ro7-uLa{6=i)VSP#!%IX}KR-7|W1>z7AoYrC~*{^PbxW|Vc=
z>u`Uamy1IFQCt4dr2D!-p8BC`Pv3j{%GE?8j(2}GyyRiI)-3ZA{c~%AR&Lxfp>Lnw
z!|H>dwyxOzliA>InSL8oH|Otaoze7UqjY4=)Z4jCSm4==$UTGKY+Y1x+SVnzv$#Cb
zYl5Z8fcl~4J)(Ad+>!Sz;SM>m=uXm%8RZTB`h~|+9Q(a$)W5a==e*sY?cP7J8aqx>
zGIms%T&3n_mfhXCI)i2u>z-&e4KC5|P=346V!di*Vq%3|&Xh(^ulmK-{a2}}&KSR?
zsbaUEWajoJ(UE)aM#~ng&R35KaTr$He8Xk){fYhiU5uM8se0*GxqH<@ef~l9tg&vF
z4|RJR*Z0h%DNdjD^jf`QQ{9`5nLD#A4rV_HQrmK+DN1;=qtv)zT~cK165WctiL>L^
zEKeBmPoGVjs%u3ut(?5|Ms>S==9oXHGymb}M=6uI8&0k84bFUJ
z5qntYZ}G1mzhwXR+l%bkmA`8)*NJiO{CnP$U!wJP+HYbC)GSoW4ND##ZMDqgOtUNQ
z)S$yJU4AkA*fjfdW44)&?=fx1tWkL_Lzh(TnYF#w&V|c980U076&ST4;qOT&Yj5vS
z+nc>a{&>XjVp%66x1RUZ1^skfj5LO8x6B!$`J&_GJz0+u-SU~mG!_b6Pmk*
zZoXl+d4rXy>(!h6-??7fHc#7SY4fKHCV!8~f^oUyC(e7hJLjERY|UBMtL0rJxARX=
zEmT=icJ;yW`_YHG$4z^dXyCN%ER*ZvFwpX{t%Jppk?w!(45)K*_HbL~V?5T9CtmKE(#m`_S*Pfe{9*2TQFVHrP*z|y|4GcN<%TP
z&`tl^=~Zq6w_IJawbPg(*Hh-miT#m#rud$i8o5?Hiqmy1!3@roJV!LKVXT+CL@?YQjyy-Ll677b&?-WrP*A8oLj
z=2#e!RycfP!;|I!v&Y)@(>YpekGf7Rxxc!0>9e|{qiu?{ZC^xYbe@^b##lFra4#|?V89qR6Sf9Z($him_=dF%Tn#YmdERClSkv)Ao{g658a
z?|5dpTGw9mj=vn?^YNp+iX5$_Dv~
zH800?TDNzdS47O4xjl3CYTx%e^MWa>TkPEV=*GLVK0Q5eQEig#-#g=(=aD7aYvxqW
z3J%@ZCu6d`WY5)&pT5i=e`w=hd&R**>f~i5aY|
z(e!z?-V3`m(atCK|MP6#q&HvEoj$Z?HfE;Il3jdOb8Cpp)~JG<_Y0%%^zj;V!llO{
zZtdlDeN;|m+$;+}Qr7dZ-o!=y)X#0#-CUFS=|xW06*b8t?Qi$ygtrRCg;}Okb?s#L
zyCm(L>?vqHHSgY`HHoLHR1-TNt2|d2e)ndn(ctvgs<8vdI6f_MYdKvoS!L<(wHX5v
zGxFd1-pO+M?QPF{ynauon|OS<`>g!T^%;hrEq3V4%bk8wHPx%nBk|S;=Gilx{U_dj
z;9@zu<6vz=3R|h5XAEdW$E29+rOG?Pyakj*fYLPI`~4*Lqsa
zonf{i>6#$f^UXZ&E1A4EH)+#HFU|c2o8P|IF+Fbe$!SKZb#`F)A>CrT9d*x?&ov#O
zlK67e>K+~+U*12xt^Z1`hlQ^#?se|8=INovs#%q{_SEe-HN|%O>47O{D!SxrPd#_j`q#Sr?&8pl
ztI3rg-BJo3|FI;f#d)CP?-Qz{r+K~EdT?2Z%`@}lMOJRT$35y||NAc*4s=WvvR*FC
zI^we5HgrYs1*=TMnK5rQ5;rzirX=;^j?#czF9hTXnWrfyK&>0@HFb75wuDSGZn
z@851Z=i!|eHg)Ag(FcP!$!8r8#%iDVCBPu%+^#>KXB%$pv5i}6o4=!I=;K3fyuH54
zuZz^C1SkPYfD)htC;>`<5}*Vq0ZM=ppaduZN`Mle1SkPYfD)htC;>`<5}*Vq0ZM=p
zpaduZN`Mle1SkPYfD)htC;>`<5}*Vq0ZM=ppaduZN`Mle1SkPY;QtK)-TsV^K4hzF
zClm_f;(h(Yg#IC6!r%no*Z}6|SSFqI2L#5(MxzlJIWIIeDiYLy#P9&Drv3yp+&
zCLJdo$3}wYQRsHi78a(8&0pHm9*tRzbd@;TT{r
z_H^S%*!XC=gBctc5A#85CTm59
z2B75wR>aqkA!xw_B1p(+)`HZrt4?(y_*+O7;#VJ4eYrs$`#1vd<~mSC#DBO7=q~`hvNn{?PeLalYjv
Date: Fri, 20 Sep 2024 13:56:18 -0400
Subject: [PATCH 050/130] Update CRAM reference test to include a genbank (gbk)
referece with chromosome aliasing
---
.../igv/sam/cram/IGVReferenceSourceTest.java | 54 +++++++++----------
1 file changed, 25 insertions(+), 29 deletions(-)
diff --git a/src/test/java/org/broad/igv/sam/cram/IGVReferenceSourceTest.java b/src/test/java/org/broad/igv/sam/cram/IGVReferenceSourceTest.java
index 6021445bf9..6e0eacd22b 100644
--- a/src/test/java/org/broad/igv/sam/cram/IGVReferenceSourceTest.java
+++ b/src/test/java/org/broad/igv/sam/cram/IGVReferenceSourceTest.java
@@ -30,9 +30,7 @@
import org.junit.Before;
import org.junit.Test;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
@@ -43,53 +41,51 @@
public class IGVReferenceSourceTest {
- public static final String FASTA_URL = "https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa";
- public static final String COMPRESSED_FASTA_URL = "https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa.gz";
+ public static final String FASTA_URL = "https://igv.org/genomes/data/hg38/hg38.fa";
public static final String EXPECTED_REFERENCE_BASES = "AAACCCAGGGCAAAGAATCTGGCCCTA"; //bases at 22:27198875-271988902
+ public static final String GBK_URL = "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/NC_012920.1.gbk";
+ public static final String GBK_EXPECTED_BASES = "tcatttctctaacagcagtaatattaataattttcatgat";
@Before
public void setUp() throws Exception {
}
- private void assertReferenceReqionRequestsWork(final String fastaUrl) throws IOException {
- GenomeManager.getInstance().loadGenome(fastaUrl);
-
+ @Test
+ public void testGetReferenceBasesByRegion() throws Exception {
+ GenomeManager.getInstance().loadGenome(IGVReferenceSourceTest.FASTA_URL);
IGVReferenceSource refSource = new IGVReferenceSource();
String expected = EXPECTED_REFERENCE_BASES;
- SAMSequenceRecord rec = new SAMSequenceRecord("22", 50818468);
+ SAMSequenceRecord rec = new SAMSequenceRecord("chr22", 50818468);
byte[] bases = refSource.getReferenceBasesByRegion(rec, 27198874, expected.length());
assertEquals(expected.length(), bases.length);
assertEquals(expected, new String(bases, StandardCharsets.US_ASCII));
- }
-
- @Test
- public void testGetReferenceBasesByRegion() throws Exception {
- assertReferenceReqionRequestsWork(IGVReferenceSourceTest.FASTA_URL);
- }
- @Test
- public void testGetReferenceBasesByRegionCompressed() throws Exception {
- assertReferenceReqionRequestsWork(COMPRESSED_FASTA_URL);
+ // Test with a chr alias
+ rec = new SAMSequenceRecord("22", 50818468);
+ bases = refSource.getReferenceBasesByRegion(rec, 27198874, expected.length());
+ assertEquals(expected.length(), bases.length);
+ assertEquals(expected, new String(bases, StandardCharsets.US_ASCII));
}
@Test
- public void testGetReferenceBasesCompressed() throws Exception {
-
- GenomeManager.getInstance().loadGenome(COMPRESSED_FASTA_URL);
-
+ public void testGenbankReference() throws Exception {
+ GenomeManager.getInstance().loadGenome(GBK_URL);
+ String expected = GBK_EXPECTED_BASES.toUpperCase(); // Seq at NC_012920:7,279-7,318
IGVReferenceSource refSource = new IGVReferenceSource();
- SAMSequenceRecord rec = new SAMSequenceRecord("22", 50818468);
- byte[] bases = refSource.getReferenceBases(rec, false);
-
- assertEquals(50818468, bases.length);
+ SAMSequenceRecord rec = new SAMSequenceRecord("NC_012920", 16569);
+ byte[] bases = refSource.getReferenceBasesByRegion(rec, 7278, expected.length());
+ assertEquals(expected.length(), bases.length);
+ assertEquals(expected, new String(bases, StandardCharsets.US_ASCII));
- assertEquals('N', bases[0]);
- String expected = EXPECTED_REFERENCE_BASES;
- String actual = new String(Arrays.copyOfRange(bases, 27198874, 27198874 + expected.length()), StandardCharsets.US_ASCII);
- assertEquals(expected, actual);
+ // Test with a chr alias
+ rec = new SAMSequenceRecord("MT", 16569);
+ bases = refSource.getReferenceBasesByRegion(rec, 7278, expected.length());
+ assertEquals(expected.length(), bases.length);
+ assertEquals(expected, new String(bases, StandardCharsets.US_ASCII));
}
+
// @Test
// public void testCompressedTiming() throws Exception {
//
From 9170e309b5707c62e3afbe5bd0874aa97e947cb9 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Tue, 24 Sep 2024 21:30:45 -0700
Subject: [PATCH 051/130] Clarify sequence name mismatch error message
---
src/main/java/org/broad/igv/track/TrackLoader.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/broad/igv/track/TrackLoader.java b/src/main/java/org/broad/igv/track/TrackLoader.java
index c967156e36..66e02b15ec 100644
--- a/src/main/java/org/broad/igv/track/TrackLoader.java
+++ b/src/main/java/org/broad/igv/track/TrackLoader.java
@@ -956,7 +956,7 @@ private void showMismatchSequenceNameMessage(String filename, Genome genome, Lis
StringBuffer message = new StringBuffer();
message.append("File: " + filename +
"
does not contain any sequence names which match the current genome.");
- message.append("
File: ");
+ message.append("
Sequence names in 'filename': ");
int n = 0;
for (String sn : seqNames) {
message.append(sn + ", ");
@@ -967,7 +967,7 @@ private void showMismatchSequenceNameMessage(String filename, Genome genome, Lis
}
}
if (genome != null && genome.getChromosomeNames() != null && genome.getChromosomeNames().size() > 0) {
- message.append("
Genome: ");
+ message.append("
Sequence names in genome reference sequence: ");
n = 0;
for (String cn : genome.getChromosomeNames()) {
message.append(cn + ", ");
From 907726c2985cdf9e44217b4da1f7cb2af57cf27d Mon Sep 17 00:00:00 2001
From: Louis Bergelson
Date: Wed, 25 Sep 2024 14:24:44 -0400
Subject: [PATCH 052/130] Fix for 2bit reference crash when reading the end of
the reference (#1586)
* Clip requests for sequence to not go over the length of the chromosome.
* fixes https://github.com/igvteam/igv/issues/1583
---
src/main/java/org/broad/igv/ucsc/twobit/TwoBitSequence.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/main/java/org/broad/igv/ucsc/twobit/TwoBitSequence.java b/src/main/java/org/broad/igv/ucsc/twobit/TwoBitSequence.java
index d491d997f1..27368ad839 100644
--- a/src/main/java/org/broad/igv/ucsc/twobit/TwoBitSequence.java
+++ b/src/main/java/org/broad/igv/ucsc/twobit/TwoBitSequence.java
@@ -133,6 +133,9 @@ public byte[] readSequence(String seqName, int regionStart, int regionEnd) {
throw new RuntimeException("regionStart cannot be less than 0");
}
+ //don't run off the end of the genome
+ regionEnd = Math.min(record.getDnaSize(), regionEnd);
+
Queue nBlocks = _getOverlappingBlocks(regionStart, regionEnd, record.nBlocks);
Queue maskBlocks = _getOverlappingBlocks(regionStart, regionEnd, record.maskBlocks);
From 6203b4537a1ef9dfac33581d86bb4375a87b7115 Mon Sep 17 00:00:00 2001
From: Chris Saunders
Date: Thu, 26 Sep 2024 07:38:42 -0700
Subject: [PATCH 053/130] Correct rendered range of symbolic VCF alleles
(#1580)
* Adjust the start position of non-ref symbolic alleles to include a padding base as described in the vcf spec.
Co-authored-by: Louis Bergelson
---
src/main/java/org/broad/igv/variant/vcf/VCFVariant.java | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/main/java/org/broad/igv/variant/vcf/VCFVariant.java b/src/main/java/org/broad/igv/variant/vcf/VCFVariant.java
index 182c033067..acc15bc66b 100644
--- a/src/main/java/org/broad/igv/variant/vcf/VCFVariant.java
+++ b/src/main/java/org/broad/igv/variant/vcf/VCFVariant.java
@@ -385,6 +385,15 @@ private void calcStart() {
if (variantContext.getType() == VariantContext.Type.INDEL || variantContext.getType() == VariantContext.Type.MIXED) {
prefixLength = findCommonPrefixLength();
}
+
+ /**
+ * The VCF spec defines POS as the base preceding the polymorphism for non-ref symbolic alleles.
+ *
+ */
+ if (variantContext.getType(true) == VariantContext.Type.SYMBOLIC) {
+ prefixLength = 1;
+ }
+
this.start = (variantContext.getStart() - 1) + prefixLength;
}
From 40869ade416c77d37d665f2daa843e5b9692efe1 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Thu, 26 Sep 2024 14:43:31 -0700
Subject: [PATCH 054/130] Restore hosted genome selection behavior -- json is
downloaded to "genomes" folder.
---
.../java/org/broad/igv/ui/IGVMenuBar.java | 2 +-
.../igv/ui/commandbar/GenomeComboBox.java | 46 ++++++++++---------
.../ui/commandbar/GenomeSelectionDialog.java | 44 ++++++++++--------
3 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/src/main/java/org/broad/igv/ui/IGVMenuBar.java b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
index 8f72951c98..67dae72c5b 100644
--- a/src/main/java/org/broad/igv/ui/IGVMenuBar.java
+++ b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
@@ -431,7 +431,7 @@ private JMenu createGenomesMenu() {
JMenu menu = new JMenu("Genomes");
- loadGenomeFromServerMenuItem = new JMenuItem("Select Hosted Genome...");
+ loadGenomeFromServerMenuItem = new JMenuItem("Download Hosted Genome...");
loadGenomeFromServerMenuItem.addActionListener(e -> GenomeComboBox.loadGenomeFromServer());
loadGenomeFromServerMenuItem.setToolTipText(LOAD_GENOME_SERVER_TOOLTIP);
menu.add(loadGenomeFromServerMenuItem);
diff --git a/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
index 9a2dc7839e..f9cc1fbf80 100644
--- a/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
+++ b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
@@ -20,6 +20,7 @@
import java.io.File;
import java.io.IOException;
import java.util.*;
+import java.util.List;
/**
* Created by jrobinso on 7/6/17.
@@ -102,16 +103,10 @@ private void loadGenomeListItem(final GenomeListItem genomeListItem) {
loadGenomeFromServer();
} else {
- boolean success = false;
- Exception error = null;
try {
- success = GenomeManager.getInstance().loadGenomeById(genomeListItem.getId());
+ GenomeManager.getInstance().loadGenomeById(genomeListItem.getId());
} catch (Exception e) {
log.error(e);
- error = e;
- }
-
- if (!success) {
int choice = JOptionPane.showConfirmDialog(
IGV.getInstance().getMainFrame(), "The genome [" + genomeListItem.getId() +
"] could not be read. Would you like to remove the selected entry?",
@@ -120,7 +115,7 @@ private void loadGenomeListItem(final GenomeListItem genomeListItem) {
if (choice == JOptionPane.OK_OPTION) {
GenomeListManager.getInstance().removeGenomeListItem(genomeListItem);
refreshGenomeListComboBox();
- log.error("Error initializing genome", error);
+ log.error("Error initializing genome", e);
}
}
}
@@ -220,27 +215,36 @@ public static void loadGenomeFromServer() {
if (dialog.isCanceled()) {
IGVEventBus.getInstance().post(new GenomeResetEvent());
} else {
- GenomeListItem selectedValue = dialog.getSelectedValue();
- if (selectedValue != null) {
-
+ List selectedValueList = dialog.getSelectedValues();
+ GenomeListItem firstItem = null;
+ for (GenomeListItem selectedValue : selectedValueList) {
+ if (selectedValue != null) {
+ boolean downloadSequence = false;
+ boolean success = GenomeManager.getInstance().downloadGenome(selectedValue, downloadSequence);
+ if (success) {
+ GenomeListManager.getInstance().addServerGenomeItem(selectedValue);
+ firstItem = selectedValue;
+ }
+ }
+ }
+ if (firstItem != null && selectedValueList.size() == 1) {
try {
- GenomeManager.getInstance().loadGenome(selectedValue.getPath());
-
- GenomeListManager.getInstance().addServerGenomeItem(selectedValue);
- GenomeListManager.getInstance().removeUserDefinedGenome(selectedValue.getId());
+ GenomeManager.getInstance().loadGenome(firstItem.getPath());
+ // If the user has previously defined this genome, remove it.
+ GenomeListManager.getInstance().removeUserDefinedGenome(firstItem.getId());
// If this is a .json genome, attempt to remove existing .genome files
- if (selectedValue.getPath().endsWith(".json")) {
- removeDotGenomeFile(selectedValue.getId());
+ if (firstItem.getPath().endsWith(".json")) {
+ removeDotGenomeFile(firstItem.getId());
}
+
} catch (IOException e) {
- GenomeListManager.getInstance().removeGenomeListItem(selectedValue);
- MessageUtils.showErrorMessage("Error loading genome " + selectedValue.getDisplayableName(), e);
- log.error("Error loading genome " + selectedValue.getDisplayableName(), e);
+ GenomeListManager.getInstance().removeGenomeListItem(firstItem);
+ MessageUtils.showErrorMessage("Error loading genome " + firstItem.getDisplayableName(), e);
+ log.error("Error loading genome " + firstItem.getDisplayableName(), e);
}
-
}
}
};
diff --git a/src/main/java/org/broad/igv/ui/commandbar/GenomeSelectionDialog.java b/src/main/java/org/broad/igv/ui/commandbar/GenomeSelectionDialog.java
index 4b4d9cbdf0..096566b4d5 100644
--- a/src/main/java/org/broad/igv/ui/commandbar/GenomeSelectionDialog.java
+++ b/src/main/java/org/broad/igv/ui/commandbar/GenomeSelectionDialog.java
@@ -51,6 +51,7 @@ public class GenomeSelectionDialog extends org.broad.igv.ui.IGVDialog {
private JPanel dialogPane;
private JPanel contentPanel;
+ private JTextArea textArea1;
private JPanel filterPanel;
private JLabel label1;
private JTextField genomeFilter;
@@ -61,7 +62,7 @@ public class GenomeSelectionDialog extends org.broad.igv.ui.IGVDialog {
private JButton cancelButton;
private boolean isCanceled = true;
- private GenomeListItem selectedValue = null;
+ private List selectedValues = null;
private List allListItems;
private DefaultListModel genomeListModel;
@@ -105,7 +106,11 @@ private void rebuildGenomeList(String filterText) {
* @param e
*/
private void genomeListMouseClicked(MouseEvent e) {
- if (e.getClickCount() == 2) {
+ switch (e.getClickCount()) {
+ case 1:
+ List selValues = genomeList.getSelectedValuesList();
+ break;
+ case 2:
okButtonActionPerformed(null);
}
}
@@ -114,8 +119,8 @@ private void genomeEntryKeyReleased(KeyEvent e) {
rebuildGenomeList(genomeFilter.getText());
}
- public GenomeListItem getSelectedValue() {
- return selectedValue;
+ public List getSelectedValues() {
+ return selectedValues;
}
public boolean isCanceled() {
@@ -124,14 +129,14 @@ public boolean isCanceled() {
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
isCanceled = true;
- selectedValue = null;
+ selectedValues = null;
setVisible(false);
dispose();
}
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
isCanceled = false;
- selectedValue = genomeList.getSelectedValue();
+ selectedValues = genomeList.getSelectedValuesList();
setVisible(false);
dispose();
}
@@ -140,6 +145,7 @@ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
private void initComponents() {
dialogPane = new JPanel();
contentPanel = new JPanel();
+ textArea1 = new JTextArea();
filterPanel = new JPanel();
label1 = new JLabel();
genomeFilter = new JTextField();
@@ -165,6 +171,16 @@ private void initComponents() {
{
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
+ //---- textArea1 ----
+ textArea1.setText("Selected genomes will be downloaded and added to the genome dropdown list.");
+ textArea1.setLineWrap(true);
+ textArea1.setWrapStyleWord(true);
+ textArea1.setBackground(UIManager.getColor("Button.background"));
+ textArea1.setRows(2);
+ textArea1.setMaximumSize(new Dimension(2147483647, 60));
+ textArea1.setRequestFocusEnabled(false);
+ textArea1.setEditable(false);
+ contentPanel.add(textArea1);
//======== filterPanel ========
{
@@ -204,7 +220,7 @@ public void keyReleased(KeyEvent e) {
{
//---- genomeList ----
- genomeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ //genomeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
genomeList.addMouseListener(new IGVMouseInputAdapter() {
@Override
public void igvMouseClicked(MouseEvent e) {
@@ -227,24 +243,14 @@ public void igvMouseClicked(MouseEvent e) {
//---- okButton ----
okButton.setText("OK");
- okButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- okButtonActionPerformed(e);
- }
- });
+ okButton.addActionListener(e -> okButtonActionPerformed(e));
buttonBar.add(okButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- cancelButton ----
cancelButton.setText("Cancel");
- cancelButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- cancelButtonActionPerformed(e);
- }
- });
+ cancelButton.addActionListener(e -> cancelButtonActionPerformed(e));
buttonBar.add(cancelButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
From dee67089fc76f2ac3e6a1e0fe178ac27f166ea6f Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Fri, 27 Sep 2024 11:53:03 -0700
Subject: [PATCH 055/130] BB parsing bug - wrong offset for chromTree
---
src/main/java/org/broad/igv/ucsc/bb/BBFile.java | 10 ++++++----
src/main/java/org/broad/igv/ucsc/bb/ChromTree.java | 6 +++---
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/broad/igv/ucsc/bb/BBFile.java b/src/main/java/org/broad/igv/ucsc/bb/BBFile.java
index 0267ec0115..f13756c8c2 100644
--- a/src/main/java/org/broad/igv/ucsc/bb/BBFile.java
+++ b/src/main/java/org/broad/igv/ucsc/bb/BBFile.java
@@ -227,11 +227,13 @@ BBHeader readHeader() throws IOException {
this.totalSummary = BBTotalSummary.parseSummary(buffer);
}
- // Chromosome tree -- this normally preceeds fullDataOffset so will be within the buffer. However, this
- // isn't guaranteed, we have to check
- int chromtreeBufferSize = (int) Math.min(1000000, Math.max(10000, header.fullDataOffset - header.chromTreeOffset));
+ // Chromosome tree -- we know the start offset but not the size. But we can try to estimate it.
+ int chromtreeBufferSize = header.fullDataOffset > header.chromTreeOffset ?
+ (int) Math.min(10000, header.fullDataOffset - header.chromTreeOffset) :
+ 10000;
+
buffer = UnsignedByteBufferDynamic.loadBinaryBuffer(this.path, order, header.chromTreeOffset, chromtreeBufferSize);
- this.chromTree = ChromTree.parseTree(buffer, startOffset, this.genome);
+ this.chromTree = ChromTree.parseTree(buffer, header.chromTreeOffset, this.genome);
this.chrNames = this.chromTree.names();
diff --git a/src/main/java/org/broad/igv/ucsc/bb/ChromTree.java b/src/main/java/org/broad/igv/ucsc/bb/ChromTree.java
index 028f7905fa..009ba08909 100644
--- a/src/main/java/org/broad/igv/ucsc/bb/ChromTree.java
+++ b/src/main/java/org/broad/igv/ucsc/bb/ChromTree.java
@@ -25,7 +25,7 @@ public class ChromTree {
public long sumLengths = 0;
- public static ChromTree parseTree(UnsignedByteBuffer buffer, int startOffset, Genome genome) {
+ public static ChromTree parseTree(UnsignedByteBuffer buffer, long startOffset, Genome genome) {
return (new ChromTree().parse(buffer, startOffset, genome));
}
@@ -50,7 +50,7 @@ public String[] names() {
return idToName;
}
- public ChromTree parse(UnsignedByteBuffer buffer, int startOffset, Genome genome) {
+ public ChromTree parse(UnsignedByteBuffer buffer, long startOffset, Genome genome) {
{
Header header = new Header();
header.magic = buffer.getInt();
@@ -75,7 +75,7 @@ public ChromTree parse(UnsignedByteBuffer buffer, int startOffset, Genome genome
}
}
- void readTreeNode(long offset, final int startOffset, UnsignedByteBuffer buffer, Genome genome) {
+ void readTreeNode(long offset, final long startOffset, UnsignedByteBuffer buffer, Genome genome) {
if (offset >= 0) buffer.position((int) offset);
byte type = buffer.get();
byte reserved = buffer.get();
From 1347745dcec0afbfa24bbb7f13ac303074f789d3 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Fri, 27 Sep 2024 11:53:32 -0700
Subject: [PATCH 056/130] Don't check for "load from server" files in advance
-- it can take up to 500 ms delaying startup.
---
src/main/java/org/broad/igv/ui/IGVMenuBar.java | 18 ++++++++----------
.../igv/ui/action/LoadFromServerAction.java | 4 +---
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/broad/igv/ui/IGVMenuBar.java b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
index 67dae72c5b..93f1e808b6 100644
--- a/src/main/java/org/broad/igv/ui/IGVMenuBar.java
+++ b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
@@ -36,10 +36,13 @@
import org.broad.igv.event.IGVEventBus;
import org.broad.igv.event.IGVEventObserver;
import org.broad.igv.feature.genome.Genome;
+import org.broad.igv.feature.genome.GenomeListItem;
import org.broad.igv.feature.genome.GenomeManager;
import org.broad.igv.feature.genome.GenomeUtils;
import org.broad.igv.track.AttributeManager;
import org.broad.igv.track.Track;
+import org.broad.igv.ui.commandbar.GenomeListManager;
+import org.broad.igv.ui.commandbar.GenomeSelectionDialog;
import org.broad.igv.util.GoogleUtils;
import org.broad.igv.oauth.OAuthProvider;
import org.broad.igv.oauth.OAuthUtils;
@@ -51,7 +54,6 @@
import org.broad.igv.tools.motiffinder.MotifFinderPlugin;
import org.broad.igv.track.CombinedDataSourceDialog;
import org.broad.igv.ui.action.*;
-import org.broad.igv.ui.commandbar.GenomeComboBox;
import org.broad.igv.ui.commandbar.RemoveGenomesDialog;
import org.broad.igv.ui.legend.LegendDialog;
import org.broad.igv.ui.panel.FrameManager;
@@ -294,7 +296,7 @@ JMenu createFileMenu() {
menuAction = new LoadFromServerAction("Load From Server...", KeyEvent.VK_S, igv);
menuAction.setToolTipText(UIConstants.LOAD_SERVER_DATA_TOOLTIP);
loadTracksFromServerMenuItem = MenuAndToolbarUtils.createMenuItem(menuAction);
- loadTracksFromServerMenuItem.setVisible(genomeId != null && LoadFromServerAction.getNodeURLs(genomeId) != null);
+ // loadTracksFromServerMenuItem.setVisible(genomeId != null && LoadFromServerAction.getNodeURLs(genomeId) != null);
menuItems.add(loadTracksFromServerMenuItem);
// Track hubs -- moved to Genomes menu
@@ -432,7 +434,7 @@ private JMenu createGenomesMenu() {
JMenu menu = new JMenu("Genomes");
loadGenomeFromServerMenuItem = new JMenuItem("Download Hosted Genome...");
- loadGenomeFromServerMenuItem.addActionListener(e -> GenomeComboBox.loadGenomeFromServer());
+ loadGenomeFromServerMenuItem.addActionListener(e -> GenomeSelectionDialog.selectGenomesFromServer());
loadGenomeFromServerMenuItem.setToolTipText(LOAD_GENOME_SERVER_TOOLTIP);
menu.add(loadGenomeFromServerMenuItem);
@@ -450,7 +452,7 @@ private JMenu createGenomesMenu() {
// If a file selection was made
if (file != null) {
- GenomeManager.getInstance().loadGenome(file.getAbsolutePath());
+ Genome newGenome = GenomeManager.getInstance().loadGenome(file.getAbsolutePath());
}
} catch (Exception ex) {
MessageUtils.showErrorMessage(ex.getMessage(), ex);
@@ -473,11 +475,9 @@ private JMenu createGenomesMenu() {
MenuAction menuAction = new SelectGenomeAnnotationTracksAction("Select GenArk Tracks...", igv);
selectGenomeAnnotationsItem = MenuAndToolbarUtils.createMenuItem(menuAction);
- Genome genome = GenomeManager.getInstance().getCurrentGenome();
- selectGenomeAnnotationsItem.setEnabled(genome != null && genome.getHub() != null);
+ Genome newGenome = GenomeManager.getInstance().getCurrentGenome();
+ selectGenomeAnnotationsItem.setEnabled(newGenome != null && newGenome.getHub() != null);
menu.add(selectGenomeAnnotationsItem);
-
-
menu.add(new JSeparator());
// Add genome to combo box from server
@@ -1202,8 +1202,6 @@ public void receiveEvent(final IGVEvent event) {
UIUtilities.invokeOnEventThread(() -> {
final Genome genome = ((GenomeChangeEvent) event).genome();
encodeMenuItem.setVisible(EncodeFileBrowser.genomeSupported(genome.getId()));
- loadTracksFromServerMenuItem.setVisible(LoadFromServerAction.getNodeURLs(genome.getId()) != null);
- //selectGenomeAnnotationsItem .setEnabled(genome != null && genome.getHub() != null);
});
}
}
diff --git a/src/main/java/org/broad/igv/ui/action/LoadFromServerAction.java b/src/main/java/org/broad/igv/ui/action/LoadFromServerAction.java
index 2885866e7d..9403742b9a 100644
--- a/src/main/java/org/broad/igv/ui/action/LoadFromServerAction.java
+++ b/src/main/java/org/broad/igv/ui/action/LoadFromServerAction.java
@@ -113,9 +113,7 @@ public static LinkedHashSet getNodeURLs(String genomeId) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
nodeURLs = getResourceUrls(bufferedReader);
} catch (IOException e) {
- //This is pretty common, if there is no data registry file for the genome the file won't exist
- //log.error("Error loading genome registry file", e);
- log.warn("No data found for current genome.");
+ //This is common and not an error, a load-from-server "data registry" file is optional
} finally {
if (is != null) {
try {
From ab536a5685612de6f4ba81e0ddc4420c72cc991d Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Fri, 27 Sep 2024 12:06:30 -0700
Subject: [PATCH 057/130] bug...
---
src/main/java/org/broad/igv/ui/IGVMenuBar.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/broad/igv/ui/IGVMenuBar.java b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
index 93f1e808b6..62093a6df5 100644
--- a/src/main/java/org/broad/igv/ui/IGVMenuBar.java
+++ b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
@@ -41,6 +41,7 @@
import org.broad.igv.feature.genome.GenomeUtils;
import org.broad.igv.track.AttributeManager;
import org.broad.igv.track.Track;
+import org.broad.igv.ui.commandbar.GenomeComboBox;
import org.broad.igv.ui.commandbar.GenomeListManager;
import org.broad.igv.ui.commandbar.GenomeSelectionDialog;
import org.broad.igv.util.GoogleUtils;
@@ -434,7 +435,7 @@ private JMenu createGenomesMenu() {
JMenu menu = new JMenu("Genomes");
loadGenomeFromServerMenuItem = new JMenuItem("Download Hosted Genome...");
- loadGenomeFromServerMenuItem.addActionListener(e -> GenomeSelectionDialog.selectGenomesFromServer());
+ loadGenomeFromServerMenuItem.addActionListener(e -> GenomeComboBox.loadGenomeFromServer());
loadGenomeFromServerMenuItem.setToolTipText(LOAD_GENOME_SERVER_TOOLTIP);
menu.add(loadGenomeFromServerMenuItem);
From c7ef831eb4ee66e0e1beecb48fe5298e4caef8d0 Mon Sep 17 00:00:00 2001
From: Jim Robinson <933148+jrobinso@users.noreply.github.com>
Date: Fri, 27 Sep 2024 12:36:21 -0700
Subject: [PATCH 058/130] Genome improvements (#1589)
Refactoring genome load management to simplify code.
---
.../org/broad/igv/feature/genome/Genome.java | 2 +-
.../igv/feature/genome/GenomeManager.java | 61 ++++-----
.../feature/genome/load/JsonGenomeLoader.java | 16 +++
src/main/java/org/broad/igv/ui/IGV.java | 2 +-
.../java/org/broad/igv/ui/IGVMenuBar.java | 3 +-
.../igv/ui/action/LoadFromURLMenuAction.java | 4 +-
.../broad/igv/ui/action/UCSCGenArkAction.java | 2 +
.../igv/ui/commandbar/GenomeComboBox.java | 80 +-----------
.../igv/ui/commandbar/GenomeListManager.java | 50 ++++----
.../ui/commandbar/GenomeSelectionDialog.java | 119 ++++++++++++++++--
.../java/org/broad/igv/util/FileUtils.java | 2 +
11 files changed, 189 insertions(+), 152 deletions(-)
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 cf52b6ae01..00ee49f90f 100644
--- a/src/main/java/org/broad/igv/feature/genome/Genome.java
+++ b/src/main/java/org/broad/igv/feature/genome/Genome.java
@@ -125,7 +125,7 @@ public Genome(GenomeConfig config) throws IOException {
} else if (config.fastaURL != null) {
String fastaPath = config.fastaURL;
String indexPath = config.indexURL;
- String gziIndexPath = config.gziIndexURL;
+ String gziIndexPath = config.gziIndexURL != null ? config.gziIndexURL : config.compressedIndexURL; // Synonyms
uncachedSequence = fastaPath.endsWith(".gz") ?
new FastaBlockCompressedSequence(fastaPath, gziIndexPath, indexPath) :
new FastaIndexedSequence(fastaPath, indexPath);
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 6d1a13abec..2654131572 100644
--- a/src/main/java/org/broad/igv/feature/genome/GenomeManager.java
+++ b/src/main/java/org/broad/igv/feature/genome/GenomeManager.java
@@ -116,7 +116,9 @@ private GenomeManager() {
* @throws UnsupportedEncodingException
*/
public static File getGenomeFile(String genomePath) throws MalformedURLException, UnsupportedEncodingException {
+
File archiveFile;
+
if (HttpUtils.isRemoteURL(genomePath.toLowerCase())) {
// We need a local copy, as there is no http zip file reader
URL genomeArchiveURL = HttpUtils.createURL(genomePath);
@@ -195,10 +197,11 @@ public Genome loadGenome(String genomePath) throws IOException {
Genome newGenome = GenomeLoader.getLoader(genomePath).loadGenome();
// Load user-defined chr aliases, if any. This is done last so they have priority
+ final File genomeCacheDirectory = DirectoryManager.getGenomeCacheDirectory();
try {
- String aliasPath = (new File(DirectoryManager.getGenomeCacheDirectory(), newGenome.getId() + "_alias.tab")).getAbsolutePath();
+ String aliasPath = (new File(genomeCacheDirectory, newGenome.getId() + "_alias.tab")).getAbsolutePath();
if (!(new File(aliasPath)).exists()) {
- aliasPath = (new File(DirectoryManager.getGenomeCacheDirectory(), newGenome.getId() + "_alias.tab.txt")).getAbsolutePath();
+ aliasPath = (new File(genomeCacheDirectory, newGenome.getId() + "_alias.tab.txt")).getAbsolutePath();
}
if ((new File(aliasPath)).exists()) {
newGenome.addChrAliases(ChromAliasParser.loadChrAliases(aliasPath));
@@ -212,7 +215,13 @@ public Genome loadGenome(String genomePath) throws IOException {
IGV.getInstance().resetSession(null);
}
- setCurrentGenome(genomePath, newGenome);
+ // If the genome is loaded from anywhere other than the cache directory add an entry to the pulldown
+ if(newGenome != null && !(new File(genomePath).getParentFile().equals(genomeCacheDirectory))) {
+ GenomeListItem genomeListItem = new GenomeListItem(newGenome.getDisplayName(), genomePath, newGenome.getId());
+ GenomeListManager.getInstance().addGenomeItem(genomeListItem, true);
+ }
+
+ setCurrentGenome(newGenome);
return currentGenome;
@@ -226,13 +235,7 @@ 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);
+ public void setCurrentGenome(Genome newGenome) {
this.currentGenome = newGenome;
@@ -354,26 +357,32 @@ public Genome getCurrentGenome() {
}
- public boolean downloadGenome(GenomeListItem item, boolean downloadSequence) {
+ public boolean downloadGenome(GenomeListItem item, boolean downloadDataFiles) {
boolean success;
try {
- File genomeFile = getGenomeFile(item.getPath()); // Has side affect of downloading .genome file
- if (downloadSequence) {
- String fastaPath = null;
+ File genomeFile = getGenomeFile(item.getPath()); // Has side affect of downloading .genome file
+
+ if (downloadDataFiles) {
+
+
if (item.getPath().endsWith(".genome")) {
GenomeDescriptor genomeDescriptor = GenomeDescriptor.parseGenomeArchiveFile(genomeFile);
- fastaPath = genomeDescriptor.getSequencePath();
+ String fastaPath = genomeDescriptor.getSequencePath();
+ if (fastaPath != null && FileUtils.isRemote(fastaPath)) {
+ File localFile = downloadFasta(fastaPath);
+ if (localFile != null) {
+ addLocalFasta(item.getId(), localFile);
+ }
+ }
+
} else if (item.getPath().endsWith(".json")) {
+
JsonGenomeLoader.GenomeDescriptor desc = (new JsonGenomeLoader(item.getPath())).loadDescriptor();
- fastaPath = desc.getFastaURL();
- }
- if (fastaPath != null && FileUtils.isRemote(fastaPath)) {
- File localFile = downloadFasta(fastaPath);
- if (localFile != null) {
- addLocalFasta(item.getId(), localFile);
- }
+
+
}
+
}
success = true;
@@ -391,7 +400,6 @@ public boolean downloadGenome(GenomeListItem item, boolean downloadSequence) {
}
return success;
-
}
@@ -466,11 +474,4 @@ private static void updateSequenceMapFile() {
}
}
- public void refreshHostedGenome(String genomeId) {
-
- Map itemMap = GenomeListManager.getInstance().getServerGenomeMap();
- 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 c4c87db379..d2c8499dba 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
@@ -98,6 +98,19 @@ private String fixChromosomeOrder(String jsonString) {
* @return
*/
private GenomeConfig fixPaths(GenomeConfig config) {
+
+ if (config.chromAliasBbURL != null) {
+ config.chromAliasBbURL = FileUtils.getAbsolutePath(config.chromAliasBbURL, genomePath);
+ }
+ if (config.twoBitURL != null) {
+ config.twoBitURL = FileUtils.getAbsolutePath(config.twoBitURL, genomePath);
+ }
+ if (config.cytobandBbURL != null) {
+ config.cytobandBbURL = FileUtils.getAbsolutePath(config.cytobandBbURL, genomePath);
+ }
+ if (config.chromSizesURL != null) {
+ config.chromSizesURL = FileUtils.getAbsolutePath(config.chromSizesURL, genomePath);
+ }
if (config.fastaURL != null) {
config.fastaURL = FileUtils.getAbsolutePath(config.fastaURL, genomePath);
}
@@ -107,6 +120,9 @@ private GenomeConfig fixPaths(GenomeConfig config) {
if (config.gziIndexURL != null) {
config.gziIndexURL = FileUtils.getAbsolutePath(config.gziIndexURL, genomePath);
}
+ if (config.compressedIndexURL != null) {
+ config.compressedIndexURL = FileUtils.getAbsolutePath(config.compressedIndexURL, genomePath);
+ }
if (config.cytobandURL != null) {
config.cytobandURL = FileUtils.getAbsolutePath(config.cytobandURL, genomePath);
}
diff --git a/src/main/java/org/broad/igv/ui/IGV.java b/src/main/java/org/broad/igv/ui/IGV.java
index a9ad28bf21..3c1f3e3a3e 100644
--- a/src/main/java/org/broad/igv/ui/IGV.java
+++ b/src/main/java/org/broad/igv/ui/IGV.java
@@ -1943,7 +1943,7 @@ public void run() {
if (!genomeLoaded) {
Genome genome = Genome.nullGenome();
- GenomeManager.getInstance().setCurrentGenome("", genome);
+ GenomeManager.getInstance().setCurrentGenome(genome);
//GenomeManager.getInstance().setCurrentGenome(Genome.NoneGenome());
diff --git a/src/main/java/org/broad/igv/ui/IGVMenuBar.java b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
index 62093a6df5..93f1e808b6 100644
--- a/src/main/java/org/broad/igv/ui/IGVMenuBar.java
+++ b/src/main/java/org/broad/igv/ui/IGVMenuBar.java
@@ -41,7 +41,6 @@
import org.broad.igv.feature.genome.GenomeUtils;
import org.broad.igv.track.AttributeManager;
import org.broad.igv.track.Track;
-import org.broad.igv.ui.commandbar.GenomeComboBox;
import org.broad.igv.ui.commandbar.GenomeListManager;
import org.broad.igv.ui.commandbar.GenomeSelectionDialog;
import org.broad.igv.util.GoogleUtils;
@@ -435,7 +434,7 @@ private JMenu createGenomesMenu() {
JMenu menu = new JMenu("Genomes");
loadGenomeFromServerMenuItem = new JMenuItem("Download Hosted Genome...");
- loadGenomeFromServerMenuItem.addActionListener(e -> GenomeComboBox.loadGenomeFromServer());
+ loadGenomeFromServerMenuItem.addActionListener(e -> GenomeSelectionDialog.selectGenomesFromServer());
loadGenomeFromServerMenuItem.setToolTipText(LOAD_GENOME_SERVER_TOOLTIP);
menu.add(loadGenomeFromServerMenuItem);
diff --git a/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java b/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java
index 0a07edb7a8..355bd8ff59 100644
--- a/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java
+++ b/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java
@@ -30,6 +30,7 @@
package org.broad.igv.ui.action;
import org.broad.igv.Globals;
+import org.broad.igv.feature.genome.Genome;
import org.broad.igv.feature.genome.load.HubGenomeLoader;
import org.broad.igv.logging.*;
import org.broad.igv.feature.genome.GenomeManager;
@@ -81,6 +82,7 @@ public void actionPerformed(ActionEvent e) {
if (!dlg.isCanceled()) {
+
String inputURLs = dlg.getFileURL();
if (inputURLs != null && inputURLs.trim().length() > 0) {
@@ -89,7 +91,7 @@ public void actionPerformed(ActionEvent e) {
if (inputs.length == 1 && HubGenomeLoader.isHubURL(inputs[0])) {
LongRunningTask.submit(() -> {
try {
- GenomeManager.getInstance().loadGenome(inputs[0]);
+ Genome newGenome = GenomeManager.getInstance().loadGenome(inputs[0]);
} catch (IOException ex) {
log.error("Error loading tack hub", ex);
MessageUtils.showMessage("Error loading track hub: " + ex.getMessage());
diff --git a/src/main/java/org/broad/igv/ui/action/UCSCGenArkAction.java b/src/main/java/org/broad/igv/ui/action/UCSCGenArkAction.java
index c159bc00cc..785d23a307 100644
--- a/src/main/java/org/broad/igv/ui/action/UCSCGenArkAction.java
+++ b/src/main/java/org/broad/igv/ui/action/UCSCGenArkAction.java
@@ -27,12 +27,14 @@
import org.broad.igv.Globals;
import org.broad.igv.feature.genome.Genome;
+import org.broad.igv.feature.genome.GenomeListItem;
import org.broad.igv.feature.genome.GenomeManager;
import org.broad.igv.feature.genome.load.HubGenomeLoader;
import org.broad.igv.logging.LogManager;
import org.broad.igv.logging.Logger;
import org.broad.igv.track.AttributeManager;
import org.broad.igv.ui.IGV;
+import org.broad.igv.ui.commandbar.GenomeListManager;
import org.broad.igv.ui.table.SearchableTableDialog;
import org.broad.igv.ui.table.SearchableTableModel;
import org.broad.igv.ui.table.SearchableTableRecord;
diff --git a/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
index f9cc1fbf80..1b5fe42332 100644
--- a/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
+++ b/src/main/java/org/broad/igv/ui/commandbar/GenomeComboBox.java
@@ -1,15 +1,11 @@
package org.broad.igv.ui.commandbar;
import org.broad.igv.logging.*;
-import org.broad.igv.DirectoryManager;
-import org.broad.igv.event.GenomeResetEvent;
-import org.broad.igv.event.IGVEventBus;
import org.broad.igv.feature.genome.GenomeListItem;
import org.broad.igv.feature.genome.GenomeManager;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.UIConstants;
import org.broad.igv.ui.util.MessageUtils;
-import org.broad.igv.ui.util.UIUtilities;
import org.broad.igv.util.LongRunningTask;
import javax.swing.*;
@@ -17,10 +13,8 @@
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.io.File;
import java.io.IOException;
import java.util.*;
-import java.util.List;
/**
* Created by jrobinso on 7/6/17.
@@ -100,7 +94,7 @@ private void loadGenomeListItem(final GenomeListItem genomeListItem) {
if (genomeListItem != null && genomeListItem.getPath() != null) {
if (genomeListItem == GenomeListItem.DOWNLOAD_ITEM) {
- loadGenomeFromServer();
+ GenomeSelectionDialog.selectGenomesFromServer();
} else {
try {
@@ -197,76 +191,4 @@ public Component getListCellRendererComponent(JList list, Object value, int inde
}
- /**
- * Open a selection list to load a genome from the server. This method is static because its used by multiple
- * UI elements (menu bar and genome selection pulldown).
- */
- public static void loadGenomeFromServer() {
-
- Runnable showDialog = () -> {
-
- Collection inputListItems = GenomeListManager.getInstance().getServerGenomeList();
- if (inputListItems == null) {
- return;
- }
- GenomeSelectionDialog dialog = new GenomeSelectionDialog(IGV.getInstance().getMainFrame(), inputListItems);
- UIUtilities.invokeAndWaitOnEventThread(() -> dialog.setVisible(true));
-
- if (dialog.isCanceled()) {
- IGVEventBus.getInstance().post(new GenomeResetEvent());
- } else {
- List selectedValueList = dialog.getSelectedValues();
- GenomeListItem firstItem = null;
- for (GenomeListItem selectedValue : selectedValueList) {
- if (selectedValue != null) {
- boolean downloadSequence = false;
- boolean success = GenomeManager.getInstance().downloadGenome(selectedValue, downloadSequence);
- if (success) {
- GenomeListManager.getInstance().addServerGenomeItem(selectedValue);
- firstItem = selectedValue;
- }
- }
- }
- if (firstItem != null && selectedValueList.size() == 1) {
- try {
-
- GenomeManager.getInstance().loadGenome(firstItem.getPath());
- // If the user has previously defined this genome, remove it.
- GenomeListManager.getInstance().removeUserDefinedGenome(firstItem.getId());
-
- // If this is a .json genome, attempt to remove existing .genome files
- if (firstItem.getPath().endsWith(".json")) {
- removeDotGenomeFile(firstItem.getId());
- }
-
-
- } catch (IOException e) {
- GenomeListManager.getInstance().removeGenomeListItem(firstItem);
- MessageUtils.showErrorMessage("Error loading genome " + firstItem.getDisplayableName(), e);
- log.error("Error loading genome " + firstItem.getDisplayableName(), e);
- }
- }
- }
- };
-
- if (SwingUtilities.isEventDispatchThread()) {
- LongRunningTask.submit(showDialog);
- } else {
- showDialog.run();
- }
- }
-
- public static void removeDotGenomeFile(String id) {
- try {
- File dotGenomeFile = new File(DirectoryManager.getGenomeCacheDirectory(), id + ".genome");
- if (dotGenomeFile.exists()) {
- dotGenomeFile.delete();
- }
- } catch (Exception e) {
- // If anything goes wrong, just log it, this cleanup is not essential
- log.error("Error deleting .genome file", e);
- }
- }
-
-
}
diff --git a/src/main/java/org/broad/igv/ui/commandbar/GenomeListManager.java b/src/main/java/org/broad/igv/ui/commandbar/GenomeListManager.java
index 89501936a5..b6bab49160 100644
--- a/src/main/java/org/broad/igv/ui/commandbar/GenomeListManager.java
+++ b/src/main/java/org/broad/igv/ui/commandbar/GenomeListManager.java
@@ -31,7 +31,6 @@
*/
public class GenomeListManager {
- public static final String BACKUP_GENOME_SERVER_URL = "https://s3.amazonaws.com/igv.org.genomes/genomes.tsv";
private static Logger log = LogManager.getLogger(GenomeListManager.class);
private static GenomeListManager theInstance;
@@ -40,7 +39,7 @@ public class GenomeListManager {
public static final GenomeListItem DEFAULT_GENOME = new GenomeListItem(
"Human (hg38)",
- "https://igv-genepattern-org.s3.amazonaws.com/genomes/hg38/hg38.json",
+ "https://igv.org/genomes/hg38/hg38.json",
"hg38");
private Map