Skip to content
Commits on Source (2)
......@@ -2,3 +2,4 @@
.idea/workspace.xml
*.jar
igv.sh
/out/
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 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.
-->
<project name="IGV" default="all" basedir=".">
......
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 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.
-->
<project name="macrodefs">
......
{
"id": "hg38",
"ucscID": "hg38",
"name": "Human (hg38)",
"fastaURL": "http://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa",
"indexURL": "http://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai",
"cytobandURL": "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/cytoBandIdeo.txt.gz",
"aliasURL": "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/hg38/hg38_alias.tab",
"annotations": [
{
"name": "Refseq Genes",
"url": "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/refGene.txt.gz",
"indexed": false
}
]
}
https://s3.amazonaws.com/igv.broadinstitute.org/annotations/WS235/WS235_annotations.xml
<?xml version="1.0"?>
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 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.
-->
<project name="igvtools" basedir="../." default="deploy">
......
<!--
~ Copyright (c) 2007-2012 The Broad Institute, Inc.
~ SOFTWARE COPYRIGHT NOTICE
~ This software and its documentation are the copyright of the Broad Institute, Inc. All rights are reserved.
~
~ This software is supplied without any warranty or guaranteed support whatsoever. The Broad Institute is not responsible for its use, misuse, or functionality.
~
~ This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
~ Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
~ The MIT License (MIT)
~
~ Copyright (c) 2007-2017 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.
-->
<project name="IGV" default="build" basedir="../.">
......
......@@ -335,7 +335,7 @@ public class CommandExecutor {
}
}
private String setSleepInterval(String param1) {
public String setSleepInterval(String param1) {
try {
sleepInterval = Integer.parseInt(param1.trim());
return "OK";
......
......@@ -40,6 +40,7 @@ import org.broad.igv.feature.Chromosome;
import org.broad.igv.feature.Cytoband;
import org.broad.igv.track.FeatureTrack;
import org.broad.igv.ui.panel.ReferenceFrame;
import org.broad.igv.util.ResourceLocator;
import java.io.*;
import java.util.*;
......@@ -67,6 +68,7 @@ public class Genome {
private String species;
private String ucscID;
private GenomeDescriptor descriptor; // Can be null
private ArrayList<ResourceLocator> annotationResources;
public Genome(String id, String displayName, Sequence sequence, boolean chromosOrdered, GenomeDescriptor descriptor) {
......@@ -601,4 +603,12 @@ public class Genome {
public boolean sequenceIsLoaded(ReferenceFrame frame) {
return sequence.isLoaded(frame);
}
public void setAnnotationResources(ArrayList<ResourceLocator> annotationResources) {
this.annotationResources = annotationResources;
}
public ArrayList<ResourceLocator> getAnnotationResources() {
return annotationResources;
}
}
......@@ -43,7 +43,6 @@ import java.io.InputStream;
public abstract class GenomeDescriptor {
private String name;
private boolean chrNamesAltered;
private String id;
protected String cytoBandFileName;
protected String geneFileName;
......@@ -55,11 +54,9 @@ public abstract class GenomeDescriptor {
private boolean hasCustomSequencePath;
private boolean chromosomesAreOrdered = false;
private boolean fasta = false;
private boolean fastaDirectory = false;
private String [] fastaFileNames;
public GenomeDescriptor(String name,
boolean chrNamesAltered,
String id,
String cytoBandFileName,
String geneFileName,
......@@ -70,9 +67,7 @@ public abstract class GenomeDescriptor {
String compressedSequencePath,
boolean chromosomesAreOrdered,
boolean fasta,
boolean fastaDirectory,
String fastaFileNameString) {
this.chrNamesAltered = chrNamesAltered;
this.name = name;
this.id = id;
this.cytoBandFileName = cytoBandFileName;
......@@ -84,7 +79,6 @@ public abstract class GenomeDescriptor {
this.compressedSequencePath = compressedSequencePath;
this.chromosomesAreOrdered = chromosomesAreOrdered;
this.fasta = fasta;
this.fastaDirectory = fastaDirectory;
if(fastaFileNameString != null) {
fastaFileNames = fastaFileNameString.split(",");
......@@ -109,8 +103,6 @@ public abstract class GenomeDescriptor {
return id;
}
// Used to determine feature file type, really only extension is needed
public String getGeneFileName() {
return geneFileName;
}
......@@ -123,12 +115,6 @@ public abstract class GenomeDescriptor {
return fastaFileNames;
}
public abstract InputStream getCytoBandStream() throws IOException;
public abstract InputStream getGeneStream() throws IOException;
public abstract InputStream getChrAliasStream() throws IOException;
public String getSequencePath() {
return compressedSequencePath == null ? sequencePath : compressedSequencePath;
}
......@@ -165,4 +151,10 @@ public abstract class GenomeDescriptor {
return hasCustomSequencePath;
}
public abstract InputStream getCytoBandStream() throws IOException;
public abstract InputStream getGeneStream() throws IOException;
public abstract InputStream getChrAliasStream() throws IOException;
}
......@@ -34,6 +34,10 @@
package org.broad.igv.feature.genome;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.log4j.Logger;
import org.broad.igv.DirectoryManager;
import org.broad.igv.Globals;
......@@ -51,8 +55,10 @@ import org.broad.igv.track.*;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.commandbar.GenomeListManager;
import org.broad.igv.ui.panel.FrameManager;
import org.broad.igv.ui.util.*;
import org.broad.igv.ui.util.MessageUtils;
import org.broad.igv.ui.util.ProgressBar;
import org.broad.igv.ui.util.ProgressMonitor;
import org.broad.igv.ui.util.UIUtilities;
import org.broad.igv.ui.util.download.Downloader;
import org.broad.igv.util.*;
......@@ -101,21 +107,10 @@ public class GenomeManager {
private GenomeListManager genomeListManager;
// public static String getUserDefinedGenomeListFile() {
// if (Globals.isTesting()) {
// return TEST_USER_DEFINED_GENOME_LIST_FILE;
// } else {
// return ACT_USER_DEFINED_GENOME_LIST_FILE;
// }
//
// }
private static GenomeManager theInstance;
private Genome currentGenome;
boolean serverGenomeListUnreachable = false;
private Map<String, File> localSequenceMap;
/**
......@@ -149,9 +144,6 @@ public class GenomeManager {
}
}
public boolean isServerGenomeListUnreachable() {
return serverGenomeListUnreachable;
}
public void loadGenomeById(String genomeId) throws IOException {
......@@ -214,7 +206,11 @@ public class GenomeManager {
} else if (genomePath.endsWith(".chrom.sizes")) {
altGenomePath = genomePath;
newGenome = loadChromSizes(genomePath);
} else if (genomePath.endsWith(".json")) {
altGenomePath = genomePath;
newGenome = loadJsonFile(genomePath);
} else {
// Assume a fasta file
altGenomePath = genomePath;
if (genomePath.endsWith(Globals.GZIP_FILE_EXTENSION)) {
......@@ -262,8 +258,13 @@ public class GenomeManager {
setCurrentGenome(newGenome);
if (IGV.hasInstance()) {
FeatureTrack geneFeatureTrack = newGenome.getGeneTrack();
FeatureTrack geneFeatureTrack = newGenome.getGeneTrack(); // Can be null
IGV.getInstance().setGenomeTracks(geneFeatureTrack);
List<ResourceLocator> resources = newGenome.getAnnotationResources();
if (resources != null) {
IGV.getInstance().loadResources(resources);
}
}
......@@ -384,6 +385,55 @@ public class GenomeManager {
return newGenome;
}
private Genome loadJsonFile(String genomePath) throws IOException {
Genome newGenome = null;
BufferedReader reader = ParsingUtils.openBufferedReader(genomePath);
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(reader).getAsJsonObject();
String id = json.get("id").getAsString();
String name = json.get("name").getAsString();
String fastaPath = json.get("fastaURL").getAsString();
JsonElement indexPathObject = json.get("indexURL");
String indexPath = indexPathObject == null ? null : indexPathObject.getAsString();
FastaIndexedSequence sequence = fastaPath.endsWith(".gz") ?
new FastaBlockCompressedSequence(fastaPath, indexPath) :
new FastaIndexedSequence(fastaPath, indexPath);
ArrayList<ResourceLocator> tracks = new ArrayList<>();
JsonArray annotations = json.getAsJsonArray("annotations");
if (annotations != null) {
annotations.forEach((JsonElement jsonElement) -> {
JsonObject obj = jsonElement.getAsJsonObject();
String trackPath = obj.get("url").getAsString();
JsonElement trackName = obj.get("name");
JsonElement trackIndexPath = obj.get("indexURL");
JsonElement indexed = obj.get("indexed");
JsonElement aliasURL = obj.get("aliasURL");
ResourceLocator res = new ResourceLocator(trackPath);
if (trackName != null) res.setName(trackName.getAsString());
if (trackIndexPath != null) res.setIndexPath(trackIndexPath.getAsString());
if (indexed != null) res.setIndexed(indexed.getAsBoolean());
tracks.add(res);
});
}
newGenome = new Genome(id, name, sequence, true);
newGenome.setAnnotationResources(tracks);
// TODO -- set aliases
return newGenome;
}
private Collection<Collection<String>> loadChrAliases(String path) {
// String id = genome.getId();
......@@ -720,7 +770,6 @@ public class GenomeManager {
// The new descriptor
genomeDescriptor = new GenomeZipDescriptor(
properties.getProperty(GENOME_ARCHIVE_NAME_KEY),
chrNamesAltered,
properties.getProperty(GENOME_ARCHIVE_ID_KEY),
cytobandZipEntryName,
geneFileName,
......@@ -733,7 +782,6 @@ public class GenomeManager {
zipEntries,
chromosomesAreOrdered,
fasta,
fastaDirectory,
fastaFileNameString);
if (url != null) {
......
......@@ -43,7 +43,6 @@ public class GenomeZipDescriptor extends GenomeDescriptor {
private ZipFile genomeZipFile;
public GenomeZipDescriptor(String name,
boolean chrNamesAltered,
String id,
String cytoBandFileName,
String geneFileName,
......@@ -56,12 +55,11 @@ public class GenomeZipDescriptor extends GenomeDescriptor {
Map<String, ZipEntry> zipEntries,
boolean chromosomesAreOrdered,
boolean fasta,
boolean fastaDirectory,
String fastaFileNameString) {
super(name, chrNamesAltered, id, cytoBandFileName, geneFileName, chrAliasFileName, geneTrackName,
super(name, id, cytoBandFileName, geneFileName, chrAliasFileName, geneTrackName,
sequenceLocation, hasCustomSequenceLocation, compressedSequencePath,
chromosomesAreOrdered, fasta, fastaDirectory, fastaFileNameString);
chromosomesAreOrdered, fasta, fastaFileNameString);
this.zipEntries = zipEntries;
this.genomeZipFile = genomeZipFile;
......
......@@ -7,25 +7,31 @@ import org.broad.igv.util.LittleEndianInputStream;
import org.broad.igv.util.ParsingUtils;
import org.broad.igv.util.stream.IGVSeekableStreamFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by jrobinso on 6/23/17.
*/
public class FastaBlockCompressedSequence extends FastaIndexedSequence {
Mapping [] gziMappings;
Mapping[] gziMappings;
Mapping zeroMapping = new Mapping(0, 0);
public FastaBlockCompressedSequence(String path) throws IOException {
super(path);
String gziPath = path + ".gzi";
this(path, null);
}
public FastaBlockCompressedSequence(String path, String indexPath) throws IOException {
super(path);
readGziMappings(gziPath);
if(indexPath == null) indexPath = path + ".gzi";
readGziMappings(indexPath);
}
@Override
......@@ -44,7 +50,7 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
try {
int nBytes = (int) (posEnd - posStart);
int bufferSize = Math.max(512000, nBytes/8);
int bufferSize = Math.max(512000, nBytes / 8);
ss = new SeekableBufferedStream(IGVSeekableStreamFactory.getInstance().getStreamFor(path), bufferSize);
......@@ -66,16 +72,15 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
protected Mapping findBlockContaining(long uoffset) {
int ilo = 0, ihi = gziMappings.length - 1;
while ( ilo<=ihi )
{
int i = (ilo+ihi) / 2;
while (ilo <= ihi) {
int i = (ilo + ihi) / 2;
Mapping mapping = gziMappings[i];
if ( uoffset < mapping.uncompressedOffset ) ihi = i - 1;
else if ( uoffset >= mapping.uncompressedOffset ) ilo = i + 1;
if (uoffset < mapping.uncompressedOffset) ihi = i - 1;
else if (uoffset >= mapping.uncompressedOffset) ilo = i + 1;
else break;
}
return ilo == 0 ? zeroMapping : gziMappings[ilo-1];
return ilo == 0 ? zeroMapping : gziMappings[ilo - 1];
}
......@@ -99,13 +104,13 @@ public class FastaBlockCompressedSequence extends FastaIndexedSequence {
private void readFully(byte[] b, InputStream is) throws IOException {
int len = b.length;
if(len < 0) {
if (len < 0) {
throw new IndexOutOfBoundsException();
} else {
int count;
for(int n = 0; n < len; n += count) {
for (int n = 0; n < len; n += count) {
count = is.read(b, n, len - n);
if(count < 0) {
if (count < 0) {
throw new EOFException();
}
}
......
......@@ -25,12 +25,10 @@
package org.broad.igv.feature.genome.fasta;
import htsjdk.samtools.seekablestream.SeekableBufferedStream;
import htsjdk.samtools.seekablestream.SeekableStream;
import org.apache.log4j.Logger;
import org.broad.igv.feature.genome.Sequence;
import org.broad.igv.util.FileUtils;
import org.broad.igv.util.HttpUtils;
import org.broad.igv.util.ParsingUtils;
import org.broad.igv.util.stream.IGVSeekableStreamFactory;
......@@ -56,11 +54,15 @@ public class FastaIndexedSequence implements Sequence {
private final ArrayList<String> chromoNamesList;
public FastaIndexedSequence(String path) throws IOException {
this(path, null);
}
public FastaIndexedSequence(String path, String indexPath) throws IOException {
this.path = path;
contentLength = ParsingUtils.getContentLength(path);
String indexPath = path + ".fai";
if (indexPath == null) indexPath = path + ".fai";
index = new FastaIndex(indexPath);
chromoNamesList = new ArrayList<>(index.getSequenceNames());
......@@ -95,6 +97,7 @@ public class FastaIndexedSequence implements Sequence {
FastaIndex.FastaSequenceIndexEntry idxEntry = index.getIndexEntry(chr);
if (idxEntry == null) {
log.info("No fasta sequence entry for: " + chr);
return null;
}
......@@ -149,8 +152,7 @@ public class FastaIndexedSequence implements Sequence {
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
log.error("Error loading sequence " + chr + ":" + qstart + "-" + qend, e);
return null;
}
}
......@@ -171,7 +173,7 @@ public class FastaIndexedSequence implements Sequence {
SeekableStream ss = null;
try {
ss = IGVSeekableStreamFactory.getInstance().getStreamFor(path);
ss = IGVSeekableStreamFactory.getInstance().getStreamFor(path);
int nBytes = (int) (posEnd - posStart);
byte[] bytes = new byte[nBytes];
ss.seek(posStart);
......
......@@ -37,12 +37,17 @@ import org.broad.igv.util.FileUtils;
import org.broad.igv.util.HttpUtils;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.prefs.Preferences;
/**
......@@ -66,7 +71,7 @@ public class OAuthUtils {
private static final String PROPERTIES_URL = "https://igvdata.broadinstitute.org/app/oauth_native.json";
private String genomicsScope = "https://www.googleapis.com/auth/genomics";
private String gsScope = "https://www.googleapis.com/auth/devstorage.read_write";
private String profileScope = "https://www.googleapis.com/auth/userinfo.profile";
private String emailScope = "https://www.googleapis.com/auth/userinfo.email";
private String state = "%2Fprofile";
private String redirectURI = "http%3A%2F%2Flocalhost%3A60151%2FoauthCallback";
private String oobURI = "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob";
......@@ -84,19 +89,23 @@ public class OAuthUtils {
private static OAuthUtils theInstance;
private String currentUserName;
private String currentUserEmail;
private String currentUserID;
// dwm08
// by default this is the google scope
private String scope = genomicsScope + "%20" + gsScope + "%20" + profileScope;
private String scope = genomicsScope + "%20" + gsScope + "%20" + emailScope;
// Construct OAuthUtils earcly so Google menu can be updated to the
// Construct OAuthUtils earcly so Google menu can be updated to the
// correct oauth provider. dwm08
static {
if (theInstance == null) {
if (theInstance == null) {
theInstance = new OAuthUtils();
}
}
public static synchronized OAuthUtils getInstance() {
if (theInstance == null) {
......@@ -169,7 +178,7 @@ public class OAuthUtils {
* @throws URISyntaxException
*/
public void openAuthorizationPage() throws IOException, URISyntaxException {
Desktop desktop = Desktop.getDesktop();
Desktop desktop = Desktop.getDesktop();
// properties moved to early init dwm08
//if (clientId == null) fetchOauthProperties();
......@@ -208,13 +217,13 @@ public class OAuthUtils {
// throw new IOException("Either scope or resource must be provided to authenticate.");
// }
// check if the "browse" Desktop action is suppported (many Linux DEs cannot directly
// launch browsers!)
if(desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url));
} else { // otherwise, display a dialog box for the user to copy the URL manually.
MessageUtils.showMessage("Copy this authorization URL into your web browser: " + url);
}
// check if the "browse" Desktop action is suppported (many Linux DEs cannot directly
// launch browsers!)
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url));
} else { // otherwise, display a dialog box for the user to copy the URL manually.
MessageUtils.showMessage("Copy this authorization URL into your web browser: " + url);
}
// if the listener is not active, prompt the user
// for the access token
......@@ -330,29 +339,26 @@ public class OAuthUtils {
*
* @throws IOException
*/
private void fetchUserProfile() throws IOException {
// dwm08 - removing functionality to get user profile info from microsoft oauth. Just not worth the trouble
// JWT jwt = JWT.decode(accessToken);
// Map<String, Claim> claims = jwt.getClaims();
// for (String claim: claims.keySet()) {
// System.out.println(claim + " = " + claims.get(claim).asString());
// }
// currentUserName = claims.get("unique_name").asString();
public JsonObject fetchUserProfile() throws IOException {
try {
URL url = new URL("https://www.googleapis.com/plus/v1/people/me?access_token=" + accessToken);
URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken);
String response = HttpUtils.getInstance().getContentsAsJSON(url);
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(response).getAsJsonObject();
currentUserName = obj.get("displayName").getAsString();
} catch (Throwable exception){
}
currentUserName = obj.get("name").getAsString();
currentUserEmail = obj.get("email").getAsString();
currentUserID = obj.get("id").getAsString();
return obj;
} catch (Throwable exception) {
log.error(exception);
return null;
}
}
public String getAccessToken() {
// Check expiration time, with 1 minute cushion
......@@ -428,4 +434,89 @@ public class OAuthUtils {
}
}
/**
* Try to login to secure server. dwm08
*/
public static void doSecureLogin() {
// if user is not currently logged in, attempt to
// log in user if not logged in dwm08
if (!OAuthUtils.getInstance().isLoggedIn()) {
try {
OAuthUtils.getInstance().openAuthorizationPage();
} catch (Exception ex) {
MessageUtils.showErrorMessage("Error fetching oAuth tokens. See log for details", ex);
log.error("Error fetching oAuth tokens", ex);
}
}
// wait until authentication successful or 1 minute -
// dwm08
int i = 0;
while (!OAuthUtils.getInstance().isLoggedIn() && i < 600) {
++i;
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
/**
* Generate a set of all urls in the sessino file
*
* @param sessionPath
* @return list of urls
*/
public static Set<String> findUrlsInSessionFile(String sessionPath) {
BufferedReader br = null;
HashSet<String> urlSet = new HashSet<>();
try {
br = new BufferedReader(new FileReader(new File(sessionPath)));
String line;
while ((line = br.readLine()) != null) {
int start = line.indexOf("http");
if (start != -1) {
int mid = line.indexOf("://", start);
int end = line.indexOf("/", mid + 3);
String url = line.substring(start, end);
urlSet.add(url);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
}
}
}
return urlSet;
}
/**
* Check if any reference in the session file refers to a server protected
* by the oauth protocol. If so, check to see if the user is logged in. If
* user is not logged in, put up login prompt.
*
* @param sessionPath
*/
public static void checkServerLogin(String sessionPath) {
Set<String> urlSet = findUrlsInSessionFile(sessionPath);
if (urlSet.size() > 0) {
for (String url : urlSet) {
if (OAuthUtils.isGoogleCloud(url)) {
OAuthUtils.doSecureLogin();
// user is logged in. Can proceed with the load
return;
}
}
}
}
}
......@@ -7,7 +7,6 @@ import java.util.Arrays;
*/
final public class Constants {
private Constants() {} // Prevent instantiation
// Preference sets
......@@ -248,6 +247,10 @@ final public class Constants {
// Letter of support dialog
public static final String SHOW_LOS = "showLOS";
// Experimental
public static final String SCORE_VARIANTS = "SCORE_VARIANTS";
/**
* List of keys that affect the alignments loaded. This list is used to trigger a reload, if required.
* Not all alignment preferences need trigger a reload, this is a subset.
......
......@@ -25,13 +25,16 @@ public class PreferencesManager implements IGVEventObserver {
private static List<PreferenceGroup> preferenceGroupList;
private static Logger log = Logger.getLogger(PreferencesManager.class);
private static Map<String, IGVPreferences> preferencesMap = Collections.synchronizedMap(new HashMap<>());
private static IGVPreferences genericDefaults;
public static boolean forceDefaults = false;
private static String prefFile; // User preferences file
static Hashtable<String, String> aliasTable = new Hashtable<String, String>();
static {
aliasTable.put("SAM>SORT_OPTION", "SAM.SORT_OPTION");
aliasTable.put("FLAKING_REGIONS", "FLANKING_REGION");
......@@ -49,7 +52,9 @@ public class PreferencesManager implements IGVEventObserver {
if (preferenceGroupList == null) {
init();
}
if (preferencesMap.containsKey(category)) {
if (forceDefaults) {
return genericDefaults;
} else if (preferencesMap.containsKey(category)) {
return preferencesMap.get(category);
} else {
return preferencesMap.get(NULL_CATEGORY);
......@@ -80,7 +85,7 @@ public class PreferencesManager implements IGVEventObserver {
}
}
IGVPreferences genericDefaults = new IGVPreferences(defaultPreferences.get(NULL_CATEGORY), null);
genericDefaults = new IGVPreferences(defaultPreferences.get(NULL_CATEGORY), null);
IGVPreferences rnaDefaults = new IGVPreferences(defaultPreferences.get(RNA), genericDefaults);
IGVPreferences thirdGenDefaults = new IGVPreferences(defaultPreferences.get(THIRD_GEN), genericDefaults);
......@@ -101,7 +106,7 @@ public class PreferencesManager implements IGVEventObserver {
}
public static IGVPreferences getPreferences() {
return getPreferences(NULL_CATEGORY);
return forceDefaults ? genericDefaults : getPreferences(NULL_CATEGORY);
}
public static Collection<IGVPreferences> getAllPreferences() {
......
......@@ -142,6 +142,7 @@ CRAM.CACHE_SEQUENCES Cache reference sequences boolean TRUE
CRAM.CACHE_SIZE Cache size (MB) integer 500
#Proxy
PROXY.DISABLE_CHECK Disable check for system proxy boolean FALSE
PROXY.USE Use proxy boolean FALSE
PROXY.HOST Proxy host string null
PROXY.PORT Proxy port integer 0
......@@ -168,6 +169,8 @@ TOOLTIP.DISMISS_DELAY Tooltip dismiss delay (ms) integer 60000
---
#Hidden
SCORE_VARIANTS FALSE
SAM.COLOR_BY UNEXPECTED_PAIR
SAM.AUTOSORT FALSE
SAM.SHADE_CENTER TRUE
......
......@@ -41,6 +41,7 @@ import org.broad.igv.track.Track;
import org.broad.igv.ui.panel.FrameManager;
import org.broad.igv.ui.panel.ReferenceFrame;
import org.broad.igv.util.ResourceLocator;
import org.broad.igv.util.collections.IntArrayList;
import java.io.IOException;
import java.util.*;
......@@ -57,7 +58,7 @@ public class AlignmentDataManager implements IGVEventObserver {
private static Logger log = Logger.getLogger(AlignmentDataManager.class);
private Collection<AlignmentInterval> intervalCache;
private List<AlignmentInterval> intervalCache;
private ResourceLocator locator;
private HashMap<String, String> chrMappings = new HashMap();
private Set<Range> isLoading = new HashSet<>();
......@@ -66,7 +67,6 @@ public class AlignmentDataManager implements IGVEventObserver {
private Map<String, PEStats> peStats;
private SpliceJunctionHelper.LoadOptions loadOptions;
private Object loadLock = new Object();
private boolean showAlignments = true;
private AlignmentTrack.ExperimentType inferredExperimentType;
private Set<Track> subscribedTracks;
......@@ -86,21 +86,7 @@ public class AlignmentDataManager implements IGVEventObserver {
public void receiveEvent(Object event) {
if (event instanceof FrameManager.ChangeEvent) {
Collection<ReferenceFrame> frames = ((FrameManager.ChangeEvent) event).getFrames();
Collection<AlignmentInterval> newCache = Collections.synchronizedList(new ArrayList<>());
// Trim cache to include only current frames
for (ReferenceFrame f : frames) {
AlignmentInterval i = getLoadedInterval(f);
if (i != null) {
newCache.add(i);
}
}
intervalCache = newCache;
trimCache();
} else if (event instanceof RefreshEvent) {
clear();
} else {
......@@ -206,7 +192,6 @@ public class AlignmentDataManager implements IGVEventObserver {
}
}
return null;
}
......@@ -306,7 +291,11 @@ public class AlignmentDataManager implements IGVEventObserver {
log.debug("Loading alignments: " + chr + ":" + adjustedStart + "-" + adjustedEnd + " for " + AlignmentDataManager.this);
AlignmentInterval loadedInterval = loadInterval(chr, adjustedStart, adjustedEnd, renderOptions);
trimCache();
intervalCache.add(loadedInterval);
packAlignments(renderOptions);
......@@ -318,6 +307,25 @@ public class AlignmentDataManager implements IGVEventObserver {
}
/**
* Remove out-of-view intervals from the cache. This is O(N) where N = #frames X #intervals. It is assumed
* that N is small
*/
private synchronized void trimCache() {
Iterator<AlignmentInterval> iter = intervalCache.iterator();
while(iter.hasNext()) {
AlignmentInterval interval = iter.next();
for (ReferenceFrame frame : FrameManager.getFrames()) {
if (!interval.contains(frame.getCurrentRange())) {
iter.remove();
}
}
}
}
AlignmentInterval loadInterval(String chr, int start, int end, AlignmentTrack.RenderOptions renderOptions) {
String sequence = chrMappings.containsKey(chr) ? chrMappings.get(chr) : chr;
......@@ -332,8 +340,8 @@ public class AlignmentDataManager implements IGVEventObserver {
ReadStats readStats = new ReadStats();
AlignmentTileLoader.AlignmentTile t = reader.loadTile(sequence, start, end, spliceJunctionHelper,
downsampleOptions, readStats, peStats, bisulfiteContext, showAlignments);
downsampleOptions, readStats, peStats, bisulfiteContext);
//
if (inferredExperimentType == null && !Globals.VERSION.contains("2.4")) {
readStats.compute();
inferType(readStats);
......@@ -476,19 +484,6 @@ public class AlignmentDataManager implements IGVEventObserver {
coverageTrack.setSnpThreshold(PreferencesManager.getPreferences().getAsFloat(SAM_ALLELE_THRESHOLD));
}
public void setShowAlignments(boolean showAlignments) {
if (showAlignments != this.showAlignments) {
this.showAlignments = showAlignments;
if (showAlignments == false) {
dumpAlignments();
} else {
// Change from false => true, need to reload
intervalCache.clear();
}
}
}
public boolean isTenX() {
return reader.isTenX();
}
......
......@@ -121,8 +121,7 @@ public class AlignmentTileLoader implements IGVEventObserver {
SpliceJunctionHelper spliceJunctionHelper,
AlignmentDataManager.DownsampleOptions downsampleOptions,
ReadStats readStats, Map<String, PEStats> peStats,
AlignmentTrack.BisulfiteContext bisulfiteContext,
boolean showAlignments) {
AlignmentTrack.BisulfiteContext bisulfiteContext) {
final IGVPreferences prefMgr = PreferencesManager.getPreferences();
boolean filterFailedReads = prefMgr.getAsBoolean(SAM_FILTER_FAILED_READS);
......@@ -134,7 +133,7 @@ public class AlignmentTileLoader implements IGVEventObserver {
boolean reducedMemory = prefMgr.getAsBoolean(SAM_REDUCED_MEMORY_MODE);
AlignmentTile t = new AlignmentTile(start, end, spliceJunctionHelper, downsampleOptions, bisulfiteContext, showAlignments, reducedMemory);
AlignmentTile t = new AlignmentTile(start, end, spliceJunctionHelper, downsampleOptions, bisulfiteContext, reducedMemory);
//assert (tiles.size() > 0);
......@@ -392,7 +391,6 @@ public class AlignmentTileLoader implements IGVEventObserver {
private static final Random RAND = new Random();
private boolean downsample;
private boolean showAlignments;
private int samplingWindowSize;
private int samplingDepth;
......@@ -417,14 +415,12 @@ public class AlignmentTileLoader implements IGVEventObserver {
SpliceJunctionHelper spliceJunctionHelper,
AlignmentDataManager.DownsampleOptions downsampleOptions,
AlignmentTrack.BisulfiteContext bisulfiteContext,
boolean showAlignments,
boolean reducedMemory) {
this.start = start;
this.end = end;
this.downsampledIntervals = new ArrayList<DownsampledInterval>();
this.indelLimit = PreferencesManager.getPreferences().getAsInt(SAM_SMALL_INDEL_BP_THRESHOLD);
this.showAlignments = showAlignments;
long seed = System.currentTimeMillis();
//System.out.println("seed: " + seed);
......@@ -485,19 +481,17 @@ public class AlignmentTileLoader implements IGVEventObserver {
spliceJunctionHelper.addAlignment(alignment);
}
if (showAlignments) {
if (downsample) {
final int alignmentStart = alignment.getAlignmentStart();
int currentSamplingBucketEnd = currentSamplingWindowStart + samplingWindowSize;
if (currentSamplingWindowStart < 0 || alignmentStart >= currentSamplingBucketEnd) {
setCurrentSamplingBucket(alignmentStart);
}
if (downsample) {
final int alignmentStart = alignment.getAlignmentStart();
int currentSamplingBucketEnd = currentSamplingWindowStart + samplingWindowSize;
if (currentSamplingWindowStart < 0 || alignmentStart >= currentSamplingBucketEnd) {
setCurrentSamplingBucket(alignmentStart);
}
attemptAddRecordDownsampled(alignment);
attemptAddRecordDownsampled(alignment);
} else {
alignments.add(alignment);
}
} else {
alignments.add(alignment);
}
alignment.finish();
......