/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.core.multiGenome.filter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.List; import edu.yu.einstein.genplay.core.manager.project.ProjectManager; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFLine; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFFile.VCFFile; import edu.yu.einstein.genplay.core.multiGenome.data.display.variant.Variant; import edu.yu.einstein.genplay.dataStructure.list.primitiveList.PrimitiveList; /** * @author Nicolas Fourel * @version 0.1 */ public class VCFFilter extends MGFilter implements Serializable { /** Generated serial version ID */ private static final long serialVersionUID = 8207888574897530618L; private static final int SAVED_FORMAT_VERSION_NUMBER = 0; // saved format version private VCFFile vcfFile; // the file reader private List<Boolean> booleanList; // list of boolean meaning whether variants pass the filter or not /** * Constructor of {@link VCFFilter} */ public VCFFilter () { filter = null; vcfFile = null; booleanList = null; } /** * Constructor of {@link VCFFilter} * @param filter the filter * @param vcfFile the reader */ public VCFFilter (FilterInterface filter, VCFFile vcfFile) { this.filter = filter; this.vcfFile = vcfFile; booleanList = null; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if((obj == null) || (obj.getClass() != this.getClass())) { return false; } // object must be Test at this point VCFFilter test = (VCFFilter)obj; return vcfFile.equals(test.getVCFFile()) && filter.equals(test.getFilter()); } /** * Analyzes lines from VCF file in order to determine if variation pass the filter. * @param results list of VCF lines delimited by columns (must contains the column of the filter) */ public void generateFilter (List<VCFLine> results) { vcfFile.initializePositionList(ProjectManager.getInstance().getProjectWindow().getGenomeWindow().getChromosome(), results); if (results != null) { booleanList = new PrimitiveList<Boolean>(Boolean.class, vcfFile.getPositionList().size()); for (VCFLine currentVcfLine: results) { boolean valid = filter.isValid(currentVcfLine); booleanList.add(valid); } } } /** * @return the booleanList */ public List<Boolean> getBooleanList() { return booleanList; } @Override public VCFFilter getDuplicate () { VCFFilter duplicate = new VCFFilter(); duplicate.setFilter(getFilter().getDuplicate()); duplicate.setVCFFile(getVCFFile()); duplicate.setBooleanList(getBooleanList()); return duplicate; } /** * Recursive function. Returns the index where the value is found * or the index right after if the exact value is not found. * @param value value * @return the index where the start value of the window is found or -1 if the value is not found */ public int getIndex (int value) { List<Integer> data = vcfFile.getPositionList(); int index = getIndex(value, 0, data.size() - 1); if (data.get(index) == value) { return index; } else { int lengthCurrentIndex = Math.abs(data.get(index) - value); int lengthSecondIndex = -1; int secondIndex = -1; if (value > data.get(index)) { if ((index + 1) < data.size()) { secondIndex = index + 1; } } else { if ((index - 1) > 0) { secondIndex = index -1; } } if (secondIndex >= 0) { lengthSecondIndex = Math.abs(data.get(secondIndex) - value); if (lengthSecondIndex < lengthCurrentIndex) { index = secondIndex; } } } return index; } /** * Recursive function. Returns the index where the value is found * or the index right after if the exact value is not found. * @param value value * @param indexStart start index (in the data array) * @param indexStop stop index (in the data array) * @return the index where the start value of the window is found or the index right after if the exact value is not found */ private int getIndex (int value, int indexStart, int indexStop) { List<Integer> data = vcfFile.getPositionList(); int middle = (indexStop - indexStart) / 2; if (indexStart == indexStop) { return indexStart; } else if (value == data.get(indexStart + middle)) { return indexStart + middle; } else if (value > data.get(indexStart + middle)) { return getIndex(value, indexStart + middle + 1, indexStop); } else { return getIndex(value, indexStart, indexStart + middle); } } @Override public int getVariantIndex(Variant variant) { int position = variant.getReferenceGenomePosition(); return getIndex(position); } /** * @return the reader */ public VCFFile getVCFFile() { return vcfFile; } @Override public boolean isVariantValid(int variantIndex) { boolean result = false; if (variantIndex != -1) { result = booleanList.get(variantIndex); } return result; } @Override public boolean isVariantValid (Variant variant) { int index = getVariantIndex(variant); return isVariantValid(index); } /** * Method used for unserialization * @param in * @throws IOException * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.readInt(); filter = (FilterInterface) in.readObject(); vcfFile = (VCFFile) in.readObject(); booleanList = (List<Boolean>) in.readObject(); } /** * @param booleanList the booleanList to set */ public void setBooleanList(List<Boolean> booleanList) { this.booleanList = booleanList; } /** * @param reader the reader to set */ public void setVCFFile(VCFFile reader) { vcfFile = reader; } @Override public void show () { String info = ""; info += "VCF File: " + vcfFile.getFile().getName() + "\n"; info += "Filter display: " + filter.toStringForDisplay() + "\n"; System.out.println(info); } /** * Shows information about the MG filter */ public void showBooleanList () { String info = ""; if (booleanList == null) { info += "The boolean list is null"; } else { if (booleanList.size() == 0) { info += "The boolean list is empty"; } else { info += "Size of the boolean list: " + booleanList.size() + "\n"; for (int i = 0; i < booleanList.size(); i++) { info += booleanList.get(i) + "; "; if ((i > 0) && ((i % 5) == 0)) { info += "\n"; } } } } System.out.println(info); } /** * Method used for serialization * @param out * @throws IOException */ private void writeObject(ObjectOutputStream out) throws IOException { out.writeInt(SAVED_FORMAT_VERSION_NUMBER); out.writeObject(filter); out.writeObject(vcfFile); out.writeObject(booleanList); } }