/*
* 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.maf;
import org.apache.log4j.Logger;
import org.broad.igv.Globals;
import org.broad.igv.feature.genome.Genome;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.util.MessageUtils;
import org.broad.igv.util.FileUtils;
import org.broad.igv.util.LongRunningTask;
import org.broad.igv.util.ParsingUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
/**
* Implementation of MAFReader for MAF files that are split by chromosome (1 file per chromosome). Requires
* a 2 column mapping file, chr -> maf file.
*
* @author Jim Robinson
* @date 4/16/12
*/
public class MAFListReader implements MAFReader {
private static Logger log = Logger.getLogger(MAFListReader.class);
List<String> chrNames;
private String refId;
/**
* Species (sequences) represented in this maf file.
*/
private List<String> species;
/**
* A lookup table for species (id -> name). This is optional
*/
private Map<String, String> speciesNames;
// Map of chr name -> MAF file path
Map<String, String> filenameMap;
// Map of chr name -> MAFLocalReader
Map<String, MAFParser> readerMap;
public MAFListReader(String mappingFile) throws IOException {
loadDictionaryFile(mappingFile);
loadSpeciesNames(mappingFile);
readerMap = new HashMap<String, MAFParser>();
}
public String getRefId() {
return refId;
}
private void loadDictionaryFile(String mappingFile) throws IOException {
chrNames = new ArrayList<String>();
// Map of chr name -> MAF file path
filenameMap = new HashMap();
BufferedReader br = null;
try {
br = ParsingUtils.openBufferedReader(mappingFile);
String nextLine;
while ((nextLine = br.readLine()) != null) {
if (nextLine.startsWith("#")) continue;
String[] tokens = Globals.tabPattern.split(nextLine, -1);
if (tokens.length != 2) {
log.info("Skipping line: " + nextLine);
} else {
String chr = tokens[0];
String fname = tokens[1];
String fullPath = FileUtils.getAbsolutePath(fname, mappingFile);
filenameMap.put(chr, fullPath);
chrNames.add(chr);
}
}
} finally {
if (br != null) br.close();
}
}
/**
* Load a file containing species IDs and names.
*
* @param path
*/
private void loadSpeciesNames(String path) {
InputStream is = null;
species = new ArrayList<String>();
speciesNames = new LinkedHashMap<String, String>();
try {
String speciesPath = path + ".species";
if (FileUtils.resourceExists(speciesPath)) {
is = ParsingUtils.openInputStream(speciesPath);
} else {
// No file, use default
is = MAFUtils.class.getResourceAsStream("species.properties");
}
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String nextLine;
while ((nextLine = br.readLine()) != null) {
if (nextLine.startsWith("#ref")) {
String[] tokens = Globals.equalPattern.split(nextLine);
refId = tokens[1];
} else {
String[] tokens = Globals.equalPattern.split(nextLine);
if (tokens.length == 2) {
String id = tokens[0];
String name = tokens[1];
species.add(id);
speciesNames.put(id, name);
} else {
//log.info("Skipping line: " + nextLine);
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}
//
// public MAFTile loadTile(String chr, int start, int end, List<String> species) {
//
// MAFLocalReader reader = getReader(chr);
// return reader == null ? null : reader.loadTile(chr, start, end, species);
// }
@Override
public List<MultipleAlignmentBlock> loadAlignments(String chr, int start, int end) throws IOException {
MAFReader reader = getReader(chr);
return reader == null ? null : reader.loadAlignments(chr, start, end);
}
private MAFParser getReader(final String chr) {
MAFParser reader = readerMap.get(chr);
if (reader == null) {
final String path = filenameMap.get(chr);
if (path == null) {
log.info("No MAF file found for chromosome: " + chr);
} else {
try {
reader = new MAFParser(path);
readerMap.put(chr, reader);
} catch (Exception e) {
log.error("Error loading MAF reader (" + path + "): ", e);
MessageUtils.showMessage("Error loading MAF file: " + e.getMessage());
}
}
}
return reader;
}
public List<String> getChrNames() {
return chrNames;
}
@Override
public String getSpeciesName(String speciesId) {
if (speciesNames != null && speciesNames.containsKey(speciesId)) {
return speciesNames.get(speciesId);
} else {
return speciesId;
}
}
public Collection<String> getSpecies() {
return species;
}
}