/******************************************************************************* * 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.operation.VCF; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFFile.VCFFile; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFHeaderType.VCFHeaderAdvancedType; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFHeaderType.VCFHeaderType; import edu.yu.einstein.genplay.util.Utils; /** * This class provides help to handle the header and to build it for export action. * * @author Nicolas Fourel * @version 0.1 */ public class ExportHeaderHandler { private Map<VCFFile, List<VCFHeaderType>> altHeadersMap; // Map between files and their list of ALT headers private Map<VCFFile, List<VCFHeaderType>> filterHeadersMap; // Map between files and their list of FILTER headers private Map<VCFFile, List<VCFHeaderType>> infoHeadersMap; // Map between files and their list of INFO headers private Map<VCFFile, List<VCFHeaderType>> formatHeadersMap; // Map between files and their list of FORMAT headers /** * Constructor of {@link ExportHeaderHandler} */ protected ExportHeaderHandler () { } /** * Set the map between files and their list of headers using a list of files. * Must be called at the beginning, existing data will be removed. * @param files the list of files */ protected void initializeHeadersMap (List<VCFFile> files) { altHeadersMap = new HashMap<VCFFile, List<VCFHeaderType>>(); filterHeadersMap = new HashMap<VCFFile, List<VCFHeaderType>>(); infoHeadersMap = new HashMap<VCFFile, List<VCFHeaderType>>(); formatHeadersMap = new HashMap<VCFFile, List<VCFHeaderType>>(); for (VCFFile file: files) { altHeadersMap.put(file, new ArrayList<VCFHeaderType>()); filterHeadersMap.put(file, new ArrayList<VCFHeaderType>()); infoHeadersMap.put(file, new ArrayList<VCFHeaderType>()); formatHeadersMap.put(file, new ArrayList<VCFHeaderType>()); } } /** * Process line information in order to update data for the new header * @param file the file related to the information fields * @param ALT the ALT information field * @param FILTER the FILTER information field * @param INFO the INFO information field * @param FORMAT the FORMAT information field */ protected void processLine (VCFFile file, String ALT, String FILTER, String INFO, String FORMAT) { processALT(file, ALT); processFILTER(file, FILTER); processINFO(file, INFO); processFORMAT(file, FORMAT); } /** * Retrieves ALT information in order to update data for the new header * @param file the file related to the information field * @param ALT the information field */ private void processALT (VCFFile file, String ALT) { String[] alternatives = Utils.split(ALT, ','); for (String alternative: alternatives) { if (alternative.charAt(0) == '<') { List<VCFHeaderType> altHeader = file.getHeader().getAltHeader(); for (VCFHeaderType header: altHeader) { if (header.getId().equals(alternative.substring(1, alternative.length() - 1))) { if (!altHeadersMap.get(file).contains(header)) { altHeadersMap.get(file).add(header); } } } } } } /** * Retrieves FILTER information in order to update data for the new header * @param file the file related to the information field * @param FILTER the information field */ private void processFILTER (VCFFile file, String FILTER) { } /** * Retrieves INFO information in order to update data for the new header * @param file the file related to the information field * @param INFO the information field */ private void processINFO (VCFFile file, String INFO) { String[] information = Utils.split(INFO, ';'); for (String info: information) { String id = Utils.split(info, '=')[0]; List<VCFHeaderAdvancedType> infoHeader = file.getHeader().getInfoHeader(); for (VCFHeaderAdvancedType header: infoHeader) { if (header.getId().equals(id)) { if (!infoHeadersMap.get(file).contains(header)) { infoHeadersMap.get(file).add(header); } } } } } /** * Retrieves FORMAT information in order to update data for the new header * @param file the file related to the information field * @param FORMAT the information field */ private void processFORMAT (VCFFile file, String FORMAT) { String[] format = Utils.split(FORMAT, ':'); for (String id: format) { List<VCFHeaderAdvancedType> formatHeader = file.getHeader().getFormatHeader(); for (VCFHeaderAdvancedType header: formatHeader) { if (header.getId().equals(id)) { if (!formatHeadersMap.get(file).contains(header)) { formatHeadersMap.get(file).add(header); } } } } } /** * @return the header containing the used fields */ protected String getFieldHeader () { String header = ""; // Gets the headers String alt = getHeader(altHeadersMap); String filter = getHeader(filterHeadersMap); String info = getHeader(infoHeadersMap); String format = getHeader(formatHeadersMap); // Adds the ALT header if (!alt.isEmpty()) { header += alt; } // Adds the FILTER header if (!filter.isEmpty()) { if (!header.isEmpty()) { header += "\n"; } header += filter; } // Adds the INFO header if (!info.isEmpty()) { if (!header.isEmpty()) { header += "\n"; } header += info; } // Adds the FORMAT header if (!format.isEmpty()) { if (!header.isEmpty()) { header += "\n"; } header += format; } return header; } /** * @param map map of headers * @return the formatted field header part using the map */ private String getHeader (Map<VCFFile, List<VCFHeaderType>> map) { String result = ""; for (List<VCFHeaderType> headers: map.values()) { for (int i = 0; i < headers.size(); i++) { String line = headers.get(i).getAsOriginalLine(); if (!line.isEmpty()) { result += line; if (i < (headers.size() - 1)) { result += "\n"; } } } } return result; } }