Skip to content

Commit

Permalink
Add explicit "htsget" menu to IGV doesn't have to guess. 99% or more …
Browse files Browse the repository at this point in the history
…of urls entered are not going to be htsget endpoints, so we should not be making https requests to try to find out.
  • Loading branch information
jrobinso committed Sep 29, 2023
1 parent 396c7e2 commit b8e4abe
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 69 deletions.
3 changes: 3 additions & 0 deletions src/main/java/org/broad/igv/htsget/HtsgetUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
105 changes: 38 additions & 67 deletions src/main/java/org/broad/igv/track/TrackLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public List<Track> load(ResourceLocator locator, Genome genome) throws DataLoadE

log.info("Loading resource: " + (locator.isDataURL() ? "<data url>" : path));
try {

String format = locator.getFormat();

if (format.equals("tbi")) {
Expand All @@ -134,9 +135,23 @@ public List<Track> load(ResourceLocator locator, Genome genome) throws DataLoadE
//This list will hold all new tracks created for this locator
List<Track> newTracks = new ArrayList<Track>();


// 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);
Expand Down Expand Up @@ -208,33 +223,29 @@ public List<Track> 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("<html>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("<html>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("<html>Unknown file type: " + path + "<br>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("<html>Unknown file type: " + path + "<br>Check file extension");
}

}

// Track line
Expand Down Expand Up @@ -275,46 +286,6 @@ public List<Track> 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<Track> 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;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/org/broad/igv/ui/IGVMenuBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/broad/igv/ui/UIConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit b8e4abe

Please sign in to comment.