/******************************************************************************* * 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.gui.action.track; import javax.swing.ActionMap; import edu.yu.einstein.genplay.core.IO.dataReader.SCWReader; import edu.yu.einstein.genplay.core.IO.extractor.Extractor; import edu.yu.einstein.genplay.core.IO.extractor.SAMExtractor; import edu.yu.einstein.genplay.core.IO.extractor.StrandedExtractor; import edu.yu.einstein.genplay.core.IO.utils.ChromosomesSelector; import edu.yu.einstein.genplay.core.IO.utils.StrandedExtractorOptions; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.DuplicateSAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.InvalidSAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.MappingQualitySAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.NotUniqueNorPrimarySAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.NotUniqueSAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.ReadGroupsSAMRecordFilter; import edu.yu.einstein.genplay.core.IO.utils.SAMRecordFilter.UnpairedSAMRecordFilter; import edu.yu.einstein.genplay.core.manager.project.ProjectManager; import edu.yu.einstein.genplay.dataStructure.enums.SCWListType; import edu.yu.einstein.genplay.dataStructure.enums.ScoreOperation; import edu.yu.einstein.genplay.dataStructure.enums.Strand; import edu.yu.einstein.genplay.dataStructure.list.genomeWideList.SCWList.SCWList; import edu.yu.einstein.genplay.dataStructure.list.genomeWideList.SCWList.SCWListFactory; import edu.yu.einstein.genplay.dataStructure.list.genomeWideList.SCWList.SimpleSCWList.SimpleSCWList; import edu.yu.einstein.genplay.dataStructure.list.genomeWideList.SCWList.binList.BinList; import edu.yu.einstein.genplay.exception.exceptions.InvalidFileTypeException; import edu.yu.einstein.genplay.gui.action.TrackListActionExtractorWorker; import edu.yu.einstein.genplay.gui.dialog.newCurveLayerDialog.NewCurveLayerDialog; import edu.yu.einstein.genplay.gui.track.Track; import edu.yu.einstein.genplay.gui.track.layer.AbstractSCWLayer; import edu.yu.einstein.genplay.gui.track.layer.BinLayer; import edu.yu.einstein.genplay.gui.track.layer.SimpleSCWLayer; import edu.yu.einstein.genplay.util.colors.Colors; /** * Adds a {@link SimpleSCWLayer} to the selected track * @author Julien Lajugie */ public final class TAAddSCWLayer extends TrackListActionExtractorWorker<SCWList> { private static final long serialVersionUID = -7836987725953057426L; // generated ID private static final String ACTION_NAME = "Add Window Layer"; // action name private static final String DESCRIPTION = "Add a layer displaying windows with a score"; // tooltip private ScoreOperation scoreCalculation = null; // method of calculation for the score private Strand strand = null; // strand to extract private int fragmentLength = 0; // user specified length of the fragments private int readLength = 0; // user specified length of the reads private String samHistory = null; // history line for sam extraction private boolean isBinList = false; // true if the result should be a bin list private int binSize = 0; // Size of the bins of the BinList /** * key of the action in the {@link ActionMap} */ public static final String ACTION_KEY = TAAddSCWLayer.class.getName(); /** * Creates an instance of {@link TAAddSCWLayer} * @param extractor the extractor that will extract the data */ public TAAddSCWLayer(Extractor extractor) { super(extractor); putValue(NAME, ACTION_NAME); putValue(ACTION_COMMAND_KEY, ACTION_KEY); putValue(SHORT_DESCRIPTION, DESCRIPTION); } @Override public void doAtTheEnd(SCWList actionResult) { if (actionResult != null) { Track selectedTrack = getTrackListPanel().getSelectedTrack(); AbstractSCWLayer<?> newLayer; String history = new String(); if (isBinList) { newLayer = new BinLayer(selectedTrack, (BinList) actionResult, name); // add the history to the layer history = "Bin Size = " + binSize + "bp, "; } else { newLayer = new SimpleSCWLayer(selectedTrack, actionResult, name); } newLayer.getHistory().add("Load " + extractor.getDataFile().getAbsolutePath(), Colors.GREY); history += "Method of Calculation = " + scoreCalculation; if (strand != null) { history += ", Strand = "; if (strand == Strand.FIVE) { history += "5'"; } else { history += "3'"; } } if (fragmentLength != 0) { history += ", Fragment Length = " + fragmentLength + "bp"; } if (readLength != 0) { history += ", Read Length = " + readLength + "bp"; } if (!history.isEmpty()) { newLayer.getHistory().add(history, Colors.GREY); } if (samHistory != null) { newLayer.getHistory().add(samHistory, Colors.GREY); } selectedTrack.getLayers().add(newLayer); selectedTrack.setActiveLayer(newLayer); } } @Override protected void doBeforeExtraction() throws InterruptedException { boolean isStrandNeeded = extractor instanceof StrandedExtractor; boolean isSAMExtractor = extractor instanceof SAMExtractor; boolean isMultiGenome = ProjectManager.getInstance().isMultiGenomeProject(); NewCurveLayerDialog ncld = new NewCurveLayerDialog(extractor); if (ncld.showDialog(getRootPane()) == NewCurveLayerDialog.APPROVE_OPTION) { selectedChromo = ncld.getSelectedChromosomes(); // if not all the chromosomes are selected we need // to ask the user if the file is sorted or not extractor.setChromosomeSelector(new ChromosomesSelector(selectedChromo)); name = ncld.getLayerName(); scoreCalculation = ncld.getScoreCalculationMethod(); isBinList = ncld.isCreateBinListSelected(); binSize = ncld.getBinSize(); // set strand options if (isStrandNeeded) { strand = ncld.getStrandToExtract(); fragmentLength = ncld.getFragmentLengthValue(); readLength = ncld.getReadLengthValue(); StrandedExtractorOptions strandedExtractorOptions = new StrandedExtractorOptions(strand, fragmentLength, readLength); ((StrandedExtractor) extractor).setStrandedExtractorOptions(strandedExtractorOptions); } // set SAM options if (isSAMExtractor) { samHistory = ""; SAMExtractor samExtractor = (SAMExtractor) extractor; // always remove invalid reads samExtractor.addFilter(new InvalidSAMRecordFilter()); if (ncld.getReadGroup() != null) { samExtractor.addFilter(new ReadGroupsSAMRecordFilter(ncld.getReadGroup())); samHistory += "Read Group: " + ncld.getReadGroup().getId() + ", "; } if (ncld.isRemoveDuplicatesSelected()) { samExtractor.addFilter(new DuplicateSAMRecordFilter()); samHistory += "Duplicates Removed, "; } if (ncld.isPairedEndSelected()) { samExtractor.setPairedMode(true); samExtractor.addFilter(new UnpairedSAMRecordFilter()); samHistory += "Paired-End Mode"; } else { samExtractor.setPairedMode(false); samHistory += "Single-End Mode"; if (ncld.getMappingQuality() > 0) { samExtractor.addFilter(new MappingQualitySAMRecordFilter(ncld.getMappingQuality())); samHistory += ", Mapping Quality ≥ " + ncld.getMappingQuality(); } if (ncld.isUniqueSelected()) { samExtractor.addFilter(new NotUniqueSAMRecordFilter()); samHistory += ", Unique Alignments Only"; } else if (ncld.isPrimaryAligmentSelected()) { samExtractor.addFilter(new NotUniqueNorPrimarySAMRecordFilter()); samHistory += ", Unique and Primary Alignments"; } } } // set multi-genome options if (isMultiGenome) { genomeName = ncld.getGenomeName(); alleleType = ncld.getAlleleType(); extractor.setGenomeName(genomeName); extractor.setAlleleType(alleleType); } } else { throw new InterruptedException(); } } @Override protected SCWList generateList() throws Exception { try { SCWList scwList; if (((fragmentLength != 0) || (readLength != 0)) && (strand == null)) { /* if we extract both strand and the strands are shifted we need to use the strand safe * factory since reads on the 3' strand are shifted toward 5' which can change the order * of reads and cause the file to be no longer sorted */ if (isBinList) { notifyActionStart("Generating Fixed-Window Layer", (BinList.getCreationStepCount(SCWListType.BIN) * 3) + 2, true); scwList = SCWListFactory.createStrandSafeBinList((SCWReader) extractor, binSize, scoreCalculation); } else { notifyActionStart("Generating Variable-Window Layer", (SimpleSCWList.getCreationStepCount(SCWListType.GENERIC) * 3) + 2, true); scwList = SCWListFactory.createStrandSafeDenseSCWList((SCWReader) extractor, scoreCalculation); } } else { if (isBinList) { notifyActionStart("Generating Fixed-Window Layer", BinList.getCreationStepCount(SCWListType.BIN) + 1, true); scwList = SCWListFactory.createBinList((SCWReader) extractor, binSize, scoreCalculation); } else { notifyActionStart("Generating Variable-Window Layer", SimpleSCWList.getCreationStepCount(SCWListType.GENERIC) + 1, true); scwList = SCWListFactory.createDenseSCWList((SCWReader) extractor, scoreCalculation); } } return scwList; } catch (ClassCastException e) { throw new InvalidFileTypeException(); } } }