diff --git a/.classpath b/.classpath index 4165f5d7..c9bdbd45 100644 --- a/.classpath +++ b/.classpath @@ -6,20 +6,6 @@ - - - - - - - - - - - - - - @@ -29,4 +15,4 @@ - \ No newline at end of file + diff --git a/.project b/.project index 7bd8d663..9bd869e1 100644 --- a/.project +++ b/.project @@ -20,4 +20,15 @@ org.eclipse.jdt.core.javanature org.eclipse.buildship.core.gradleprojectnature + + + 1731979070369 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs index 9d2efc8e..18cd189d 100644 --- a/.settings/org.eclipse.buildship.core.prefs +++ b/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments=--init-script /var/folders/vs/qy0cxq3x47v2gjsbgwxmt14r0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/vs/qy0cxq3x47v2gjsbgwxmt14r0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= -eclipse.preferences.version=1 \ No newline at end of file +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Library/Java/JavaVirtualMachines/jdk-22.jdk/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/src/main/java/scriptmanager/main/ScriptManagerGUI.java b/src/main/java/scriptmanager/main/ScriptManagerGUI.java index 38fcbace..bbd08889 100755 --- a/src/main/java/scriptmanager/main/ScriptManagerGUI.java +++ b/src/main/java/scriptmanager/main/ScriptManagerGUI.java @@ -115,6 +115,10 @@ public void run() { // CrossCorrelation pnlStat.add(initializeToolPanel("Cross Correlation", ToolDescriptions.archtex_crosscorrelation_description, Class.forName("scriptmanager.window_interface.BAM_Statistics.CrossCorrelationWindow"))); + + // CollectBaseDistributionByCycle + pnlStat.add(initializeToolPanel("Collect BAM Distribution", ToolDescriptions.collect_base_distribution_by_cycle_description, + Class.forName("scriptmanager.window_interface.BAM_Statistics.CollectBaseDistributionByCycleWindow"))); // ======== BAM_Manipulation ======== JPanel pnlBamManip = new JPanel(); @@ -138,6 +142,26 @@ public void run() { // FilterPIPseq pnlBamManip.add(initializeToolPanel("Filter for PIP-seq", ToolDescriptions.filter_pip_seq_description, Class.forName("scriptmanager.window_interface.BAM_Manipulation.FilterforPIPseqWindow"))); + + // DownsampleSAM + pnlBamManip.add(initializeToolPanel("Downsample SAM/BAM", ToolDescriptions.downsample_sam_description, + Class.forName("scriptmanager.window_interface.BAM_Manipulation.DownsampleSamWindow"))); + + // ValidateSAMFile + pnlBamManip.add(initializeToolPanel("Validate SAM/BAM", ToolDescriptions.validate_sam_file_description, + Class.forName("scriptmanager.window_interface.BAM_Manipulation.ValidateSamWindow"))); + + // NormalizeFasta + pnlBamManip.add(initializeToolPanel("Normalize FASTA File", ToolDescriptions.normalize_fasta_description, + Class.forName("scriptmanager.window_interface.BAM_Manipulation.NormalizeFastaWindow"))); + + // FilterSAMReads + pnlBamManip.add(initializeToolPanel("Filter BAM Reads", ToolDescriptions.filter_sam_reads_description, + Class.forName("scriptmanager.window_interface.BAM_Manipulation.FilterSamReadsWindow"))); + + // FilterSAMReads + pnlBamManip.add(initializeToolPanel("Add Comments to BAM", ToolDescriptions.add_comments_to_bam_description, + Class.forName("scriptmanager.window_interface.BAM_Manipulation.AddCommentsToBamWindow"))); // ======== BAM_Format_Converter ======== JPanel pnlBamConvert = new JPanel(); @@ -160,6 +184,14 @@ public void run() { pnlBamConvert.add(initializeToolPanel("BAM to bedGraph", ToolDescriptions.bam_to_bedgraph_description, Class.forName("scriptmanager.window_interface.BAM_Format_Converter.BAMtobedGraphWindow"))); + // SAMtoFASTQ + pnlBamConvert.add(initializeToolPanel("BAM to FASTQ", ToolDescriptions.sam_to_fastq_description, + Class.forName("scriptmanager.window_interface.BAM_Format_Converter.SamtoFastqWindow"))); + + // SAMFormatConverter + pnlBamConvert.add(initializeToolPanel("SAM to BAM or BAM to SAM", ToolDescriptions.sam_to_fastq_description, + Class.forName("scriptmanager.window_interface.BAM_Format_Converter.SamFormatConverterWindow"))); + // ======== File_Utilities ======== JPanel pnlFileUtility = new JPanel(); BoxLayout bl_pnlFileUtility = new BoxLayout(pnlFileUtility, BoxLayout.PAGE_AXIS); diff --git a/src/main/java/scriptmanager/objects/ToolDescriptions.java b/src/main/java/scriptmanager/objects/ToolDescriptions.java index ef21db08..b30c1a47 100644 --- a/src/main/java/scriptmanager/objects/ToolDescriptions.java +++ b/src/main/java/scriptmanager/objects/ToolDescriptions.java @@ -33,6 +33,7 @@ public class ToolDescriptions { public static final String se_stat_description = "Output BAM Header including alignment statistics and parameters given any indexed (BAI) BAM File."; public static final String pe_stat_description = "Generates Insert-size Histogram statistics (GEO requirement) and outputs BAM Header including alignment statistics and parameters given a sorted and indexed (BAI) paired-end BAM File."; public static final String bam_correlation_description = "Genome-Genome correlations for replicate comparisons given multiple sorted and indexed (BAI) BAM files."; + public static final String collect_base_distribution_by_cycle_description = "Chart the nucleotide distribution per cycle in a BAM file"; public static final String archtex_crosscorrelation_description = ("Calculate optimal tag shift based on ArchTEx implementation (PMID:22302569)"); // BAM Manipulation @@ -41,12 +42,19 @@ public class ToolDescriptions { public static final String remove_duplicates_description = "Removes duplicate reads in Paired-End sequencing given identical 5' read locations. RAM intensive process. If program freezes, increase JAVA heap size."; //* public static final String merge_bam_description = "Merges Multiple BAM files into single BAM file. Sorting is performed automatically. RAM intensive process. If program freezes, increase JAVA heap size."; //* public static final String filter_pip_seq_description = "Filter BAM file by -1 nucleotide. Requires genome FASTA file."; + public static final String downsample_sam_description = "Downsample a BAM file to a specified percentage or read count of deterministically random reads."; + public static final String validate_sam_file_description = "Validate SAM/BAM files comprehensively, ensuring adherence to the SAM format specification and detecting errors or inconsistencies in alignment data."; + public static final String normalize_fasta_description = "Reduce redundant sequences and normalize read coverage in a FASTA file, improving downstream analysis accuracy"; + public static final String filter_sam_reads_description = "Filter BAM files by applying user-defined filters to include or exclude specific reads based on read lists or genomic intervals"; + public static final String add_comments_to_bam_description = "Adds comments to the header of a BAM file."; // BAM Format Converter public static final String bam_to_scidx_description = "Convert BAM file to scIDX file."; public static final String bam_to_gff_description = "Convert BAM file to GFF file."; public static final String bam_to_bed_description = "Convert BAM file to BED file."; public static final String bam_to_bedgraph_description = "Convert BAM file to bedGraph file."; + public static final String sam_to_fastq_description = "Convert BAM file to FASTQ file"; + public static final String sam_format_converter_description = "Convert SAM file to Bam file or Bam file to Sam file"; // File Utilities public static final String md5checksum_description = "Calculate MD5 checksum for files."; @@ -85,7 +93,6 @@ public class ToolDescriptions { public static final String aggregate_data_description = "Compile data from tab-delimited file into matrix according to user-specified metric."; public static final String transpose_matrix_description = "Interchange the rows and columns of tab-delimited matrix data."; - // Sequence Analysis public static final String fasta_extract_description = "Generate FASTA file from indexed Genome FASTA file and BED file. Script will generate FAI index if not present in Genome FASTA folder."; public static final String randomize_fasta_description = "Randomize FASTA sequence for each input entry."; @@ -101,4 +108,6 @@ public class ToolDescriptions { public static final String composite_description = "Generate a Composite Plot PNG from composite data like the output in TagPileup"; public static final String label_heatmap_description = "Create an SVG label for heatmap inputs"; + // Whether or not to log legacy Picard commands + public static final boolean picard_legacy_commends = true; } diff --git a/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamFormatConverterWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamFormatConverterWrapper.java new file mode 100644 index 00000000..6b46f7f9 --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamFormatConverterWrapper.java @@ -0,0 +1,53 @@ +package scriptmanager.scripts.BAM_Format_Converter; +import htsjdk.samtools.SAMException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * @see scriptmanager.window_interface.BAM_Format_Converter.SamFormatConverterWindow + * This code runs the Picard tool SamFormatConverter + * It can swap a SAM file to a BAM file and vice versa + */ + +public class SamFormatConverterWrapper { + /** + * @param input the BAM/SAM file to be converted + * @param output the output BAM/SAM file + * + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output) throws IOException, SAMException { + System.out.println("Converting file..."); + // Converts the SAM/BAM file to fastq + final picard.sam.SamFormatConverter samFormatConverter = new picard.sam.SamFormatConverter(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + samFormatConverter.instanceMain(args.toArray(new String[args.size()])); + System.out.println("File converted"); + } + + /** + * Reconstruct CLI command + * + * @param input the BAM/SAM file to be converted + * @param output the output BAM/SAM file + */ + public static String getCLIcommand(File input, File output) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.SamFormatConverter().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamtoFastqWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamtoFastqWrapper.java new file mode 100644 index 00000000..4aeaffd6 --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Format_Converter/SamtoFastqWrapper.java @@ -0,0 +1,77 @@ +package scriptmanager.scripts.BAM_Format_Converter; +import htsjdk.samtools.SAMException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * @see scriptmanager.window_interface.BAM_Format_Converter.SamtoFastqWindow + * This code runs the Picard tool SamtoFastq + */ + +public class SamtoFastqWrapper { + /** + * @param input the BAM/SAM file to be converted + * @param output the output fastq file + * @param compress a boolean to determine whether to compress the output or not + * default = false = do not compress + * @param perRG a boolean to determine whether to output per read group. Compress does this as well + * @param outputDir the output directory + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output, boolean compress, boolean perRG, File outputDir) throws IOException, SAMException { + + System.out.println("Converting file..."); + // Converts the SAM/BAM file to fastq + final picard.sam.SamToFastq samToFastq = new picard.sam.SamToFastq(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + if (compress) { + args.add("OUTPUT_DIR=" + outputDir.getCanonicalPath()); + args.add("COMPRESS_OUTPUTS_PER_RG=" + true); + } else if (perRG) { + args.add("OUTPUT_DIR=" + outputDir.getCanonicalPath()); + args.add("OUTPUT_PER_RG=" + true); + } else { + args.add("FASTQ=" + output.getAbsolutePath()); + } + samToFastq.instanceMain(args.toArray(new String[args.size()])); + System.out.println("File converted"); + } + + /** + * Reconstruct CLI command + * + * @param input the BAM/SAM file to be converted + * @param output the output fastq file + * @param compress a boolean to determine whether to compress the output or not + * default = false = do not compress + * @param perRG a boolean to determine whether to output per read group. Compress does this as well + * @param outputDir the output directory + * @throws IOException + */ + public static String getCLIcommand(File input, File output, boolean compress, boolean perRG, File outputDir) throws IOException { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.SamToFastq().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + if (compress) { + args.add("OUTPUT_DIR=" + outputDir.getCanonicalPath()); + args.add("COMPRESS_OUTPUTS_PER_RG=" + true); + } else if (perRG) { + args.add("OUTPUT_DIR=" + outputDir.getCanonicalPath()); + args.add("OUTPUT_PER_RG=" + true); + } else { + args.add("FASTQ=" + output.getAbsolutePath()); + } + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/AddCommentsToBamWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/AddCommentsToBamWrapper.java new file mode 100644 index 00000000..95237775 --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/AddCommentsToBamWrapper.java @@ -0,0 +1,82 @@ +package scriptmanager.scripts.BAM_Manipulation; + +import htsjdk.samtools.BamFileIoUtils; +import htsjdk.samtools.SAMException; +import htsjdk.samtools.SAMProgramRecord; +import htsjdk.samtools.SamReader; +import htsjdk.samtools.SamReaderFactory; +import picard.cmdline.CommandLineSyntaxTranslater; +import picard.sam.AddCommentsToBam; +import scriptmanager.objects.ToolDescriptions; +import scriptmanager.util.BAMUtilities; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * This is the Wrapper class for the AddCommentsToBam Picard tool + * @see scriptmanager.window_interface.BAM_Manipulation.AddCommentsToBamWindow + */ +public class AddCommentsToBamWrapper { + /** + * @param input the bam file to add comments to + * @param output the output file + * + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output, ArrayList comments) throws IOException, SAMException { + System.out.println("Add Comments To Bam"); + + final picard.sam.AddCommentsToBam addComments = new picard.sam.AddCommentsToBam(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + for (String c: comments){ + args.add("C=" + c); + } + addComments.instanceMain(args.toArray(new String[args.size()])); + + // Copy output + File temp = new File(output.toPath() + "copy"); + Files.copy(output.toPath(), new PrintStream(temp)); + // Create and add new record + SamReader reader = SamReaderFactory.makeDefault().open(temp); + String command = AddCommentsToBamWrapper.getCLIcommand(input, output, comments); + SAMProgramRecord newRecord = BAMUtilities.getPGRecord(reader.getFileHeader(), addComments.getClass().getSimpleName(), command, addComments.getVersion()); + reader.getFileHeader().addProgramRecord(newRecord); + BamFileIoUtils.reheaderBamFile(reader.getFileHeader(), temp, output, false, false); + // Delete copy + temp.delete(); + System.out.println("SAM/BAM file downsampled"); + + System.out.println("Comments Added"); + } + + /** + * Reconstruct CLI command + * + * @param input the bam file to add comments to + * @param output the output file + */ + public static String getCLIcommand(File input, File output, ArrayList comments) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.AddCommentsToBam().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + for (String c: comments){ + args.add("C=" + c); + } + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/DownsampleSamWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/DownsampleSamWrapper.java new file mode 100644 index 00000000..e449848f --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/DownsampleSamWrapper.java @@ -0,0 +1,90 @@ +package scriptmanager.scripts.BAM_Manipulation; + +import htsjdk.samtools.BamFileIoUtils; +import htsjdk.samtools.SAMException; +import htsjdk.samtools.SAMProgramRecord; +import htsjdk.samtools.SamReader; +import htsjdk.samtools.SamReaderFactory; +import scriptmanager.util.BAMUtilities; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; +/** + * @author Erik Pavloski + * @see scriptmanager.window_interface.BAM_Manipulation.DownsampleSamWindow + * This code runs the Picard tool DownsampleSam + * + * + */ +public class DownsampleSamWrapper { + /** + * The following code uses Picard's downsampleSAM tool to shink the BAM/SAM file + * and retain a random subset of the reads based on the probability parameter + * Output reads = (probability) * (input reads) + * + * @param input the BAM/SAM file to be downsampled + * @param output the downsampled file + * @param probability the probability of keeping reads. + * 0.5 default -> 50% reduction in data. + * Smaller number -> less data once down-sampled + * @param seed the custom seed that the user entered. + * Defaults to null if no custom seed is entered which just spools a random seed + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output, double probability, Long seed) throws IOException, SAMException { + System.out.println("Downsampling SAM/BAM file..."); + + // Downsamples the SAM/BAM file + final picard.sam.DownsampleSam downsampleSam = new picard.sam.DownsampleSam(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + args.add("PROBABILITY=" + probability); + args.add("RANDOM_SEED=" + seed); + downsampleSam.instanceMain(args.toArray(new String[args.size()])); + + // Copy output + File temp = new File(output.toPath() + "copy"); + Files.copy(output.toPath(), new PrintStream(temp)); + // Create and add new record + SamReader reader = SamReaderFactory.makeDefault().open(temp); + String command = DownsampleSamWrapper.getCLIcommand(input, output, probability, seed); + SAMProgramRecord newRecord = BAMUtilities.getPGRecord(reader.getFileHeader(), downsampleSam.getClass().getSimpleName(), command, downsampleSam.getVersion()); + reader.getFileHeader().addProgramRecord(newRecord); + BamFileIoUtils.reheaderBamFile(reader.getFileHeader(), temp, output, false, false); + // Delete copy + temp.delete(); + System.out.println("SAM/BAM file downsampled"); + } + + /** + * Reconstruct CLI command + * + * @param input the BAM/SAM file to be downsampled + * @param output the downsampled file + * @param probability the probability of keeping reads. + * 0.5 default -> 50% reduction in data. + * Smaller number -> less data once down-sampled + * @param seed the custom seed that the user entered. + * Defaults to null if no custom seed is entered which just spools a random seed + */ + public static String getCLIcommand(File input, File output, double probability, Long seed) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.DownsampleSam().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + args.add("PROBABILITY=" + probability); + args.add("RANDOM_SEED=" + seed); + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterSamReadsWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterSamReadsWrapper.java new file mode 100644 index 00000000..8672c703 --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterSamReadsWrapper.java @@ -0,0 +1,78 @@ +package scriptmanager.scripts.BAM_Manipulation; + +import htsjdk.samtools.SAMException; +import picard.sam.FilterSamReads; + +import java.io.IOException; +import java.io.File; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * This code runs the FilterSamReads Picard tool + * @see scriptmanager.window_interface.BAM_Manipulation.FilterSamReadsWindow + */ +public class FilterSamReadsWrapper { + /** + * @param input the file to be filtered + * @param output the file to be outputted + * @param filter which filter the user wants to use can be includeReadList or includePairIntervals + * true == includeReadList + * false == includePairIntervals + * @param readListFile the txt file output for the read list if that is the chosen filter + * @param intervalList the list of interval output file if that is the desired filter + * + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output, boolean filter, File readListFile, File intervalList) throws IOException, SAMException { + System.out.println("Filtering Reads"); + + final picard.sam.FilterSamReads filterSamReads = new FilterSamReads(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + if (filter) { + args.add("READ_LIST_FILE=" + readListFile.getAbsolutePath()); + args.add("FILTER=includeReadList"); + } else { + args.add("INTERVAL_LIST=" + intervalList.getAbsolutePath()); + args.add("FILTER=includePairedIntervals"); + } + filterSamReads.instanceMain(args.toArray(new String[args.size()])); + + System.out.println("Filtering Complete"); + } + + /** + * Reconstruct CLI command + * + * @param input the file to be filtered + * @param output the file to be outputted + * @param filter which filter the user wants to use can be includeReadList or includePairIntervals + * true == includeReadList + * false == includePairIntervals + * @param readListFile the txt file output for the read list if that is the chosen filter + * @param intervalList the list of interval output file if that is the desired filter + */ + public static String getCLIcommand(File input, File output, boolean filter, File readListFile, File intervalList) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.FilterSamReads().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + if (filter) { + args.add("READ_LIST_FILE=" + readListFile.getAbsolutePath()); + args.add("FILTER=includeReadList"); + } else { + args.add("INTERVAL_LIST=" + intervalList.getAbsolutePath()); + args.add("FILTER=includePairedIntervals"); + } + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterforPIPseq.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterforPIPseq.java index 6dc71f6b..ba45dc31 100644 --- a/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterforPIPseq.java +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/FilterforPIPseq.java @@ -4,6 +4,7 @@ import htsjdk.samtools.SAMFileHeader; import htsjdk.samtools.SAMFileWriter; import htsjdk.samtools.SAMFileWriterFactory; +import htsjdk.samtools.SAMProgramRecord; import htsjdk.samtools.SAMRecord; import htsjdk.samtools.SAMSequenceRecord; import htsjdk.samtools.SamReader; @@ -16,7 +17,11 @@ import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.util.ArrayList; +import scriptmanager.cli.BAM_Manipulation.FilterforPIPseqCLI; +import scriptmanager.objects.ToolDescriptions; +import scriptmanager.util.BAMUtilities; import scriptmanager.util.FASTAUtilities; /** @@ -70,8 +75,11 @@ public void run() throws IOException, InterruptedException { IOUtil.assertFileIsWritable(output); final SamReader reader = SamReaderFactory.makeDefault().open(bamFile); reader.getFileHeader().setSortOrder(SAMFileHeader.SortOrder.coordinate); - final SAMFileWriter writer = new SAMFileWriterFactory().makeSAMOrBAMWriter(reader.getFileHeader(), false, - output); + // Append @PG annotation to header and instantiate writer + String command = FilterforPIPseqCLI.getCLIcommand(bamFile, genome, output, SEQ); + SAMProgramRecord record = BAMUtilities.getPGRecord(reader.getFileHeader(), "scriptmanager", command, ToolDescriptions.VERSION); + reader.getFileHeader().addProgramRecord(record); + final SAMFileWriter writer = new SAMFileWriterFactory().makeSAMOrBAMWriter(reader.getFileHeader(), false, output); printBoth(bamFile.getName()); // output file name to textarea diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/NormalizeFastaWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/NormalizeFastaWrapper.java new file mode 100644 index 00000000..8874589d --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/NormalizeFastaWrapper.java @@ -0,0 +1,54 @@ +package scriptmanager.scripts.BAM_Manipulation; + +import htsjdk.samtools.SAMException; +import picard.reference.NormalizeFasta; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * This is the Wrapper class for the NormalizeFasta Picard tool + * @see scriptmanager.window_interface.BAM_Manipulation.NormalizeFastaWindow + */ +public class NormalizeFastaWrapper { + /** + * @param input the file to be filtered + * @param output the file to be outputted + * + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output) throws IOException, SAMException { + System.out.println("Normalizing FASTA file"); + + final picard.reference.NormalizeFasta normalizeFasta = new picard.reference.NormalizeFasta(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + normalizeFasta.instanceMain(args.toArray(new String[args.size()])); + + System.out.println("File Normalized"); + } + + /** + * Reconstruct CLI command + * + * @param input the file to be filtered + * @param output the file to be outputted + */ + public static String getCLIcommand(File input, File output) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.reference.NormalizeFasta().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Manipulation/ValidateSamWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Manipulation/ValidateSamWrapper.java new file mode 100644 index 00000000..54fb4b9c --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Manipulation/ValidateSamWrapper.java @@ -0,0 +1,75 @@ +package scriptmanager.scripts.BAM_Manipulation; +import htsjdk.samtools.SAMException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * @see scriptmanager.window_interface.BAM_Manipulation.ValidateSamWindow + * This code runs the picard tool validateSAMFile + * + */ + + +public class ValidateSamWrapper { + /** + * + * @param input The BAM/SAM file to be Validated + * @param output the output of the validation + * @param mode Allows the user to select verbose or summary mode. True = verbose - false = summary + * @param referenceGenome Allows the user to add reference sequence if needed + * @param maxOutput Allows customization of the maximum number of outputs in verbose mode + * + * @throws IOException + * @throws SAMException + * + */ + public static void run(File input, File output, boolean mode, File referenceGenome, int maxOutput) throws IOException, SAMException{ + + System.out.println("Validating SAM/BAM file..."); + // Validates the SAM/BAM file + final picard.sam.ValidateSamFile validateSam = new picard.sam.ValidateSamFile(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + String modeString = mode ? "VERBOSE" : "SUMMARY"; + args.add("MODE=" + modeString); + args.add("MAX_OUTPUT=" + maxOutput); + if (referenceGenome != null) { + args.add("REFERENCE_SEQUENCE=" + referenceGenome.getAbsolutePath()); + } + validateSam.instanceMain(args.toArray(new String[args.size()])); + System.out.println("SAM/BAM file validated"); + } + + /** + * Reconstruct CLI command + * + * @param input The BAM/SAM file to be Validated + * @param output the output of the validation + * @param mode Allows the user to select verbose or summary mode. True = verbose - false = summary + * @param referenceGenome Allows the user to add reference sequence if needed + * @param maxOutput Allows customization of the maximum number of outputs in verbose mode + */ + public static String getCLIcommand(File input, File output, boolean mode, File referenceGenome, int maxOutput) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.sam.ValidateSamFile().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + String modeString = mode ? "VERBOSE" : "SUMMARY"; + args.add("MODE=" + modeString); + args.add("MAX_OUTPUT=" + maxOutput); + if (referenceGenome != null) { + args.add("REFERENCE_SEQUENCE=" + referenceGenome.getAbsolutePath()); + } + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/scripts/BAM_Statistics/CollectBaseDistributionByCycleWrapper.java b/src/main/java/scriptmanager/scripts/BAM_Statistics/CollectBaseDistributionByCycleWrapper.java new file mode 100644 index 00000000..16fb8df7 --- /dev/null +++ b/src/main/java/scriptmanager/scripts/BAM_Statistics/CollectBaseDistributionByCycleWrapper.java @@ -0,0 +1,57 @@ +package scriptmanager.scripts.BAM_Statistics; +import htsjdk.samtools.SAMException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.broadinstitute.barclay.argparser.CommandLineParser; + +/** + * @author Erik Pavloski + * @see scriptmanager.window_interface.BAM_Statistics.CollectBaseDistributionByCycleWindow + * This code runs the Picard tool called CollectBaseDistributionByCycle + */ + +public class CollectBaseDistributionByCycleWrapper { + /** + * @param input the bam file to be analysed + * @param output the output text file + * @param chartOutput the pdf chart output + * + * @throws IOException + * @throws SAMException + */ + public static void run(File input, File output, File chartOutput) throws IOException, SAMException { + System.out.println("Analysing file..."); + + // Analysis of the file + final picard.analysis.CollectBaseDistributionByCycle collectBaseDistributionByCycle = new picard.analysis.CollectBaseDistributionByCycle(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + args.add("CHART_OUTPUT=" + chartOutput.getAbsolutePath()); + collectBaseDistributionByCycle.instanceMain(args.toArray(new String[args.size()])); + System.out.println("Analysis complete"); + } + + /** + * Reconstruct CLI command + * + * @param input the bam file to be analysed + * @param output the output text file + * @param chartOutput the pdf chart output + */ + public static String getCLIcommand(File input, File output, File chartOutput) { + String command = "java -jar $PICARD "; + final CommandLineParser parser = new picard.analysis.CollectBaseDistributionByCycle().getCommandLineParser(); + final ArrayList args = new ArrayList<>(); + args.add("INPUT=" + input.getAbsolutePath()); + args.add("OUTPUT=" + output.getAbsolutePath()); + args.add("CHART_OUTPUT=" + chartOutput.getAbsolutePath()); + String[] argv = args.toArray(new String[args.size()]); + parser.parseArguments(System.err, argv); + command += parser.getCommandLine(); + return command; + } +} diff --git a/src/main/java/scriptmanager/util/BAMUtilities.java b/src/main/java/scriptmanager/util/BAMUtilities.java index 305c1485..8cc289bd 100644 --- a/src/main/java/scriptmanager/util/BAMUtilities.java +++ b/src/main/java/scriptmanager/util/BAMUtilities.java @@ -10,6 +10,8 @@ import java.util.Scanner; import htsjdk.samtools.AbstractBAMFileIndex; +import htsjdk.samtools.SAMFileHeader; +import htsjdk.samtools.SAMProgramRecord; import htsjdk.samtools.SAMRecord; import htsjdk.samtools.SAMSequenceRecord; import htsjdk.samtools.SamReader; @@ -19,6 +21,7 @@ import scriptmanager.objects.Exceptions.OptionException; import scriptmanager.objects.PileupParameters; +import scriptmanager.objects.ToolDescriptions; import scriptmanager.objects.CoordinateObjects.BEDCoord; /** @@ -287,4 +290,21 @@ private static HashMap> loadBlacklist(File BLACKFile scan.close(); return BLACKLIST; } + + /** + * Create program record with non-overlapping ID + * @param header Original header + * @param programName Name of the application + * @param command CLI command + * @param version Version of tool/command + * @return Program record with a non-overlapping ID + */ + public static SAMProgramRecord getPGRecord(final SAMFileHeader header, String programName, String command, String version) { + final SAMFileHeader.PgIdGenerator pgIdGenerator = new SAMFileHeader.PgIdGenerator(header); + final SAMProgramRecord programRecord = new SAMProgramRecord(pgIdGenerator.getNonCollidingId(programName)); + programRecord.setProgramName(programName); + programRecord.setCommandLine(command); + programRecord.setProgramVersion(version); + return programRecord; + } } diff --git a/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamFormatConverterWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamFormatConverterWindow.java new file mode 100644 index 00000000..6ab30d20 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamFormatConverterWindow.java @@ -0,0 +1,237 @@ +package scriptmanager.window_interface.BAM_Format_Converter; + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Format_Converter.SamFormatConverterWrapper; +import scriptmanager.scripts.BAM_Format_Converter.SamtoFastqWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +public class SamFormatConverterWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + + private JButton btnLoadBam; + private JButton btnLoadSam; + private JButton btnRemoveBam; + private JButton btnOutput; + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JButton btnConvert; + private JProgressBar progressBar; + public SamFormatConverterWindow.Task task; + + class Task extends SwingWorker { + + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for(int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (BAMFiles.get(x).getName().contains("sam")) { + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_converted.bam"); + } else { + OUTPUT = new File(NAME[0] + "_converted.bam"); + } + } else { + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_converted.sam"); + } else { + OUTPUT = new File(NAME[0] + "_converted.sam"); + } + } + // Initialize log item + String command = SamFormatConverterWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Execute Picard wrapper + SamFormatConverterWrapper.run(BAMFiles.get(x), OUTPUT); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Conversion Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + public SamFormatConverterWindow() { + setTitle("Convert SAM to BAM or BAM to SAM"); + setBounds(125, 125, 480, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + btnLoadSam = new JButton("Load SAM Files"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadSam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 30, SpringLayout.NORTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 30, SpringLayout.NORTH, btnLoadSam); + + btnLoadSam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"sam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadSam); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 150, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -150, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnConvert = new JButton("Convert"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnConvert, 2, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnConvert, -5, SpringLayout.EAST, contentPane); + contentPane.add(btnConvert); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + + + btnConvert.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + task = new Task(); + task.addPropertyChangeListener(SamFormatConverterWindow.this); + task.execute(); + } + }); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamtoFastqWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamtoFastqWindow.java new file mode 100644 index 00000000..bbffbdd3 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Format_Converter/SamtoFastqWindow.java @@ -0,0 +1,246 @@ +package scriptmanager.window_interface.BAM_Format_Converter; + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Format_Converter.SamtoFastqWrapper; +import scriptmanager.scripts.BAM_Manipulation.ValidateSamWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +public class SamtoFastqWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + + private JButton btnLoad; + + private JButton btnRemoveBam; + private JButton btnOutput; + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JCheckBox chckbxCompress; + private JCheckBox chckbxPerRG; + private JButton btnConvert; + private boolean compress; + private boolean perRG; + private JProgressBar progressBar; + public SamtoFastqWindow.Task task; + + class Task extends SwingWorker { + + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for(int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_converted.fastq"); + } else { + OUTPUT = new File(NAME[0] + "_converted.fastq"); + } + compress = chckbxCompress.isSelected(); + perRG = chckbxPerRG.isSelected(); + // Initialize log item + String command = SamtoFastqWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, compress, perRG, OUT_DIR); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Execute Picard wrapper + SamtoFastqWrapper.run(BAMFiles.get(x), OUTPUT, compress, perRG, OUT_DIR); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Conversion Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + public SamtoFastqWindow(){ + setTitle("Convert BAM to Fastq"); + setBounds(125, 125, 480, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoad = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoad, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoad); + + btnLoad.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoad); + + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoad, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + chckbxCompress = new JCheckBox("Compress output?"); + sl_contentPane.putConstraint(SpringLayout.WEST, chckbxCompress, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxCompress, 10, SpringLayout.SOUTH, scrollPane); + chckbxCompress.setSelected(false); + contentPane.add(chckbxCompress); + + chckbxCompress.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (chckbxCompress.isSelected()) { + chckbxPerRG.setSelected(false); + } + } + }); + + chckbxPerRG = new JCheckBox("Output per read group?"); + sl_contentPane.putConstraint(SpringLayout.WEST, chckbxPerRG, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxPerRG, 30, SpringLayout.SOUTH, scrollPane); + chckbxPerRG.setSelected(false); + contentPane.add(chckbxPerRG); + + chckbxPerRG.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (chckbxPerRG.isSelected()) { + chckbxCompress.setSelected(false); + } + } + }); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 150, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -150, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnConvert = new JButton("Convert"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnConvert, 2, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnConvert, -5, SpringLayout.EAST, contentPane); + contentPane.add(btnConvert); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + + + btnConvert.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + task = new Task(); + task.addPropertyChangeListener(SamtoFastqWindow.this); + task.execute(); + } + }); + + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Manipulation/AddCommentsToBamWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/AddCommentsToBamWindow.java new file mode 100644 index 00000000..6b0deb9e --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/AddCommentsToBamWindow.java @@ -0,0 +1,271 @@ +package scriptmanager.window_interface.BAM_Manipulation; + +import htsjdk.samtools.SAMException; +import picard.sam.AddCommentsToBam; +import scriptmanager.cli.BAM_Format_Converter.BAMtobedGraphCLI; +import scriptmanager.objects.LogItem; +import scriptmanager.objects.PasteableTable; +import scriptmanager.scripts.BAM_Manipulation.AddCommentsToBamWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Vector; +import java.util.ArrayList; +import java.util.Date; + +/** + * @author Erik Pavloski + * This is the window class for the AddCommentsToBam Picard tool + * @see scriptmanager.scripts.BAM_Manipulation.AddCommentsToBamWrapper + */ +public class AddCommentsToBamWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + + private JButton btnLoadBam; + private JButton btnRemoveBam; + private JButton btnAddComment; + private JButton btnRemoveComment; + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JButton btnOutput; + private JButton btnComment; + private JProgressBar progressBar; + private DefaultTableModel commentTable; + public Task task; + class Task extends SwingWorker { + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + ArrayList comments = new ArrayList(); + for (int i = 0; i < commentTable.getRowCount(); i++){ + comments.add(commentTable.getValueAt(i, 0).toString()); + } + if (comments.size() == 0) { + JOptionPane.showMessageDialog(null, "No Comments Provided!!!"); + } else { + for (int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_commented.bam"); + } else { + OUTPUT = new File(NAME[0] + "_commented.bam"); + } + // Initialize log item + String command = AddCommentsToBamWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, comments); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Run Wrapper + AddCommentsToBamWrapper.run(BAMFiles.get(x), OUTPUT, comments); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Comments Added"); + } + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + + public AddCommentsToBamWindow() { + setTitle("Add Comments to BAM File"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(125, 125, 580, 550); + + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, 200, SpringLayout.NORTH, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel<>(); + final JList listExp = new JList<>(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 0, SpringLayout.WEST, scrollPane); + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + btnAddComment = new JButton("Add Comment"); + btnAddComment.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + commentTable.addRow(new Object[] { "" }); + } + } + ); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnAddComment, 6, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, btnAddComment, 0, SpringLayout.WEST, scrollPane); + contentPane.add(btnAddComment); + + btnRemoveComment = new JButton("Remove Comment"); + btnRemoveComment.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + commentTable.removeRow(commentTable.getRowCount() - 1); + } + } + ); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveComment, 6, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveComment, 0, SpringLayout.EAST, scrollPane); + contentPane.add(btnRemoveComment); + + String[] TableHeader = { "Comments" }; + commentTable = new DefaultTableModel(null, TableHeader); + JTable tableScale = new JTable(commentTable); + // Allow for the selection of multiple OR individual cells across either rows or columns + tableScale.setCellSelectionEnabled(true); + tableScale.setColumnSelectionAllowed(true); + tableScale.setRowSelectionAllowed(true); + DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); + centerRenderer.setHorizontalAlignment( JLabel.CENTER ); + tableScale.setDefaultRenderer(Object.class, centerRenderer); + @SuppressWarnings("unused") + PasteableTable myAd = new PasteableTable(tableScale); + + scrollPane = new JScrollPane(tableScale); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnRemoveComment); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 146, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -146, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, -30, SpringLayout.SOUTH, contentPane); + outputLabel.setFont(new Font("Lucida Grande", Font.BOLD, 13)); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 1, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnComment = new JButton("Write Comments"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnComment, 6, SpringLayout.SOUTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.WEST, btnComment, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnComment, -200, SpringLayout.EAST, contentPane); + btnComment.addActionListener(e -> { + task = new Task(); + task.addPropertyChangeListener(AddCommentsToBamWindow.this); + task.execute(); + }); + contentPane.add(btnComment); + + progressBar = new JProgressBar(); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, 6, SpringLayout.SOUTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + } + + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when the task's progress changes + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Manipulation/DownsampleSamWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/DownsampleSamWindow.java new file mode 100644 index 00000000..76f213c1 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/DownsampleSamWindow.java @@ -0,0 +1,382 @@ +package scriptmanager.window_interface.BAM_Manipulation; + +import htsjdk.samtools.*; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Manipulation.AddCommentsToBamWrapper; +import scriptmanager.scripts.BAM_Manipulation.DownsampleSamWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Iterator; +import java.util.Vector; + +/** + * @author Erik Pavloski + * This is the window class for DownsampleSamWrapper + * @see scriptmanager.scripts.BAM_Manipulation.DownsampleSamWrapper + */ +public class DownsampleSamWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private JButton btnLoadBam; + private JButton btnRemoveBam; + private JButton btnDownSample; + private Long desiredReadCount; + private Long totalreadCount = Long.valueOf(0); + + private JButton btnOutput; + + private JLabel outputLabel; + + private JLabel lblDefaultToLocal; + + private JCheckBox useCustomSeedBox; + private JTextField seedField; + + + private Long seed; + private JCheckBox setReadCountBox; + private JTextField readCountField; + private File OUT_DIR = null; + private JButton btnLoadSam; + + private JProgressBar progressBar; + public Task task; + + + + class Task extends SwingWorker { + double probability; + + public Task (double probability) { + this.probability = probability; + } + + @Override + public Void doInBackground() throws IOException{ + setProgress(0); + LogItem old_li = null; + try { + for (int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_downsampled.bam"); + } else { + OUTPUT = new File(NAME[0] + "_downsampled.bam"); + } + if (probability > 1 || probability < 0) { + JOptionPane.showMessageDialog(null, "Must enter a value between 0 and 1"); + } + + // Open BAM file for reading + SamReader reader = SamReaderFactory.makeDefault().open(BAMFiles.get(x)); + + // Get the header and record iterator + SAMFileHeader header = reader.getFileHeader(); + Iterator iterator = reader.iterator(); + + // Count the number of reads + while (iterator.hasNext()) { + iterator.next(); + totalreadCount++; + } + + // Close the reader + reader.close(); + + // Initialize log item + String command = DownsampleSamWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, probability, seed); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + + // Execute picard wrapper + DownsampleSamWrapper.run(BAMFiles.get(x), OUTPUT, probability, seed); + // Update Progress + int percentComplete = (int) (((double) (x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Downsampling Complete"); + return null; + } catch (SAMException sme) { + JOptionPane.showMessageDialog(null, sme.getMessage()); + return null; + } + } + + public void done() { + massXable(contentPane, true); + setCursor(null); + } + } + + public DownsampleSamWindow() { + setTitle("Downsample SAM/BAM File"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + setBounds(125, 125, 580, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + + btnLoadSam = new JButton("Load SAM Files"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadSam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 30, SpringLayout.NORTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 30, SpringLayout.NORTH, btnLoadSam); + + btnLoadSam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"sam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadSam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + + JLabel probabilityLabel = new JLabel("Probability: "); + sl_contentPane.putConstraint(SpringLayout.NORTH, probabilityLabel, 10, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, probabilityLabel, 0, SpringLayout.WEST, scrollPane); + contentPane.add(probabilityLabel); + + JTextField probabilityField = new JTextField("0.5"); + probabilityField.setPreferredSize(new Dimension(50, probabilityField.getPreferredSize().height)); + sl_contentPane.putConstraint(SpringLayout.NORTH, probabilityField, 10, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, probabilityField, 5, SpringLayout.EAST, probabilityLabel); + contentPane.add(probabilityField); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -200, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + useCustomSeedBox = new JCheckBox("Custom Seed?"); + sl_contentPane.putConstraint(SpringLayout.EAST, useCustomSeedBox, 0, SpringLayout.EAST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, useCustomSeedBox, 50, SpringLayout.EAST, btnOutput); + sl_contentPane.putConstraint(SpringLayout.NORTH, useCustomSeedBox, 5, SpringLayout.SOUTH, scrollPane); + contentPane.add(useCustomSeedBox); + + useCustomSeedBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + boolean isChecked = useCustomSeedBox.isSelected(); + seedField.setEnabled(isChecked); + seedField.setText(""); + if (!isChecked) { + seedField.setText("Enter Custom Seed"); + seed = null; + } + } + }); + + seedField = new JTextField("Enter Custom Seed"); + seedField.setPreferredSize(new Dimension(65, seedField.getPreferredSize().height)); + sl_contentPane.putConstraint(SpringLayout.EAST, seedField, 0, SpringLayout.EAST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, seedField, 50, SpringLayout.EAST, btnOutput); + sl_contentPane.putConstraint(SpringLayout.NORTH, seedField, 30, SpringLayout.SOUTH, scrollPane); + contentPane.add(seedField); + + seedField.setEnabled(false); + + setReadCountBox = new JCheckBox("Set # of reads?"); + setReadCountBox.setSize(new Dimension(120, setReadCountBox.getPreferredSize().height)); + sl_contentPane.putConstraint(SpringLayout.NORTH, setReadCountBox, 55,SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, setReadCountBox, 167, SpringLayout.WEST, contentPane); + contentPane.add(setReadCountBox); + + setReadCountBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + boolean isChecked = setReadCountBox.isSelected(); + readCountField.setEnabled(isChecked); + probabilityField.setEnabled(!isChecked); + readCountField.setText(""); + if (!isChecked) { + readCountField.setText("Enter # of Reads"); + } + } + }); + + + + readCountField = new JTextField("Enter # of Reads"); + readCountField.setPreferredSize(new Dimension(120, readCountField.getPreferredSize().height)); + sl_contentPane.putConstraint(SpringLayout.NORTH, readCountField, 58,SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, readCountField, 5, SpringLayout.EAST, setReadCountBox); + contentPane.add(readCountField); + + readCountField.setEnabled(false); + + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, -30, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 1, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnDownSample = new JButton("Downsample"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnDownSample, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnDownSample, 0, SpringLayout.SOUTH, contentPane); + btnDownSample.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + // These lines ensure that the program will run even if the user enters a string or other invalid characters + // The program will just default to 0.5 + double probability = 0.5; + if (setReadCountBox.isSelected()) { + try { + desiredReadCount = Long.parseLong(readCountField.getText()); + // Compare read count to desired read count + if (totalreadCount > desiredReadCount) { + // Set the probability value relative to the desired read count + probability = (double) desiredReadCount / totalreadCount; + } else { + JOptionPane.showMessageDialog(null, "Invalid read count. The entered value is larger than the total number of reads. Defaulting to 0.5 probability"); + } + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(null, "Invalid read count. Please enter an integer value."); + return; + } + } else { + try { + probability = Double.parseDouble(probabilityField.getText()); + } catch (NumberFormatException nfe) { + JOptionPane.showMessageDialog(null, "Must enter a double value between 0 and 1. Due to improper input program will default to 0.5 probability"); + } + } + try { + seed = Long.parseLong(seedField.getText()); + } catch (NumberFormatException nfe) { + seed = null; + } + if (seed != null) { + task = new Task(seed); + } + task = new Task(probability); + task.addPropertyChangeListener(DownsampleSamWindow.this); + task.execute(); + + } + }); + contentPane.add(btnDownSample); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, 3, SpringLayout.NORTH, btnDownSample); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new DownsampleSamWindow().task; + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } + +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Manipulation/FilterSamReadsWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/FilterSamReadsWindow.java new file mode 100644 index 00000000..064f4239 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/FilterSamReadsWindow.java @@ -0,0 +1,261 @@ +package scriptmanager.window_interface.BAM_Manipulation; + + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Manipulation.AddCommentsToBamWrapper; +import scriptmanager.scripts.BAM_Manipulation.BAIIndexer; +import scriptmanager.scripts.BAM_Manipulation.BAMFileSort; +import scriptmanager.scripts.BAM_Manipulation.FilterSamReadsWrapper; +import scriptmanager.scripts.BAM_Manipulation.ValidateSamWrapper; +import scriptmanager.util.FileSelection; +import scriptmanager.window_interface.BAM_Statistics.CollectBaseDistributionByCycleWindow; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +/** + * @author Erik Pavloski + * This is the window class for FilterSamReadsWrapper + * @see scriptmanager.scripts.BAM_Manipulation.FilterSamReadsWrapper + */ +public class FilterSamReadsWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + private File readListFile = null; + private File intervalList = null; + + private JButton btnLoadBam; + private JButton btnRemoveBam; + private JButton btnReadListFile; + private JButton btnIntervalList; + private JButton btnAction; + private JButton btnOutput; + private JCheckBox filterchbx; + + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JProgressBar progressBar; + public Task task; + + class Task extends SwingWorker { + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for (int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_filtered.bam"); + } else { + OUTPUT = new File(NAME[0] + "_filtered.bam"); + } + // Initialize log item + String command = FilterSamReadsWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, filterchbx.isSelected(), readListFile, intervalList); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Execute Picard wrapper + FilterSamReadsWrapper.run(BAMFiles.get(x), OUTPUT, filterchbx.isSelected(), readListFile, intervalList); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Filtering Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + + public FilterSamReadsWindow() { + setTitle("Filter BAM file reads"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + setBounds(125, 125, 580, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -200, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnReadListFile = new JButton("Load Read List"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnReadListFile, 6, SpringLayout.SOUTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.WEST, btnReadListFile, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnReadListFile, 30, SpringLayout.NORTH, btnLoadBam); + btnReadListFile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getFile(fc, "txt"); + if (temp != null) { + readListFile = temp; + } + } + }); + contentPane.add(btnReadListFile); + + btnIntervalList = new JButton("Load Interval List"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnIntervalList, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.WEST, btnIntervalList, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnIntervalList, 60, SpringLayout.NORTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 60, SpringLayout.NORTH, btnIntervalList); + btnIntervalList.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getFile(fc, "interval_list"); + if (temp != null) { + intervalList = temp; + } + } + }); + contentPane.add(btnIntervalList); + + btnAction = new JButton("Filter"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnAction, 30, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnAction, -5, SpringLayout.EAST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 60, SpringLayout.NORTH, btnAction); + contentPane.add(btnAction); + + btnAction.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + task = new Task(); + task.addPropertyChangeListener(FilterSamReadsWindow.this); + task.execute(); + } + }); + + filterchbx = new JCheckBox("Select for include read list or don't select for include pair intervals."); + sl_contentPane.putConstraint(SpringLayout.WEST, filterchbx, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, filterchbx, 30, SpringLayout.SOUTH, scrollPane); + filterchbx.setSelected(false); + contentPane.add(filterchbx); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} + diff --git a/src/main/java/scriptmanager/window_interface/BAM_Manipulation/NormalizeFastaWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/NormalizeFastaWindow.java new file mode 100644 index 00000000..25fb6d4d --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/NormalizeFastaWindow.java @@ -0,0 +1,212 @@ +package scriptmanager.window_interface.BAM_Manipulation; + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Manipulation.AddCommentsToBamWrapper; +import scriptmanager.scripts.BAM_Manipulation.NormalizeFastaWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +/** + * @author Erik Pavloski + * This is the window class for the NormalizeFasta Picard tool + * @see scriptmanager.scripts.BAM_Manipulation.NormalizeFastaWrapper + */ +public class NormalizeFastaWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + + private JButton btnLoadFasta; + private JButton btnRemoveFasta; + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JButton btnOutput; + private JButton btnNormalize; + private JProgressBar progressBar; + public Task task; + class Task extends SwingWorker { + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for (int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_normalized.fasta"); + } else { + OUTPUT = new File(NAME[0] + "_normalized.fasta"); + } + // Initialize log item + String command = NormalizeFastaWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT); + System.err.println(command); + LogItem new_li = new LogItem(command); + // Run Wrapper + NormalizeFastaWrapper.run(BAMFiles.get(x), OUTPUT); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Validation Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + + public NormalizeFastaWindow() { + setTitle("Normalize FASTA File"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + setBounds(125, 125, 580, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadFasta = new JButton("Load FASTA Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadFasta, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadFasta); + + btnLoadFasta.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"fasta"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadFasta); + + btnRemoveFasta = new JButton("Remove FASTA"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadFasta, 0, SpringLayout.NORTH, btnRemoveFasta); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveFasta, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveFasta, -5, SpringLayout.EAST, contentPane); + btnRemoveFasta.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveFasta); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -200, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnNormalize = new JButton("Normalize"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnNormalize, 2, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnNormalize, -5, SpringLayout.EAST, contentPane); + contentPane.add(btnNormalize); + + btnNormalize.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + task = new Task(); + task.addPropertyChangeListener(NormalizeFastaWindow.this); + task.execute(); + } + }); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Manipulation/ValidateSamWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/ValidateSamWindow.java new file mode 100644 index 00000000..686de185 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Manipulation/ValidateSamWindow.java @@ -0,0 +1,324 @@ +package scriptmanager.window_interface.BAM_Manipulation; + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Manipulation.BAIIndexer; +import scriptmanager.scripts.BAM_Manipulation.FilterSamReadsWrapper; +import scriptmanager.scripts.BAM_Manipulation.ValidateSamWrapper; +import scriptmanager.util.FileSelection; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +/** + * @author Erik Pavloski + * This is the window class for ValidateSamWrapper + * @see scriptmanager.scripts.BAM_Manipulation.ValidateSamWrapper + */ + +public class ValidateSamWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + private File GENOME = null; + private JButton btnLoadBam; + private JButton btnRemoveBam; + private JCheckBox chckbxGenerateBaiIndex; + private JCheckBox chckbxSummaryMode; + private JButton btnLoadGenome; + private JLabel lblReferenceGenome; + private JButton btnOutput; + + private JLabel outputLabel; + private JButton btnLoadSam; + private JLabel maxLabel; + + private JTextField maxField; + + private JLabel lblDefaultToLocal; + private boolean mode; + + private JButton btnValidate; + private int maxOutput; + private JProgressBar progressBar; + public Task task; + + + class Task extends SwingWorker { + + int maxOutput; + + public Task (int maxOutput) { + this.maxOutput = maxOutput; + } + + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for(int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_validated.html"); + } else { + OUTPUT = new File(NAME[0] + "_validated.html"); + } + if (chckbxGenerateBaiIndex.isSelected()) { + BAIIndexer.generateIndex(BAMFiles.get(x)); + } + mode = !chckbxSummaryMode.isSelected(); + // Initialize log item + String command = ValidateSamWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, mode, GENOME, maxOutput); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Execute Picard wrapper + ValidateSamWrapper.run(BAMFiles.get(x), OUTPUT, mode, GENOME, maxOutput); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Validation Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + } + public ValidateSamWindow() { + setTitle("Validate SAM/BAM file"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + setBounds(125, 125, 580, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + + btnLoadSam = new JButton("Load SAM Files"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 6, SpringLayout.SOUTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadSam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadSam, 60, SpringLayout.NORTH, btnLoadBam); + + btnLoadSam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"sam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadSam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + chckbxGenerateBaiIndex = new JCheckBox("Generate BAI Index?"); + sl_contentPane.putConstraint(SpringLayout.WEST, chckbxGenerateBaiIndex, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxGenerateBaiIndex, 10, SpringLayout.SOUTH, scrollPane); + chckbxGenerateBaiIndex.setSelected(false); + contentPane.add(chckbxGenerateBaiIndex); + + chckbxSummaryMode = new JCheckBox("Use Summary Mode?"); + sl_contentPane.putConstraint(SpringLayout.WEST, chckbxSummaryMode, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxSummaryMode, 10, SpringLayout.SOUTH, scrollPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, chckbxSummaryMode, 1, SpringLayout.SOUTH, chckbxGenerateBaiIndex); + chckbxSummaryMode.setSelected(false); + contentPane.add(chckbxSummaryMode); + + chckbxSummaryMode.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + boolean isChecked = chckbxSummaryMode.isSelected(); + maxField.setEnabled(!isChecked); + maxField.setText("100"); + if (isChecked) { + maxField.setText(""); + maxOutput = 100; + } + } + }); + + btnLoadGenome = new JButton("Load Genome"); + btnLoadGenome.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getFile(fc, "fa"); + if (temp != null) { + GENOME = temp; + lblReferenceGenome.setText("Reference Genome: " + GENOME.getName()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadGenome, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadGenome, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadGenome, 30, SpringLayout.NORTH, btnLoadBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 60, SpringLayout.NORTH, btnLoadGenome); + contentPane.add(btnLoadGenome); + + lblReferenceGenome = new JLabel("Reference Genome: "); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblReferenceGenome, 5, SpringLayout.NORTH, btnLoadGenome); + sl_contentPane.putConstraint(SpringLayout.WEST, lblReferenceGenome, 6, SpringLayout.EAST, btnLoadGenome); + contentPane.add(lblReferenceGenome); + + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -200, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnValidate = new JButton("Validate"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnValidate, 30, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnValidate, -5, SpringLayout.EAST, contentPane); + contentPane.add(btnValidate); + + maxLabel = new JLabel("Maximum Output"); + sl_contentPane.putConstraint(SpringLayout.EAST, maxLabel, 0, SpringLayout.EAST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, maxLabel, 50, SpringLayout.EAST, btnOutput); + sl_contentPane.putConstraint(SpringLayout.NORTH, maxLabel, 5, SpringLayout.SOUTH, scrollPane); + contentPane.add(maxLabel); + + maxField = new JTextField("100"); + maxField.setPreferredSize(new Dimension(65, maxField.getPreferredSize().height)); + sl_contentPane.putConstraint(SpringLayout.EAST, maxField, 0, SpringLayout.EAST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.WEST, maxField, 50, SpringLayout.EAST, btnOutput); + sl_contentPane.putConstraint(SpringLayout.NORTH, maxField, 30, SpringLayout.SOUTH, scrollPane); + contentPane.add(maxField); + + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + + btnValidate.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + maxOutput = Integer.parseInt(maxField.getText()); + } catch (NumberFormatException nfe) { + maxOutput = 100; + } + + task = new Task(maxOutput); + task.addPropertyChangeListener(ValidateSamWindow.this); + task.execute(); + } + }); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(maxOutput); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } +} diff --git a/src/main/java/scriptmanager/window_interface/BAM_Statistics/CollectBaseDistributionByCycleWindow.java b/src/main/java/scriptmanager/window_interface/BAM_Statistics/CollectBaseDistributionByCycleWindow.java new file mode 100644 index 00000000..e7544d01 --- /dev/null +++ b/src/main/java/scriptmanager/window_interface/BAM_Statistics/CollectBaseDistributionByCycleWindow.java @@ -0,0 +1,221 @@ +package scriptmanager.window_interface.BAM_Statistics; + +import htsjdk.samtools.SAMException; +import scriptmanager.objects.LogItem; +import scriptmanager.scripts.BAM_Manipulation.ValidateSamWrapper; +import scriptmanager.scripts.BAM_Statistics.CollectBaseDistributionByCycleWrapper; +import scriptmanager.util.FileSelection; +import scriptmanager.window_interface.BAM_Manipulation.ValidateSamWindow; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.Vector; + +/** + * @author Erik Pavloski + * This is the window class for the CollectBaseDistrubtionByCycleWinow + * @see scriptmanager.scripts.BAM_Statistics.CollectBaseDistributionByCycleWrapper + */ +public class CollectBaseDistributionByCycleWindow extends JFrame implements ActionListener, PropertyChangeListener { + private JPanel contentPane; + protected JFileChooser fc = new JFileChooser(new File(System.getProperty("user.dir"))); + + final DefaultListModel expList; + + Vector BAMFiles = new Vector(); + private File OUT_DIR = null; + + private JButton btnLoadBam; + private JButton btnRemoveBam; + private JButton btnAction; + private JButton btnOutput; + + private JLabel outputLabel; + private JLabel lblDefaultToLocal; + private JProgressBar progressBar; + public Task task; + + class Task extends SwingWorker { + @Override + public Void doInBackground() throws IOException { + setProgress(0); + LogItem old_li = null; + try { + for(int x = 0; x < BAMFiles.size(); x++) { + // Build output filepath + String[] NAME = BAMFiles.get(x).getName().split("\\."); + File OUTPUT = null; + File chartOutput = null; + if (OUT_DIR != null) { + OUTPUT = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_output.txt"); + chartOutput = new File(OUT_DIR.getCanonicalPath() + File.separator + NAME[0] + "_collect_base_dist_by_cycle.pdf"); + } else { + OUTPUT = new File(NAME[0] + "_output.txt"); + chartOutput = new File(NAME[0] + "_collect_base_dist_by_cycle.pdf"); + } + // Initialize log item + String command = CollectBaseDistributionByCycleWrapper.getCLIcommand(BAMFiles.get(x), OUTPUT, chartOutput); + System.err.println(command); + LogItem new_li = new LogItem(command); + firePropertyChange("log", old_li, new_li); + // Execute Picard wrapper + CollectBaseDistributionByCycleWrapper.run(BAMFiles.get(x), OUTPUT, chartOutput); + // Update progress + int percentComplete = (int)(((double)(x + 1) / BAMFiles.size()) * 100); + setProgress(percentComplete); + // Update LogItem + new_li.setStopTime(new Timestamp(new Date().getTime())); + new_li.setStatus(0); + old_li = new_li; + } + firePropertyChange("log", old_li, null); + setProgress(100); + JOptionPane.showMessageDialog(null, "Distribution Complete"); + } catch (SAMException se) { + JOptionPane.showMessageDialog(null, se.getMessage()); + } + return null; + } + public void done() { + massXable(contentPane, true); + setCursor(null); //turn off the wait cursor + } + + } + public CollectBaseDistributionByCycleWindow() { + setTitle("Collect Base Distribution By Cycle"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + setBounds(125, 125, 580, 450); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + SpringLayout sl_contentPane = new SpringLayout(); + contentPane.setLayout(sl_contentPane); + + JScrollPane scrollPane = new JScrollPane(); + sl_contentPane.putConstraint(SpringLayout.WEST, scrollPane, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, scrollPane, -5, SpringLayout.EAST, contentPane); + contentPane.add(scrollPane); + + expList = new DefaultListModel(); + final JList listExp = new JList(expList); + listExp.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + scrollPane.setViewportView(listExp); + + btnLoadBam = new JButton("Load BAM Files"); + sl_contentPane.putConstraint(SpringLayout.WEST, btnLoadBam, 5, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 6, SpringLayout.SOUTH, btnLoadBam); + + btnRemoveBam = new JButton("Remove BAM"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnLoadBam, 0, SpringLayout.NORTH, btnRemoveBam); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnRemoveBam, 0, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnRemoveBam, -5, SpringLayout.EAST, contentPane); + btnRemoveBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + while(listExp.getSelectedIndex() > -1) { + BAMFiles.remove(listExp.getSelectedIndex()); + expList.remove(listExp.getSelectedIndex()); + } + } + }); + contentPane.add(btnRemoveBam); + + btnLoadBam.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File[] newBAMFiles = FileSelection.getFiles(fc,"bam"); + if(newBAMFiles != null) { + for(int x = 0; x < newBAMFiles.length; x++) { + BAMFiles.add(newBAMFiles[x]); + expList.addElement(newBAMFiles[x].getName()); + } + } + } + }); + contentPane.add(btnLoadBam); + btnOutput = new JButton("Output Directory"); + btnOutput.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + File temp = FileSelection.getOutputDir(fc); + if(temp != null) { + OUT_DIR = temp; + lblDefaultToLocal.setText(OUT_DIR.getAbsolutePath()); + } + } + }); + sl_contentPane.putConstraint(SpringLayout.SOUTH, scrollPane, -3, SpringLayout.NORTH, btnOutput); + sl_contentPane.putConstraint(SpringLayout.WEST, btnOutput, 200, SpringLayout.WEST, contentPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, btnOutput, -50, SpringLayout.SOUTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnOutput, -200, SpringLayout.EAST, contentPane); + contentPane.add(btnOutput); + + outputLabel = new JLabel("Current Output:"); + sl_contentPane.putConstraint(SpringLayout.WEST, outputLabel, 0, SpringLayout.WEST, scrollPane); + sl_contentPane.putConstraint(SpringLayout.SOUTH, outputLabel, 0, SpringLayout.SOUTH, contentPane); + contentPane.add(outputLabel); + + lblDefaultToLocal = new JLabel("Default to Local Directory"); + sl_contentPane.putConstraint(SpringLayout.NORTH, lblDefaultToLocal, 0, SpringLayout.NORTH, outputLabel); + sl_contentPane.putConstraint(SpringLayout.WEST, lblDefaultToLocal, 6, SpringLayout.EAST, outputLabel); + lblDefaultToLocal.setBackground(Color.WHITE); + contentPane.add(lblDefaultToLocal); + + btnAction = new JButton("Collect Base Distribution"); + sl_contentPane.putConstraint(SpringLayout.NORTH, btnAction, 30, SpringLayout.NORTH, contentPane); + sl_contentPane.putConstraint(SpringLayout.EAST, btnAction, -5, SpringLayout.EAST, contentPane); + sl_contentPane.putConstraint(SpringLayout.NORTH, scrollPane, 30, SpringLayout.NORTH, btnAction); + contentPane.add(btnAction); + + btnAction.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + task = new Task(); + task.addPropertyChangeListener(CollectBaseDistributionByCycleWindow.this); + task.execute(); + } + }); + progressBar = new JProgressBar(); + sl_contentPane.putConstraint(SpringLayout.NORTH, progressBar, -3, SpringLayout.NORTH, lblDefaultToLocal); + sl_contentPane.putConstraint(SpringLayout.EAST, progressBar, 0, SpringLayout.EAST, scrollPane); + progressBar.setStringPainted(true); + contentPane.add(progressBar); + } + @Override + public void actionPerformed(ActionEvent arg0) { + massXable(contentPane, false); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + task = new Task(); + task.addPropertyChangeListener(this); + task.execute(); + } + /** + * Invoked when task's progress property changes. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ("progress" == evt.getPropertyName()) { + int progress = (Integer) evt.getNewValue(); + progressBar.setValue(progress); + } else if ("log" == evt.getPropertyName()) { + firePropertyChange("log", evt.getOldValue(), evt.getNewValue()); + } + } + public void massXable(Container con, boolean status) { + for(Component c : con.getComponents()) { + c.setEnabled(status); + if(c instanceof Container) { massXable((Container)c, status); } + } + } + +} + +