From b8e4abee7a647f8e5a4b21babddb7c8ec853d300 Mon Sep 17 00:00:00 2001 From: jrobinso <933148+jrobinso@users.noreply.github.com> Date: Thu, 28 Sep 2023 21:46:20 -0700 Subject: [PATCH] Add explicit "htsget" menu to IGV doesn't have to guess. 99% or more of urls entered are not going to be htsget endpoints, so we should not be making https requests to try to find out. --- .../org/broad/igv/htsget/HtsgetUtils.java | 3 + .../java/org/broad/igv/track/TrackLoader.java | 105 +++++++----------- .../java/org/broad/igv/ui/IGVMenuBar.java | 7 +- .../java/org/broad/igv/ui/UIConstants.java | 2 + .../igv/ui/action/LoadFromURLMenuAction.java | 8 +- 5 files changed, 56 insertions(+), 69 deletions(-) diff --git a/src/main/java/org/broad/igv/htsget/HtsgetUtils.java b/src/main/java/org/broad/igv/htsget/HtsgetUtils.java index 39525dc97a..88bf8bdc06 100644 --- a/src/main/java/org/broad/igv/htsget/HtsgetUtils.java +++ b/src/main/java/org/broad/igv/htsget/HtsgetUtils.java @@ -41,6 +41,9 @@ public static Metadata getMetadata(final String url) throws IOException { return null; } else { String format = json.get("htsget").getAsJsonObject().get("format").getAsString(); +// if(!(format.toUpperCase().equals("BAM")) || format.toUpperCase().equals("VCF")) { +// throw new RuntimeException(("Format")) +// } return new Metadata(url, format); } } diff --git a/src/main/java/org/broad/igv/track/TrackLoader.java b/src/main/java/org/broad/igv/track/TrackLoader.java index 03254f5707..0ded5799ef 100644 --- a/src/main/java/org/broad/igv/track/TrackLoader.java +++ b/src/main/java/org/broad/igv/track/TrackLoader.java @@ -124,6 +124,7 @@ public List load(ResourceLocator locator, Genome genome) throws DataLoadE log.info("Loading resource: " + (locator.isDataURL() ? "" : path)); try { + String format = locator.getFormat(); if (format.equals("tbi")) { @@ -134,9 +135,23 @@ public List load(ResourceLocator locator, Genome genome) throws DataLoadE //This list will hold all new tracks created for this locator List newTracks = new ArrayList(); + + // Determine track type, if possible, and add new tracks if (locator.isHtsget()) { - tryHtsget(locator, newTracks, genome); - } else if (format.equals("gmt")) { + HtsgetUtils.Metadata htsgetMeta = HtsgetUtils.getMetadata(locator.getPath()); + locator.setFormat(htsgetMeta.getFormat().toLowerCase()); + if (htsgetMeta.getFormat().equals("VCF")) { + locator.setHtsget(true); + HtsgetVariantSource source = new HtsgetVariantSource(htsgetMeta, genome); + loadVCFWithSource(locator, source, newTracks); + } else if (htsgetMeta.getFormat().equals("BAM") || htsgetMeta.getFormat().equals("CRAM")) { + locator.setHtsget(true); + loadAlignmentsTrack(locator, newTracks, genome); + } else { + throw new RuntimeException("Format: '" + htsgetMeta.getFormat() + "' is not supported for htsget servers."); + } + + } else if (format.equals("gmt")) { loadGMT(locator); } else if (format.equals("vcf.list")) { loadVCFListFile(locator, newTracks, genome); @@ -208,33 +223,29 @@ public List load(ResourceLocator locator, Genome genome) throws DataLoadE loadMutFile(locator, newTracks, genome); // Must be tried before ".maf" test below } else if (format.equals("maf")) { loadMultipleAlignmentTrack(locator, newTracks, genome); - } else { - //if a url, try htsget - boolean isHtsget = tryHtsget(locator, newTracks, genome); - if (!isHtsget) { - - // If the file is too large, give up - // TODO -- ftp test - final int tenMB = 10000000; - long fileLength = ParsingUtils.getContentLength(locator.getPath()); - if (fileLength > tenMB) { - MessageUtils.confirm("Cannot determine file type of: " + locator.getPath()); - } + } else { + // If the file is too large, give up + // TODO -- ftp test + final int tenMB = 10000000; + long fileLength = ParsingUtils.getContentLength(locator.getPath()); + if (fileLength > tenMB) { + MessageUtils.confirm("Cannot determine file type of: " + locator.getPath()); + } - // Read file contents and try to sort it out - String contents = FileUtils.getContents(locator.getPath()); - BufferedReader reader = new BufferedReader(new StringReader(contents)); - - if (CytoBandFileParser.isValid(reader, locator.getPath())) { - Track track = new CytobandTrack(locator, new BufferedReader(new StringReader(contents)), genome); - newTracks.add(track); - } else if (AttributeManager.isSampleInfoFile(reader)) { - // This might be a sample information file. - AttributeManager.getInstance().loadSampleInfo(locator); - } else { - MessageUtils.showMessage("Unknown file type: " + path + "
Check file extension"); - } + // Read file contents and try to sort it out + String contents = FileUtils.getContents(locator.getPath()); + BufferedReader reader = new BufferedReader(new StringReader(contents)); + + if (CytoBandFileParser.isValid(reader, locator.getPath())) { + Track track = new CytobandTrack(locator, new BufferedReader(new StringReader(contents)), genome); + newTracks.add(track); + } else if (AttributeManager.isSampleInfoFile(reader)) { + // This might be a sample information file. + AttributeManager.getInstance().loadSampleInfo(locator); + } else { + MessageUtils.showMessage("Unknown file type: " + path + "
Check file extension"); } + } // Track line @@ -275,46 +286,6 @@ public List load(ResourceLocator locator, Genome genome) throws DataLoadE } - /** - * Try to load as an htsget resource. As most (all?) htsget endpoints use an https:// scheme URL, there is - * no way to detect other than try. - * - * @param locator - * @param newTracks - * @param genome - * @return - */ - private boolean tryHtsget(ResourceLocator locator, List newTracks, Genome genome) { - boolean isHtsget = false; - if (locator.getPath().startsWith("https://") || - locator.getPath().startsWith("http://") || - locator.getPath().startsWith("htsget://")) { - try { - HtsgetUtils.Metadata htsgetMeta = HtsgetUtils.getMetadata(locator.getPath()); - if (htsgetMeta != null) { - isHtsget = true; - locator.setFormat(htsgetMeta.getFormat().toLowerCase()); - if (htsgetMeta.getFormat().equals("VCF")) { - locator.setHtsget(true); - HtsgetVariantSource source = new HtsgetVariantSource(htsgetMeta, genome); - loadVCFWithSource(locator, source, newTracks); - } else if (htsgetMeta.getFormat().equals("BAM") || htsgetMeta.getFormat().equals("CRAM")) { - locator.setHtsget(true); - loadAlignmentsTrack(locator, newTracks, genome); - } else { - throw new RuntimeException("Format: '" + htsgetMeta.getFormat() + "' is not supported for htsget servers."); - } - } - } catch (IOException e) { - // Not neccessarily an error, might just indicate its not an htsget server. Not sure - // if this should be logged or not, it will be a common and expected occurence when loading - // sample information, which is checked after htsget - return false; - } - } - return isHtsget; - } - public static boolean isAlignmentTrack(String typeString) { if (typeString == null) { return false; diff --git a/src/main/java/org/broad/igv/ui/IGVMenuBar.java b/src/main/java/org/broad/igv/ui/IGVMenuBar.java index 1537a7fcd6..9d5599000d 100644 --- a/src/main/java/org/broad/igv/ui/IGVMenuBar.java +++ b/src/main/java/org/broad/igv/ui/IGVMenuBar.java @@ -284,7 +284,12 @@ JMenu createFileMenu() { menuAction.setToolTipText(UIConstants.LOAD_TRACKS_TOOLTIP); menuItems.add(MenuAndToolbarUtils.createMenuItem(menuAction)); - menuAction = new LoadFromServerAction("Load from Server...", KeyEvent.VK_S, igv); + menuAction = new LoadFromURLMenuAction(LoadFromURLMenuAction.LOAD_FROM_HTSGET, 0, igv); + menuAction.setToolTipText(UIConstants.LOAD_HTSGET_TOOLTOP); + menuItems.add(MenuAndToolbarUtils.createMenuItem(menuAction)); + + + menuAction = new LoadFromServerAction("Load from IGV Server...", KeyEvent.VK_S, igv); menuAction.setToolTipText(UIConstants.LOAD_SERVER_DATA_TOOLTIP); menuItems.add(MenuAndToolbarUtils.createMenuItem(menuAction)); diff --git a/src/main/java/org/broad/igv/ui/UIConstants.java b/src/main/java/org/broad/igv/ui/UIConstants.java index fbefdddd00..466bb43b96 100644 --- a/src/main/java/org/broad/igv/ui/UIConstants.java +++ b/src/main/java/org/broad/igv/ui/UIConstants.java @@ -49,6 +49,8 @@ public class UIConstants { // Menu tooltips static final public String LOAD_TRACKS_TOOLTIP = "Load tracks or sample information"; + + static final public String LOAD_HTSGET_TOOLTOP = "Load BAM or VCF tracks from an htsget server"; static final public String LOAD_SERVER_DATA_TOOLTIP = "Load tracks or sample information from a server"; static final public String SAVE_PNG_IMAGE_TOOLTIP = "Capture and save a PNG image"; static final public String SAVE_SVG_IMAGE_TOOLTIP = "Capture and save an SVG image"; 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 9c8473c975..47180de028 100644 --- a/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java +++ b/src/main/java/org/broad/igv/ui/action/LoadFromURLMenuAction.java @@ -59,6 +59,8 @@ public class LoadFromURLMenuAction extends MenuAction { static Logger log = LogManager.getLogger(LoadFilesMenuAction.class); public static final String LOAD_FROM_URL = "Load from URL..."; public static final String LOAD_GENOME_FROM_URL = "Load Genome from URL..."; + + public static final String LOAD_FROM_HTSGET = "Load from htsget server..."; private IGV igv; public LoadFromURLMenuAction(String label, int mnemonic, IGV igv) { @@ -71,7 +73,8 @@ public void actionPerformed(ActionEvent e) { JPanel ta = new JPanel(); ta.setPreferredSize(new Dimension(600, 20)); - if (e.getActionCommand().equalsIgnoreCase(LOAD_FROM_URL)) { + boolean isHtsGet = e.getActionCommand().equalsIgnoreCase(LOAD_FROM_HTSGET); + if (e.getActionCommand().equalsIgnoreCase(LOAD_FROM_URL) || isHtsGet) { LoadFromURLDialog dlg = new LoadFromURLDialog(IGV.getInstance().getMainFrame()); dlg.setVisible(true); @@ -114,6 +117,9 @@ public void actionPerformed(ActionEvent e) { String indexUrl = indexes[i]; rl.setIndexPath(indexUrl); } + if(isHtsGet) { + rl.setHtsget(true); + } locators.add(rl); } igv.loadTracks(locators);