/*
* 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.
*/
/*
* sample chrom loc.start loc.end num.mark num.informative seg.mean
TCGA-02-0001-01C-01D-0183-04 1 554268 74674720 6892 6721 0.2077
TCGA-02-0001-01C-01D-0183-04 1 74693652 75110251 37 37 -0.2659
*/
package org.broad.igv.data.seg;
//~--- non-JDK imports --------------------------------------------------------
import org.broad.igv.feature.FeatureUtils;
import org.broad.igv.feature.LocusScore;
import org.broad.igv.feature.genome.Genome;
import org.broad.igv.track.TrackProperties;
import org.broad.igv.track.TrackType;
import org.broad.igv.util.ResourceLocator;
import java.util.*;
/**
* @author jrobinso
*/
public class SegmentedAsciiDataSet implements SegmentedDataSet {
//SegFileParser parser;
TrackType trackType = TrackType.COPY_NUMBER;
float dataMax = -Float.MAX_VALUE;
float dataMin = Float.MAX_VALUE;
/**
* Assume data is non-log value until suggested otherwise by the precense
* of negative numbers. TODO This is a fragile assumption, the user should
* input this information directly.
*/
private boolean logNormalized = false;
/**
* Map of [heading -> [chr -> [list of chrSegments]]]
*/
private Map<String, Map<String, List<LocusScore>>> segments = new HashMap();
/**
* Set of chromosomes represented in this dataset
*/
private Set<String> chromosomes = new HashSet();
private List<String> headings = new ArrayList();
private Map<String, List<LocusScore>> wholeGenomeScoresCache = new HashMap();
private long lastRefreshTime = 0;
private TrackProperties trackProperties;
Genome genome;
public SegmentedAsciiDataSet(Genome genome) {
this.genome = genome;
}
public SegmentedAsciiDataSet(ResourceLocator locator, Genome genome) {
//parser = locator.getPath().toLowerCase().endsWith(".gbench") ?
// new GBenchFileParser(locator) :
// new SegmentFileParser(locator);
this.genome = genome;
sortLists();
}
public void sortLists() {
for (Map.Entry<String, Map<String, List<LocusScore>>> sampleEntry : segments.entrySet()) {
for (Map.Entry<String, List<LocusScore>> chrEntry : sampleEntry.getValue().entrySet()) {
List<LocusScore> tmp = chrEntry.getValue();
FeatureUtils.sortFeatureList(tmp);
}
}
}
/**
*
*/
public void addSegment(String heading, String c, int start, int end, float value, String desc) {
String chr = genome == null ? c : genome.getCanonicalChrName(c);
Map<String, List<LocusScore>> chrSegments = segments.get(heading);
if (chrSegments == null) {
headings.add(heading);
chrSegments = new HashMap();
segments.put(heading, chrSegments);
}
List<LocusScore> segmentList = chrSegments.get(chr);
if (segmentList == null) {
segmentList = new ArrayList<LocusScore>();
chrSegments.put(chr, segmentList);
}
segmentList.add(new Segment(start, start, end, end, value, desc));
dataMax = Math.max(dataMax, value);
dataMin = Math.min(dataMin, value);
if (value < 0) {
logNormalized = true;
}
chromosomes.add(chr);
}
/**
* Method description
*
* @return
*/
public Set<String> getChromosomes() {
return chromosomes;
}
/**
* Method description
*
* @param heading
* @param chr
* @return
*/
public List<LocusScore> getSegments(String heading, String chr) {
Map<String, List<LocusScore>> chrSegments = segments.get(heading);
return (chrSegments == null) ? null : chrSegments.get(chr);
}
public List<String> getSampleNames() {
return headings;
}
/**
* Method description
*
* @return
*/
public TrackType getType() {
return trackType;
}
/**
* Method description
*
* @return
*/
public boolean isLogNormalized() {
return logNormalized;
}
/**
* Method description
*
* @param chr
* @return
*/
public double getDataMax(String chr) {
return dataMax;
}
/**
* Method description
*
* @param chr
* @return
*/
public double getDataMin(String chr) {
return dataMin;
}
/**
* Method description
*
* @param heading
* @return
*/
public List<LocusScore> getWholeGenomeScores(String heading) {
List<LocusScore> wholeGenomeScores = wholeGenomeScoresCache.get(heading);
if ((wholeGenomeScores == null) || wholeGenomeScores.isEmpty()) {
// Compute the smallest concievable feature that could be viewed on the
// largest screen. Be conservative. The smallest feature is one at
// the screen resolution scale in <chr units> / <pixel>
double minFeatureSize = 0; // ((double) genome.getLength()) / (maxScreenSize * locationUnit);
long offset = 0;
wholeGenomeScores = new ArrayList(1000);
for (String chr : genome.getLongChromosomeNames()) {
List<LocusScore> chrSegments = getSegments(heading, chr);
if (chrSegments != null) {
int lastgEnd = -1;
for (LocusScore score : chrSegments) {
Segment seg = (Segment) score;
int gStart = genome.getGenomeCoordinate(chr, seg.getStart());
int gEnd = genome.getGenomeCoordinate(chr, seg.getEnd());
if ((gEnd - gStart) > minFeatureSize) {
wholeGenomeScores.add(new Segment(gStart, gStart, gEnd,
gEnd, seg.getScore(), seg.getDescription()));
}
}
}
offset += genome.getChromosome(chr).getLength();
}
wholeGenomeScoresCache.put(heading, wholeGenomeScores);
}
return wholeGenomeScores;
}
/**
* Method description
*
* @return
*/
public TrackType getTrackType() {
return trackType;
}
/**
* Method description
*
* @param trackType
*/
public void setTrackType(TrackType trackType) {
this.trackType = trackType;
}
public void setTrackProperties(TrackProperties props) {
this.trackProperties = props;
}
public TrackProperties getTrackProperties() {
if (trackProperties == null) {
trackProperties = new TrackProperties();
}
return trackProperties;
}
}