From dd167edac0f12c8917d17374db7a83c41572a9f8 Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Thu, 19 Mar 2020 15:18:16 +0100 Subject: [PATCH 01/22] adding runtime estimation calculations --- src/main/java/IO/UserOptionsParser.java | 2 +- src/main/java/RunDamageProfiler.java | 2 + .../java/calculations/DamageProfiler.java | 78 +++++++++++++++++-- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index ace9a28..05080d6 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -119,7 +119,7 @@ private void parse() { CommandLineParser parser = new BasicParser(); if (args[0].equals("-version") || args[0].equals("--version")){ - System.out.print("DamageProfiler v" + this.version); + System.out.println("DamageProfiler v" + this.version); System.exit(0); } else if (args.length < 2) { helpformatter.printHelp(CLASS_NAME, options); diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index 446cef6..12eedc1 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -25,6 +25,8 @@ public static void main(String[] args) throws Exception { */ + System.setProperty("java.awt.headless", "true"); + if(args.length==0){ //MainDP damageProfilerGUI = new MainDP(c, starter, VERSION); System.out.println(VERSION); diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index 3312e3a..8c9c7c8 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -24,7 +24,6 @@ public class DamageProfiler { private Logger LOG=null; private IndexedFastaSequenceFile fastaSequenceFile; private int numberOfUsedReads; - private int numberOfAllReads; private int threshold; private int length; private Frequencies frequencies; @@ -33,6 +32,10 @@ public class DamageProfiler { LengthDistribution lengthDistribution; private ArrayList identity; private SpecieHandler specieHandler; + private double timePer100000RecordsInSeconds = 1; + private long actualRuntime=0; + private SamReader inputSamMate; + private long numberOfRecords; /** * constructor @@ -63,8 +66,11 @@ public void init(File input, File reference, int threshold, int length, String s inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). validationStringency(ValidationStringency.LENIENT).open(input); + + inputSamMate = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). + validationStringency(ValidationStringency.LENIENT).open(input); + numberOfUsedReads = 0; - numberOfAllReads = 0; this.LOG = LOG; this.threshold = threshold; this.length = length; @@ -104,10 +110,27 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea System.exit(0); } else { + + // estimate runtime: + numberOfRecords = getNumberOfrecords(); + System.out.println("Number of records to process: " + numberOfRecords); + long estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); + + if(estimatedRuntimeInSeconds > 60) { + long minutes = estimatedRuntimeInSeconds / 60; + long seconds = estimatedRuntimeInSeconds % 60; + System.out.println("Estimated Runtime: " + minutes + " minutes, and " + seconds + " seconds."); + } else { + System.out.println("Estimated Runtime: " + estimatedRuntimeInSeconds + " seconds."); + } + + // measure runtime per 100,000 records to estimate total runtime + long startTime = System.currentTimeMillis(); + for(SAMRecord record : inputSam) { + if (this.specie == null) { - numberOfAllReads++; handleRecord(use_only_merged_reads, use_all_reads, record); // print number of processed reads @@ -118,7 +141,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } else { if (record.getReferenceName().contains(this.specie)) { - numberOfAllReads++; + handleRecord(use_only_merged_reads, use_all_reads, record); // print number of processed reads @@ -127,17 +150,52 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } } } + + if((numberOfUsedReads % 100000) == 0){ + + long currtime_post_execution = System.currentTimeMillis(); + long diff = currtime_post_execution - startTime; + + long runtime_s = diff / 1000; + actualRuntime += runtime_s; + startTime = System.currentTimeMillis(); + } } + + + + frequencies.normalizeValues(); LOG.info("-------------------"); LOG.info("# reads used for damage calculation: " + (numberOfUsedReads )); } + if(actualRuntime > 60) { + long minutes = actualRuntime / 60; + long seconds = actualRuntime % 60; + System.out.println("Runtime per record: " + minutes + " minutes, and " + seconds + " seconds."); + } else { + System.out.println("Runtime per record: " + actualRuntime + " seconds."); + } + + } + + private long getNumberOfrecords() { + long count = 0; + for(SAMRecord record : inputSamMate){ + count++; + } + + inputSamMate=null; + return count; } private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, SAMRecord record) throws Exception { + + + if(use_all_reads && !use_only_merged_reads){ // process all reads processRecord(record); @@ -147,12 +205,14 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, if (!record.getReadUnmappedFlag() && record.getReadName().startsWith("M_")) { processRecord(record); } - } else if(!use_only_merged_reads && !use_all_reads) + } else if(!use_only_merged_reads && !use_all_reads) { // process only mapped reads if (!record.getReadUnmappedFlag()) { // get all mapped reads processRecord(record); } + } + } @@ -171,6 +231,8 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, private void processRecord(SAMRecord record) throws Exception{ numberOfUsedReads++; + + /* If MD value is set, use it to reconstruct reference Otherwise reconstruct reference it based on the CIGAR string @@ -243,7 +305,6 @@ private void processRecord(SAMRecord record) throws Exception{ frequencies.count(record, record_aligned, reference_aligned); frequencies.calculateMisincorporations(record, record_aligned, reference_aligned); - } @@ -284,8 +345,9 @@ public List getLength_all() { public int getNumberOfUsedReads() { return numberOfUsedReads; } - public int getNumberOfAllReads() { - return numberOfAllReads; + + public long getNumberOfAllReads() { + return numberOfRecords; } public ArrayList getIdentity() { return identity; } From 0dda1afffdd3fb21e6d56c89459115af6084904c Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Thu, 19 Mar 2020 17:12:15 +0100 Subject: [PATCH 02/22] adding runtime estimation calculations to GUI --- ...FileChooserFX.java => BamFileChooser.java} | 7 +- src/main/java/GUI/CopyTask.java | 37 ---- .../java/GUI/Dialogues/AbstractDialogue.java | 57 +++++++ .../java/GUI/{MainGuiFX.java => MainGui.java} | 161 +++++++++++++----- ...irChooserFX.java => OutputDirChooser.java} | 6 +- src/main/java/GUI/Progress.java | 128 -------------- ...ooserFX.java => ReferenceFileChooser.java} | 4 +- src/main/java/GUI/SpeciesListFileChooser.java | 1 - src/main/java/IO/Communicator.java | 4 - src/main/java/IO/OutputGenerator.java | 8 +- src/main/java/RunDamageProfiler.java | 8 +- .../java/calculations/DamageProfiler.java | 40 +---- .../java/calculations/RuntimeEstimator.java | 61 +++++++ .../java/calculations/StartCalculations.java | 8 +- 14 files changed, 271 insertions(+), 259 deletions(-) rename src/main/java/GUI/{BamFileChooserFX.java => BamFileChooser.java} (82%) delete mode 100755 src/main/java/GUI/CopyTask.java create mode 100644 src/main/java/GUI/Dialogues/AbstractDialogue.java rename src/main/java/GUI/{MainGuiFX.java => MainGui.java} (54%) rename src/main/java/GUI/{OutputDirChooserFX.java => OutputDirChooser.java} (69%) delete mode 100755 src/main/java/GUI/Progress.java rename src/main/java/GUI/{ReferenceFileChooserFX.java => ReferenceFileChooser.java} (84%) create mode 100644 src/main/java/calculations/RuntimeEstimator.java diff --git a/src/main/java/GUI/BamFileChooserFX.java b/src/main/java/GUI/BamFileChooser.java similarity index 82% rename from src/main/java/GUI/BamFileChooserFX.java rename to src/main/java/GUI/BamFileChooser.java index c91b333..d66d58f 100755 --- a/src/main/java/GUI/BamFileChooserFX.java +++ b/src/main/java/GUI/BamFileChooser.java @@ -8,11 +8,11 @@ import java.util.ArrayList; import java.util.List; -public class BamFileChooserFX { +public class BamFileChooser { private FileChooser fileChooser = new FileChooser(); - public BamFileChooserFX(Communicator c){ + public BamFileChooser(Communicator c){ fileChooser.getExtensionFilters().addAll( new FileChooser.ExtensionFilter("BAM", "*.bam"), @@ -31,9 +31,10 @@ public BamFileChooserFX(Communicator c){ } c.setInput(files.get(0)); - System.out.println(files.get(0)); + System.out.println("Input file: " + files.get(0)); } catch (Exception e){ + System.err.println(e); } diff --git a/src/main/java/GUI/CopyTask.java b/src/main/java/GUI/CopyTask.java deleted file mode 100755 index b2e068a..0000000 --- a/src/main/java/GUI/CopyTask.java +++ /dev/null @@ -1,37 +0,0 @@ -package GUI; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import javafx.concurrent.Task; - -// Copy all file in C:/Windows -public class CopyTask extends Task> { - - @Override - protected List call() throws Exception { - - File dir = new File("C:/Windows"); - File[] files = dir.listFiles(); - int count = files.length; - - List copied = new ArrayList(); - int i = 0; - for (File file : files) { - if (file.isFile()) { - this.copy(file); - copied.add(file); - } - i++; - this.updateProgress(i, count); - } - return copied; - } - - private void copy(File file) throws Exception { - this.updateMessage("Copying: " + file.getAbsolutePath()); - Thread.sleep(500); - } - -} \ No newline at end of file diff --git a/src/main/java/GUI/Dialogues/AbstractDialogue.java b/src/main/java/GUI/Dialogues/AbstractDialogue.java new file mode 100644 index 0000000..d167785 --- /dev/null +++ b/src/main/java/GUI/Dialogues/AbstractDialogue.java @@ -0,0 +1,57 @@ +package GUI.Dialogues; + +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.layout.GridPane; +import javafx.stage.Modality; +import javafx.stage.Stage; + +public class AbstractDialogue { + + private final Stage stage; + private GridPane gridPane; + private int row; + + public AbstractDialogue (String header, String message){ + + stage = new Stage(); + stage.setTitle(header); + stage.initModality(Modality.APPLICATION_MODAL); + stage.initOwner(new Stage()); + + gridPane = new GridPane(); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(10); + gridPane.setVgap(10); + + fillGrid(message); + + } + + private void fillGrid(String message) { + row = 0; + gridPane.add(new Label(message), 0,row,2,1); + gridPane.add(new Separator(), 0,++row,2,1); + } + + public void show(){ + Scene dialogScene = new Scene(gridPane, 600, 200); + stage.setScene(dialogScene); + stage.show(); + } + + public GridPane getGridPane() { + return gridPane; + } + + public int getRow() { + return row; + } + + + public void close() { + stage.close(); + } +} diff --git a/src/main/java/GUI/MainGuiFX.java b/src/main/java/GUI/MainGui.java similarity index 54% rename from src/main/java/GUI/MainGuiFX.java rename to src/main/java/GUI/MainGui.java index 3aefba8..54773b4 100755 --- a/src/main/java/GUI/MainGuiFX.java +++ b/src/main/java/GUI/MainGui.java @@ -1,7 +1,11 @@ package GUI; +import GUI.Dialogues.AbstractDialogue; import IO.Communicator; +import calculations.RuntimeEstimator; import calculations.StartCalculations; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; import javafx.application.Application; import javafx.concurrent.WorkerStateEvent; @@ -17,9 +21,13 @@ import javafx.scene.text.FontWeight; import javafx.stage.Stage; import javafx.concurrent.Task; +import javafx.util.Duration; +import java.lang.reflect.Field; -public class MainGuiFX extends Application { + + +public class MainGui extends Application { private Button btn_inputfile; private Button btn_reference; @@ -62,11 +70,11 @@ public void start(Stage primaryStage) { } - public Task startCalculuations(Communicator communicator) { + public Task startCalculations(Communicator communicator, RuntimeEstimator runtimeEstimator) { return new Task() { @Override protected Object call() throws Exception { - starter.start(communicator); + starter.start(communicator, runtimeEstimator); return true; } }; @@ -84,23 +92,29 @@ private void addListener() { // }); - btn_inputfile.setOnAction(e -> { - BamFileChooserFX fqfc = new BamFileChooserFX(communicator); - //Check if some input was truly selected + BamFileChooser fqfc = new BamFileChooser(communicator); + Tooltip tooltip_input = new Tooltip(communicator.getInput()); + setTooltipDelay(tooltip_input); + btn_inputfile.setTooltip(tooltip_input); if (checkIfInputWasSelected()) { btn_run.setDisable(false); + } else { btn_run.setDisable(true); } }); + btn_reference.setOnAction(e -> { - ReferenceFileChooserFX rfc = new ReferenceFileChooserFX(communicator); - //Check if some input was truly selected + + ReferenceFileChooser rfc = new ReferenceFileChooser(communicator); + Tooltip tooltip_ref = new Tooltip(communicator.getReference()); + setTooltipDelay(tooltip_ref); + btn_reference.setTooltip(tooltip_ref); if (checkIfInputWasSelected()) { btn_run.setDisable(false); @@ -112,10 +126,14 @@ private void addListener() { btn_output.setOnAction(e -> { - OutputDirChooserFX rfc = new OutputDirChooserFX(communicator); + OutputDirChooser rfc = new OutputDirChooser(communicator); + Tooltip tooltip_output = new Tooltip(communicator.getOutfolder()); + setTooltipDelay(tooltip_output); + btn_output.setTooltip(tooltip_output); if (checkIfInputWasSelected()) { btn_run.setDisable(false); + } else { btn_run.setDisable(true); } @@ -137,44 +155,88 @@ private void addListener() { btn_run.setOnAction(e -> { - // set all user options - communicator.setLength(Integer.parseInt(textfield_length.getText())); - communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); - communicator.setSpecies_ref_identifier(textfield_specie.getText()); -// if(!checkbox_dynamic_y_axis_height.isSelected()){ -// try { -// communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); -// } catch (Exception ex){ -// System.out.println("Height value not valid."); -// } -// } + RuntimeEstimator runtimeEstimator = new RuntimeEstimator(communicator.getInput()); + long estimatedRuntimeInSeconds = runtimeEstimator.getEstimatedRuntimeInSeconds(); + String text_estimatedRuntime; + if(estimatedRuntimeInSeconds > 60) { + long minutes = estimatedRuntimeInSeconds / 60; + long seconds = estimatedRuntimeInSeconds % 60; + text_estimatedRuntime = "Estimated Runtime: " + minutes + " minutes, and " + seconds + " seconds."; + } else { + if(estimatedRuntimeInSeconds == 0 ){ + text_estimatedRuntime = "Estimated Runtime: Insignificant"; + } else { + text_estimatedRuntime = "Estimated Runtime: " + estimatedRuntimeInSeconds + " seconds."; + } - if(!textfield_title.getText().equals("")){ - communicator.setTitle_plots(textfield_title.getText()); } + AbstractDialogue runtimeInfoDialogue = new AbstractDialogue("Runtime information", "This gives you an estimate of the runtime. For large files with a long runtime,\nit's recommended to use the command line version of DamageProfiler."); + Button btn_start = new Button("Proceed"); + Button btn_cancel = new Button("Cancel"); - try { - // add progress indicator - progressBar.setProgress(0); - startCalculuations = startCalculuations(communicator); - progressBar.progressProperty().unbind(); - progressBar.progressProperty().bind(startCalculuations.progressProperty()); - - startCalculuations.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, // - (EventHandler) t -> { - if(starter.isCalculationsDone()){ - primaryStage.close(); - } - }); - new Thread(startCalculuations).start(); - - //this.primaryStage.close(); - } catch (Exception e1) { - e1.printStackTrace(); - } + int row = runtimeInfoDialogue.getRow(); + runtimeInfoDialogue.getGridPane().add(new Label("Number of reads: " + runtimeEstimator.getNumberOfRecords()), 0, ++row, 2,1); + runtimeInfoDialogue.getGridPane().add(new Label(text_estimatedRuntime), 0, ++row, 2,1); + runtimeInfoDialogue.getGridPane().add(btn_cancel, 0, ++row, 1,1); + runtimeInfoDialogue.getGridPane().add(btn_start, 1, row, 1,1); + + runtimeInfoDialogue.show(); + + btn_start.setOnAction(e_start -> { + + runtimeInfoDialogue.close(); + + // set all user options + communicator.setLength(Integer.parseInt(textfield_length.getText())); + communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); + + if(textfield_specie.getText().equals("")) + communicator.setSpecies_ref_identifier(null); + else + communicator.setSpecies_ref_identifier(textfield_specie.getText()); + // if(!checkbox_dynamic_y_axis_height.isSelected()){ + // try { + // communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); + // } catch (Exception ex){ + // System.out.println("Height value not valid."); + // } + // } + + + if(!textfield_title.getText().equals("")){ + communicator.setTitle_plots(textfield_title.getText()); + } + + + try { + // add progress indicator + progressBar.setProgress(0); + startCalculuations = startCalculations(communicator, runtimeEstimator); + progressBar.progressProperty().unbind(); + progressBar.progressProperty().bind(startCalculuations.progressProperty()); + + startCalculuations.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, // + (EventHandler) t -> { + if(starter.isCalculationsDone()){ + primaryStage.close(); + } + }); + new Thread(startCalculuations).start(); + + //this.primaryStage.close(); + } catch (Exception e1) { + e1.printStackTrace(); + } + }); + + btn_cancel.setOnAction(e_cancel -> { + + runtimeInfoDialogue.close(); + + }); }); @@ -270,4 +332,21 @@ private boolean checkIfInputWasSelected() { + private static void setTooltipDelay(Tooltip tooltip) { + try { + Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR"); + fieldBehavior.setAccessible(true); + Object objBehavior = fieldBehavior.get(tooltip); + + Field fieldTimer = objBehavior.getClass().getDeclaredField("activationTimer"); + fieldTimer.setAccessible(true); + Timeline objTimer = (Timeline) fieldTimer.get(objBehavior); + + objTimer.getKeyFrames().clear(); + objTimer.getKeyFrames().add(new KeyFrame(new Duration(0))); + } catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/src/main/java/GUI/OutputDirChooserFX.java b/src/main/java/GUI/OutputDirChooser.java similarity index 69% rename from src/main/java/GUI/OutputDirChooserFX.java rename to src/main/java/GUI/OutputDirChooser.java index 9141f5f..e6493c8 100755 --- a/src/main/java/GUI/OutputDirChooserFX.java +++ b/src/main/java/GUI/OutputDirChooser.java @@ -6,15 +6,15 @@ import java.io.File; -public class OutputDirChooserFX { +public class OutputDirChooser { private DirectoryChooser dirChooser = new DirectoryChooser(); - public OutputDirChooserFX(Communicator c) { + public OutputDirChooser(Communicator c) { File f = dirChooser.showDialog(new Stage()); if (f != null){ c.setOutfolder(f.getAbsolutePath()); - System.out.println(f.getAbsolutePath()); + System.out.println("Output folder: " + f.getAbsolutePath()); } } diff --git a/src/main/java/GUI/Progress.java b/src/main/java/GUI/Progress.java deleted file mode 100755 index cbc5a63..0000000 --- a/src/main/java/GUI/Progress.java +++ /dev/null @@ -1,128 +0,0 @@ -package GUI; - -import javafx.application.Application; -import javafx.geometry.Insets; -import javafx.scene.Scene; -import javafx.scene.control.ProgressBar; -import javafx.scene.control.ProgressIndicator; -import javafx.scene.layout.FlowPane; -import javafx.stage.Stage; - -import java.io.File; -import java.util.List; - -import javafx.application.Application; -import javafx.concurrent.WorkerStateEvent; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Insets; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ProgressBar; -import javafx.scene.control.ProgressIndicator; -import javafx.scene.layout.FlowPane; -import javafx.scene.paint.Color; -import javafx.stage.Stage; - -public class Progress extends Application { - - private CopyTask copyTask; - - @Override - public void start(Stage primaryStage) { - - final Label label = new Label("Copy files:"); - final ProgressBar progressBar = new ProgressBar(0); - final ProgressIndicator progressIndicator = new ProgressIndicator(0); - - final Button startButton = new Button("Start"); - final Button cancelButton = new Button("Cancel"); - - final Label statusLabel = new Label(); - statusLabel.setMinWidth(250); - statusLabel.setTextFill(Color.BLUE); - - // Start Button. - startButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - startButton.setDisable(true); - progressBar.setProgress(0); - progressIndicator.setProgress(0); - cancelButton.setDisable(false); - - // Create a Task. - copyTask = new CopyTask(); - - // Unbind progress property - progressBar.progressProperty().unbind(); - - // Bind progress property - progressBar.progressProperty().bind(copyTask.progressProperty()); - - // Hủy bỏ kết nối thuộc tính progress - progressIndicator.progressProperty().unbind(); - - // Bind progress property. - progressIndicator.progressProperty().bind(copyTask.progressProperty()); - - // Unbind text property for Label. - statusLabel.textProperty().unbind(); - - // Bind the text property of Label - // with message property of Task - statusLabel.textProperty().bind(copyTask.messageProperty()); - - // When completed tasks - copyTask.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, // - new EventHandler() { - - @Override - public void handle(WorkerStateEvent t) { - List copied = copyTask.getValue(); - statusLabel.textProperty().unbind(); - statusLabel.setText("Copied: " + copied.size()); - } - }); - - // Start the Task. - new Thread(copyTask).start(); - - } - }); - - // Cancel - cancelButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - startButton.setDisable(false); - cancelButton.setDisable(true); - copyTask.cancel(true); - progressBar.progressProperty().unbind(); - progressIndicator.progressProperty().unbind(); - statusLabel.textProperty().unbind(); - // - progressBar.setProgress(0); - progressIndicator.setProgress(0); - } - }); - - FlowPane root = new FlowPane(); - root.setPadding(new Insets(10)); - root.setHgap(10); - - root.getChildren().addAll(label, progressBar, progressIndicator, // - statusLabel, startButton, cancelButton); - - Scene scene = new Scene(root, 500, 120, Color.WHITE); - primaryStage.setTitle("ProgressBar & ProgressIndicator"); - primaryStage.setScene(scene); - primaryStage.show(); - } - - public static void main(String[] args) { - Application.launch(args); - } - -} \ No newline at end of file diff --git a/src/main/java/GUI/ReferenceFileChooserFX.java b/src/main/java/GUI/ReferenceFileChooser.java similarity index 84% rename from src/main/java/GUI/ReferenceFileChooserFX.java rename to src/main/java/GUI/ReferenceFileChooser.java index 632458b..77f6389 100755 --- a/src/main/java/GUI/ReferenceFileChooserFX.java +++ b/src/main/java/GUI/ReferenceFileChooser.java @@ -6,11 +6,11 @@ import java.io.File; -public class ReferenceFileChooserFX { +public class ReferenceFileChooser { private FileChooser fileChooser = new FileChooser(); - public ReferenceFileChooserFX(Communicator c){ + public ReferenceFileChooser(Communicator c){ fileChooser.getExtensionFilters().addAll( new FileChooser.ExtensionFilter("Fasta", "*.fa","*.fasta", ".fas") diff --git a/src/main/java/GUI/SpeciesListFileChooser.java b/src/main/java/GUI/SpeciesListFileChooser.java index a9e894a..afd65c8 100755 --- a/src/main/java/GUI/SpeciesListFileChooser.java +++ b/src/main/java/GUI/SpeciesListFileChooser.java @@ -16,6 +16,5 @@ public SpeciesListFileChooser(Communicator c){ if(f != null){ c.setSpecieslist_filepath(f.getAbsolutePath()); } - } } diff --git a/src/main/java/IO/Communicator.java b/src/main/java/IO/Communicator.java index 88226d1..f2e172d 100755 --- a/src/main/java/IO/Communicator.java +++ b/src/main/java/IO/Communicator.java @@ -31,10 +31,6 @@ public class Communicator { - public Communicator(){ - - } - public String getInput() { return input; } diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index 32e15eb..aafb5b9 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -2,6 +2,7 @@ import calculations.DamageProfiler; import calculations.Frequencies; +import calculations.RuntimeEstimator; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.itextpdf.awt.PdfGraphics2D; @@ -43,6 +44,7 @@ public class OutputGenerator { private String outpath; private Frequencies frequencies; private DamageProfiler damageProfiler; + private RuntimeEstimator runtimeEstimator; private int max_length; private int min_length; private String specie; @@ -55,7 +57,8 @@ public class OutputGenerator { public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, - double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG) { + double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, + RuntimeEstimator runtimeEstimator) { this.outpath = outputFolder; this.frequencies = damageProfiler.getFrequencies(); @@ -70,6 +73,7 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.x_axis_max_length_histo = x_axis_max_length_histo; this.input = input; this.LOG = LOG; + this.runtimeEstimator = runtimeEstimator; // set tax id if specified by user if(specie != null && !specie.equals("")){ @@ -918,7 +922,7 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws document.open(); // compute percentage of used reads - double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / (double) damageProfiler.getNumberOfAllReads(); + double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / (double) runtimeEstimator.getNumberOfRecords(); // draw text String[] splitted = file.split("/"); diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index 12eedc1..7491f54 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -1,5 +1,6 @@ -import GUI.MainGuiFX; +import GUI.MainGui; import IO.*; +import calculations.RuntimeEstimator; import calculations.StartCalculations; import javafx.application.Application; @@ -30,13 +31,14 @@ public static void main(String[] args) throws Exception { if(args.length==0){ //MainDP damageProfilerGUI = new MainDP(c, starter, VERSION); System.out.println(VERSION); - new Thread(() -> Application.launch(MainGuiFX.class)).start(); + new Thread(() -> Application.launch(MainGui.class)).start(); } else { Communicator c = new Communicator(); StartCalculations starter = new StartCalculations(VERSION); UserOptionsParser userOptions = new UserOptionsParser(args, c, VERSION); - starter.start(c); + RuntimeEstimator runtimeEstimator = new RuntimeEstimator(c.getInput()); + starter.start(c, runtimeEstimator); } diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index 8c9c7c8..91942ec 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -32,10 +32,9 @@ public class DamageProfiler { LengthDistribution lengthDistribution; private ArrayList identity; private SpecieHandler specieHandler; - private double timePer100000RecordsInSeconds = 1; private long actualRuntime=0; - private SamReader inputSamMate; - private long numberOfRecords; + + private long runtime_ms; /** * constructor @@ -67,9 +66,6 @@ public void init(File input, File reference, int threshold, int length, String s inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). validationStringency(ValidationStringency.LENIENT).open(input); - inputSamMate = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). - validationStringency(ValidationStringency.LENIENT).open(input); - numberOfUsedReads = 0; this.LOG = LOG; this.threshold = threshold; @@ -111,20 +107,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } else { - // estimate runtime: - numberOfRecords = getNumberOfrecords(); - System.out.println("Number of records to process: " + numberOfRecords); - long estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); - - if(estimatedRuntimeInSeconds > 60) { - long minutes = estimatedRuntimeInSeconds / 60; - long seconds = estimatedRuntimeInSeconds % 60; - System.out.println("Estimated Runtime: " + minutes + " minutes, and " + seconds + " seconds."); - } else { - System.out.println("Estimated Runtime: " + estimatedRuntimeInSeconds + " seconds."); - } - - // measure runtime per 100,000 records to estimate total runtime + // measure runtime long startTime = System.currentTimeMillis(); for(SAMRecord record : inputSam) { @@ -156,6 +139,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea long currtime_post_execution = System.currentTimeMillis(); long diff = currtime_post_execution - startTime; + runtime_ms = diff; long runtime_s = diff / 1000; actualRuntime += runtime_s; startTime = System.currentTimeMillis(); @@ -176,20 +160,12 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea long seconds = actualRuntime % 60; System.out.println("Runtime per record: " + minutes + " minutes, and " + seconds + " seconds."); } else { - System.out.println("Runtime per record: " + actualRuntime + " seconds."); + System.out.println("Runtime per record: " + actualRuntime + " seconds and " + runtime_ms%60 + " milliseconds"); } } - private long getNumberOfrecords() { - long count = 0; - for(SAMRecord record : inputSamMate){ - count++; - } - inputSamMate=null; - return count; - } private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, SAMRecord record) throws Exception { @@ -346,9 +322,6 @@ public int getNumberOfUsedReads() { return numberOfUsedReads; } - public long getNumberOfAllReads() { - return numberOfRecords; - } public ArrayList getIdentity() { return identity; } public String getSpeciesname(File file, String ref) { @@ -366,5 +339,8 @@ public String getSpeciesname(File file, String ref) { return null; } + public long getActualRuntime() { + return actualRuntime; + } } diff --git a/src/main/java/calculations/RuntimeEstimator.java b/src/main/java/calculations/RuntimeEstimator.java new file mode 100644 index 0000000..572972e --- /dev/null +++ b/src/main/java/calculations/RuntimeEstimator.java @@ -0,0 +1,61 @@ +package calculations; + +import htsjdk.samtools.SAMRecord; +import htsjdk.samtools.SamReader; +import htsjdk.samtools.SamReaderFactory; +import htsjdk.samtools.ValidationStringency; + +import java.io.File; + +public class RuntimeEstimator { + + private SamReader input; + private long numberOfRecords; + private double timePer100000RecordsInSeconds = 2; + private long estimatedRuntimeInSeconds; + + public RuntimeEstimator(String inputfile){ + input = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). + validationStringency(ValidationStringency.LENIENT).open(new File(inputfile)); + + estimate(); + } + + private void estimate() { + // estimate runtime: + numberOfRecords = getNumberOfrecords(); + System.out.println("Number of records to process: " + numberOfRecords); + + estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); + + if(estimatedRuntimeInSeconds > 60) { + long minutes = estimatedRuntimeInSeconds / 60; + long seconds = estimatedRuntimeInSeconds % 60; + System.out.println("Estimated Runtime: " + minutes + " minutes, and " + seconds + " seconds."); + } else { + System.out.println("Estimated Runtime: " + estimatedRuntimeInSeconds + " seconds."); + } + + } + + private long getNumberOfrecords() { + long count = 0; + for(SAMRecord record : input){ + count++; + } + + input=null; + + return count; + } + + + public long getNumberOfRecords() { + return numberOfRecords; + } + + + public long getEstimatedRuntimeInSeconds() { + return estimatedRuntimeInSeconds; + } +} diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index c088b1c..301e295 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -39,13 +39,14 @@ public class StartCalculations { private double xaxis_max_id_histogram; private double xaxis_min_length_histogram; private double xaxis_max_length_histogram; + private RuntimeEstimator runtimeEstimator; public StartCalculations(String version){ VERSION = version; } - public void start(Communicator c) throws Exception { + public void start(Communicator c, RuntimeEstimator runtimeEstimator) throws Exception { currtime_prior_execution = System.currentTimeMillis(); @@ -66,13 +67,13 @@ public void start(Communicator c) throws Exception { speciesListParser=null; species_name_list=null; specieHandler = new SpecieHandler(); + this.runtimeEstimator = runtimeEstimator; SpeciesListParser speciesListParser = new SpeciesListParser( specieslist_filepath, LOG ); - if(specieslist_filepath != null){ /* @@ -338,7 +339,8 @@ private void generateOutput(DamageProfiler damageProfiler, String output_folder, xaxis_min_length_histogram, xaxis_max_length_histogram, input, - LOG + LOG, + runtimeEstimator ); outputGenerator.writeLengthDistribution(); From 10dc2842e4beb0492ba40bd694658051a6444995 Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Fri, 20 Mar 2020 11:18:25 +0100 Subject: [PATCH 03/22] implementing ssLib option in CLI and GUI --- src/main/java/GUI/MainGui.java | 16 +- src/main/java/IO/Communicator.java | 9 + src/main/java/IO/OutputGenerator.java | 372 +++++++++--------- src/main/java/IO/UserOptionsParser.java | 8 + .../java/calculations/DamageProfiler.java | 7 +- .../java/calculations/StartCalculations.java | 62 ++- 6 files changed, 255 insertions(+), 219 deletions(-) diff --git a/src/main/java/GUI/MainGui.java b/src/main/java/GUI/MainGui.java index 54773b4..febf253 100755 --- a/src/main/java/GUI/MainGui.java +++ b/src/main/java/GUI/MainGui.java @@ -39,6 +39,7 @@ public class MainGui extends Application { private TextField textfield_length; private TextField textfield_specie; private CheckBox checkbox_use_merged_reads; + private CheckBox checkbos_ssLibs_protocol; private TextField textfield_title; //private CheckBox checkbox_dynamic_y_axis_height; private TextField textfield_y_axis_height; @@ -62,7 +63,7 @@ public void start(Stage primaryStage) { addComponents(root); addListener(); - this.primaryStage.setScene(new Scene(root, 650, 400)); + this.primaryStage.setScene(new Scene(root, 750, 500)); this.primaryStage.setResizable(true); this.primaryStage.show(); @@ -191,6 +192,7 @@ private void addListener() { // set all user options communicator.setLength(Integer.parseInt(textfield_length.getText())); communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); + communicator.setSsLibsProtocolUsed(checkbos_ssLibs_protocol.isSelected()); if(textfield_specie.getText().equals("")) communicator.setSpecies_ref_identifier(null); @@ -260,6 +262,8 @@ private void addComponents(GridPane root) { Label label_title = new Label("Set title"); Label label_plot = new Label("Plot"); label_plot.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + Label label_files = new Label("Files"); + label_files.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); Label label_calculations = new Label("Calculations"); label_calculations.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); @@ -272,7 +276,8 @@ private void addComponents(GridPane root) { textfield_title = new TextField(); textfield_y_axis_height = new TextField(); - checkbox_use_merged_reads = new CheckBox("Use only merged reads"); + checkbox_use_merged_reads = new CheckBox("Only merged reads"); + checkbos_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); btn_run.setDisable(true); @@ -287,7 +292,8 @@ private void addComponents(GridPane root) { int row = 0; - root.add(btn_inputfile, 0, row,1,1); + root.add(label_files, 0, row, 1,1); + root.add(btn_inputfile, 0, ++row,1,1); root.add(btn_reference, 1, row,1,1); root.add(btn_output, 2, row,1,1); root.add(new Separator(), 0, ++row,3,1); @@ -305,12 +311,12 @@ private void addComponents(GridPane root) { root.add(label_specie, 0, ++row, 1,1); root.add(textfield_specie, 1, row, 2,1); root.add(btn_specieList, 3, row, 1,1); - root.add(checkbox_use_merged_reads, 0, ++row,1,1); root.add(new Separator(), 0, ++row,3,1); // CALCULATIONS - root.add(label_calculations, 0, ++row, 1,1); + root.add(checkbox_use_merged_reads, 0, ++row,1,1); + root.add(checkbos_ssLibs_protocol, 0, ++row, 1,1); root.add(label_length, 0, ++row, 1,1); root.add(textfield_length, 1, row, 2,1); root.add(new Separator(), 0, ++row,3,1); diff --git a/src/main/java/IO/Communicator.java b/src/main/java/IO/Communicator.java index f2e172d..14656fb 100755 --- a/src/main/java/IO/Communicator.java +++ b/src/main/java/IO/Communicator.java @@ -22,6 +22,7 @@ public class Communicator { private int length = 100; private boolean use_merged_and_mapped_reads = false; private boolean use_all_reads = false; + private boolean ssLibsProtocolUsed = false; // specie filtering private String species_ref_identifier = null; @@ -95,6 +96,14 @@ public void setUse_all_reads(boolean use_all_reads) { this.use_all_reads = use_all_reads; } + public boolean isSsLibsProtocolUsed() { + return ssLibsProtocolUsed; + } + + public void setSsLibsProtocolUsed(boolean ssLibsProtocolUsed) { + this.ssLibsProtocolUsed = ssLibsProtocolUsed; + } + public void setyAxis_damageplot(double yAxis_damageplot) { this.yAxis_damageplot = yAxis_damageplot; } diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index aafb5b9..31fa340 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -38,6 +38,7 @@ public class OutputGenerator { private final double x_axis_max_id_histo; private final double x_axis_min_length_histo; private final double x_axis_max_length_histo; + private final boolean ssLibProtocolUsed; private int numberOfUsedReads; private final double height; private final Logger LOG; @@ -58,7 +59,7 @@ public class OutputGenerator { public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, - RuntimeEstimator runtimeEstimator) { + RuntimeEstimator runtimeEstimator, boolean ssLibProtocolUsed) { this.outpath = outputFolder; this.frequencies = damageProfiler.getFrequencies(); @@ -74,6 +75,7 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.input = input; this.LOG = LOG; this.runtimeEstimator = runtimeEstimator; + this.ssLibProtocolUsed = ssLibProtocolUsed; // set tax id if specified by user if(specie != null && !specie.equals("")){ @@ -235,28 +237,29 @@ public void writeDNAComp(Frequencies frequencies) throws IOException{ // write header freq_file_sample.write("End\tStd\tPos\tA\tC\tG\tT\tTotal\n"); - // fill '3p +' - for(int i = 0; i < this.length; i++){ - double sum=frequencies.getCount_total_forward_3()[i]; + if(!ssLibProtocolUsed){ + // fill '3p +' + for(int i = 0; i < this.length; i++){ + double sum=frequencies.getCount_total_forward_3()[i]; - freq_file_sample.write("3p\t+\t"+(i+1)+"\t" - +(int)frequencies.getCountA_forward_3()[i]+"\t"+(int)frequencies.getCountC_forward_3()[i]+"\t" - +(int)frequencies.getCountG_forward_3()[i]+"\t"+(int)frequencies.getCountT_forward_3()[i]+"\t" - +(int)sum+"\n" - ); - - } + freq_file_sample.write("3p\t+\t"+(i+1)+"\t" + +(int)frequencies.getCountA_forward_3()[i]+"\t"+(int)frequencies.getCountC_forward_3()[i]+"\t" + +(int)frequencies.getCountG_forward_3()[i]+"\t"+(int)frequencies.getCountT_forward_3()[i]+"\t" + +(int)sum+"\n" + ); - // fill '3p -' - for(int i = 0; i < this.length; i++){ - double sum = frequencies.getCount_total_reverse_3()[i]; + } - freq_file_sample.write("3p\t-\t"+(i+1)+"\t" - +(int)frequencies.getCountA_reverse_3()[i]+"\t"+(int)frequencies.getCountC_reverse_3()[i]+"\t" - +(int)frequencies.getCountG_reverse_3()[i]+"\t"+(int)frequencies.getCountT_reverse_3()[i]+"\t" - +(int)sum+"\n" - ); + // fill '3p -' + for(int i = 0; i < this.length; i++){ + double sum = frequencies.getCount_total_reverse_3()[i]; + freq_file_sample.write("3p\t-\t"+(i+1)+"\t" + +(int)frequencies.getCountA_reverse_3()[i]+"\t"+(int)frequencies.getCountC_reverse_3()[i]+"\t" + +(int)frequencies.getCountG_reverse_3()[i]+"\t"+(int)frequencies.getCountT_reverse_3()[i]+"\t" + +(int)sum+"\n" + ); + } } @@ -313,56 +316,58 @@ public void writeFrequenciesReference(Frequencies frequencies) throws IOExceptio // write header freq_file_ref.write("Chr\tEnd\tStd\tPos\tA\tC\tG\tT\tTotal\tG>A\tC>T\tA>G\tT>C\tA>C\tA>T\tC>G\tC>A\tT>G\tT>A\tG>C\tG>T\tA>-\tT>-\tC>-\tG>-\t->A\t->T\t->C\t->G\tS\n"); - // fill '3p +' - for(int i = 0; i < this.length; i++){ - double sum=frequencies.getCountA_ref_forward_3()[i]+frequencies.getCountC_ref_forward_3()[i]+ - frequencies.getCountG_ref_forward_3()[i]+frequencies.getCountT_ref_forward_3()[i]; - - if(this.numberOfUsedReads>0){ - freq_file_ref.write("fwd\t3p\t+\t"+(i+1)+"\t" - +frequencies.getCountA_ref_forward_3()[i]+"\t"+frequencies.getCountC_ref_forward_3()[i]+"\t" - +frequencies.getCountG_ref_forward_3()[i]+"\t"+frequencies.getCountT_ref_forward_3()[i]+"\t" - +sum+"\t" - +frequencies.getCount_forward_G_A_3()[i]+"\t"+frequencies.getCount_forward_C_T_3()[i]+"\t" - +frequencies.getCount_forward_A_G_3()[i]+"\t"+frequencies.getCount_forward_T_C_3()[i]+"\t" - +frequencies.getCount_forward_A_C_3()[i]+"\t"+frequencies.getCount_forward_A_T_3()[i]+"\t" - +frequencies.getCount_forward_C_G_3()[i]+"\t"+frequencies.getCount_forward_C_A_3()[i]+"\t" - +frequencies.getCount_forward_T_G_3()[i]+"\t"+frequencies.getCount_forward_T_A_3()[i]+"\t" - +frequencies.getCount_forward_G_C_3()[i]+"\t"+frequencies.getCount_forward_G_T_3()[i]+"\t" - +frequencies.getCount_forward_A_0_3()[i]+"\t"+frequencies.getCount_forward_T_0_3()[i]+"\t" - +frequencies.getCount_forward_C_0_3()[i]+"\t"+frequencies.getCount_forward_G_0_3()[i]+"\t" - +frequencies.getCount_forward_0_A_3()[i]+"\t"+frequencies.getCount_forward_0_T_3()[i]+"\t" - +frequencies.getCount_forward_0_C_3()[i]+"\t"+frequencies.getCount_forward_0_G_3()[i]+"\t" - +frequencies.getCountS_forward_3()[i]+"\n" - ); + if(!ssLibProtocolUsed){ + // fill '3p +' + for(int i = 0; i < this.length; i++){ + double sum=frequencies.getCountA_ref_forward_3()[i]+frequencies.getCountC_ref_forward_3()[i]+ + frequencies.getCountG_ref_forward_3()[i]+frequencies.getCountT_ref_forward_3()[i]; + + if(this.numberOfUsedReads>0){ + freq_file_ref.write("fwd\t3p\t+\t"+(i+1)+"\t" + +frequencies.getCountA_ref_forward_3()[i]+"\t"+frequencies.getCountC_ref_forward_3()[i]+"\t" + +frequencies.getCountG_ref_forward_3()[i]+"\t"+frequencies.getCountT_ref_forward_3()[i]+"\t" + +sum+"\t" + +frequencies.getCount_forward_G_A_3()[i]+"\t"+frequencies.getCount_forward_C_T_3()[i]+"\t" + +frequencies.getCount_forward_A_G_3()[i]+"\t"+frequencies.getCount_forward_T_C_3()[i]+"\t" + +frequencies.getCount_forward_A_C_3()[i]+"\t"+frequencies.getCount_forward_A_T_3()[i]+"\t" + +frequencies.getCount_forward_C_G_3()[i]+"\t"+frequencies.getCount_forward_C_A_3()[i]+"\t" + +frequencies.getCount_forward_T_G_3()[i]+"\t"+frequencies.getCount_forward_T_A_3()[i]+"\t" + +frequencies.getCount_forward_G_C_3()[i]+"\t"+frequencies.getCount_forward_G_T_3()[i]+"\t" + +frequencies.getCount_forward_A_0_3()[i]+"\t"+frequencies.getCount_forward_T_0_3()[i]+"\t" + +frequencies.getCount_forward_C_0_3()[i]+"\t"+frequencies.getCount_forward_G_0_3()[i]+"\t" + +frequencies.getCount_forward_0_A_3()[i]+"\t"+frequencies.getCount_forward_0_T_3()[i]+"\t" + +frequencies.getCount_forward_0_C_3()[i]+"\t"+frequencies.getCount_forward_0_G_3()[i]+"\t" + +frequencies.getCountS_forward_3()[i]+"\n" + ); + } } - } - - // fill '3p -' - for(int i = 0; i < this.length; i++){ - double sum = frequencies.getCountA_ref_reverse_3()[i]+frequencies.getCountC_ref_reverse_3()[i]+ - frequencies.getCountG_ref_reverse_3()[i]+frequencies.getCountT_ref_reverse_3()[i]; - if(this.numberOfUsedReads>0){ - freq_file_ref.write("rev\t3p\t-\t"+(i+1)+"\t" - +frequencies.getCountA_ref_reverse_3()[i]+"\t"+frequencies.getCountC_ref_reverse_3()[i]+"\t" - +frequencies.getCountG_ref_reverse_3()[i]+"\t"+frequencies.getCountT_ref_reverse_3()[i]+"\t" - +sum+"\t" - +frequencies.getCount_reverse_G_A_3()[i]+"\t"+frequencies.getCount_reverse_C_T_3()[i]+"\t" - +frequencies.getCount_reverse_A_G_3()[i]+"\t"+frequencies.getCount_reverse_T_C_3()[i]+"\t" - +frequencies.getCount_reverse_A_C_3()[i]+"\t"+frequencies.getCount_reverse_A_T_3()[i]+"\t" - +frequencies.getCount_reverse_C_G_3()[i]+"\t"+frequencies.getCount_reverse_C_A_3()[i]+"\t" - +frequencies.getCount_reverse_T_G_3()[i]+"\t"+frequencies.getCount_reverse_T_A_3()[i]+"\t" - +frequencies.getCount_reverse_G_C_3()[i]+"\t"+frequencies.getCount_reverse_G_T_3()[i] - +frequencies.getCount_reverse_A_0_3()[i]+"\t"+frequencies.getCount_reverse_T_0_3()[i]+"\t" - +frequencies.getCount_reverse_C_0_3()[i]+"\t"+frequencies.getCount_reverse_G_0_3()[i]+"\t" - +frequencies.getCount_reverse_0_A_3()[i]+"\t"+frequencies.getCount_reverse_0_T_3()[i]+"\t" - +frequencies.getCount_reverse_0_C_3()[i]+"\t"+frequencies.getCount_reverse_0_G_3()[i]+"\t" - +frequencies.getCountS_reverse_3()[i]+"\n" - ); + // fill '3p -' + for(int i = 0; i < this.length; i++){ + double sum = frequencies.getCountA_ref_reverse_3()[i]+frequencies.getCountC_ref_reverse_3()[i]+ + frequencies.getCountG_ref_reverse_3()[i]+frequencies.getCountT_ref_reverse_3()[i]; + + if(this.numberOfUsedReads>0){ + freq_file_ref.write("rev\t3p\t-\t"+(i+1)+"\t" + +frequencies.getCountA_ref_reverse_3()[i]+"\t"+frequencies.getCountC_ref_reverse_3()[i]+"\t" + +frequencies.getCountG_ref_reverse_3()[i]+"\t"+frequencies.getCountT_ref_reverse_3()[i]+"\t" + +sum+"\t" + +frequencies.getCount_reverse_G_A_3()[i]+"\t"+frequencies.getCount_reverse_C_T_3()[i]+"\t" + +frequencies.getCount_reverse_A_G_3()[i]+"\t"+frequencies.getCount_reverse_T_C_3()[i]+"\t" + +frequencies.getCount_reverse_A_C_3()[i]+"\t"+frequencies.getCount_reverse_A_T_3()[i]+"\t" + +frequencies.getCount_reverse_C_G_3()[i]+"\t"+frequencies.getCount_reverse_C_A_3()[i]+"\t" + +frequencies.getCount_reverse_T_G_3()[i]+"\t"+frequencies.getCount_reverse_T_A_3()[i]+"\t" + +frequencies.getCount_reverse_G_C_3()[i]+"\t"+frequencies.getCount_reverse_G_T_3()[i] + +frequencies.getCount_reverse_A_0_3()[i]+"\t"+frequencies.getCount_reverse_T_0_3()[i]+"\t" + +frequencies.getCount_reverse_C_0_3()[i]+"\t"+frequencies.getCount_reverse_G_0_3()[i]+"\t" + +frequencies.getCount_reverse_0_A_3()[i]+"\t"+frequencies.getCount_reverse_0_T_3()[i]+"\t" + +frequencies.getCount_reverse_0_C_3()[i]+"\t"+frequencies.getCount_reverse_0_G_3()[i]+"\t" + +frequencies.getCountS_reverse_3()[i]+"\n" + ); + } } - } + } // fill '5p +' for(int i = 0; i < this.length; i++){ @@ -485,28 +490,31 @@ public void plotIdentitiyHistogram(ArrayList distances, String title, String fil */ public void writeDamageFiles(double[] gToA_reverse, double[] cToT) throws IOException{ + BufferedWriter writer3Prime; + - BufferedWriter writer3Prime = new BufferedWriter(new FileWriter(this.outpath + "/3pGtoA_freq.txt")); BufferedWriter writer5Prime = new BufferedWriter(new FileWriter(this.outpath + "/5pCtoT_freq.txt")); //Add stuff to json output file json_map.put("dmg_5p",getSubArray(cToT, this.threshold)); - json_map.put("dmg_3p",getSubArray(gToA_reverse,this.threshold)); + // 3p end always included in json file, as it's needed for EAGER2.0 report + json_map.put("dmg_3p",getSubArray(gToA_reverse,this.threshold)); - writer3Prime.write("# table produced by calculations.DamageProfiler\n"); - writer3Prime.write("# using mapped file " + input + "\n"); - writer3Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); + if(!ssLibProtocolUsed){ + writer3Prime = new BufferedWriter(new FileWriter(this.outpath + "/3pGtoA_freq.txt")); + writer3Prime.write("# table produced by calculations.DamageProfiler\n"); + writer3Prime.write("# using mapped file " + input + "\n"); + writer3Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); + writeDamagePattern("pos\t3pG>A\n", getSubArray(gToA_reverse, this.threshold), writer3Prime); + writer3Prime.close(); + } writer5Prime.write("# table produced by calculations.DamageProfiler\n"); writer5Prime.write("# using mapped file " + input + "\n"); writer5Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - writeDamagePattern("pos\t5pC>T\n", getSubArray(cToT, this.threshold), writer5Prime); - writeDamagePattern("pos\t3pG>A\n", getSubArray(gToA_reverse, this.threshold), writer3Prime); - - writer3Prime.close(); writer5Prime.close(); } @@ -527,7 +535,7 @@ private void writeDamagePattern(String title, double[] values, BufferedWriter wr } public void computeSummaryMetrics(){ - HashMap forwardMap = damageProfiler.getLength_distribution_map_forward(); // key = length, value = occurences + HashMap forwardMap = damageProfiler.getLength_distribution_map_forward(); // key = length, value = occurrences HashMapreverseMap = damageProfiler.getLength_distribution_map_reverse(); //Create ArrayList of read lengths @@ -568,17 +576,11 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw Locale.setDefault(Locale.US); BufferedWriter writer5PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/5p_freq_misincorporations.txt")); - BufferedWriter writer3PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/3p_freq_misincorporations.txt")); writer5PrimeAll.write("# table produced by calculations.DamageProfiler\n"); writer5PrimeAll.write("# using mapped file " + input + "\n"); writer5PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - writer3PrimeAll.write("# table produced by calculations.DamageProfiler\n"); - writer3PrimeAll.write("# using mapped file " + input + "\n"); - writer3PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - - /* 5 prime end @@ -633,79 +635,71 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw String.format("%.6f",deletions_mean5[pos])+ "\n"); } - + writer5PrimeAll.close(); /* 3 prime end */ + if(!ssLibProtocolUsed){ + BufferedWriter writer3PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/3p_freq_misincorporations.txt")); + writer3PrimeAll.write("# table produced by calculations.DamageProfiler\n"); + writer3PrimeAll.write("# using mapped file " + input + "\n"); + writer3PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - double[] three_A_to_C_reverse = getSubArray(frequencies.getCount_A_C_3_norm(),threshold); - double[] three_A_to_G_reverse = getSubArray(frequencies.getCount_A_G_3_norm(),threshold); - double[] three_A_to_T_reverse = getSubArray(frequencies.getCount_A_T_3_norm(),threshold); - double[] three_C_to_A_reverse = getSubArray(frequencies.getCount_C_A_3_norm(), threshold); - double[] three_C_to_G_reverse = getSubArray(frequencies.getCount_C_G_3_norm(), threshold); - double[] three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); + double[] three_A_to_C_reverse = getSubArray(frequencies.getCount_A_C_3_norm(),threshold); + double[] three_A_to_G_reverse = getSubArray(frequencies.getCount_A_G_3_norm(),threshold); + double[] three_A_to_T_reverse = getSubArray(frequencies.getCount_A_T_3_norm(),threshold); - double[] three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); - double[] three_G_to_C_reverse = getSubArray(frequencies.getCount_G_C_3_norm(),threshold); - double[] three_G_to_T_reverse = getSubArray(frequencies.getCount_G_T_3_norm(),threshold); + double[] three_C_to_A_reverse = getSubArray(frequencies.getCount_C_A_3_norm(), threshold); + double[] three_C_to_G_reverse = getSubArray(frequencies.getCount_C_G_3_norm(), threshold); + double[] three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); - double[] three_T_to_A_reverse = getSubArray(frequencies.getCount_T_A_3_norm(),threshold); - double[] three_T_to_C_reverse = getSubArray(frequencies.getCount_T_C_3_norm(),threshold); - double[] three_T_to_G_reverse = getSubArray(frequencies.getCount_T_G_3_norm(),threshold); + double[] three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); + double[] three_G_to_C_reverse = getSubArray(frequencies.getCount_G_C_3_norm(),threshold); + double[] three_G_to_T_reverse = getSubArray(frequencies.getCount_G_T_3_norm(),threshold); -// three_A_to_C_reverse = reverseArray(three_A_to_C_reverse); -// three_A_to_G_reverse = reverseArray(three_A_to_G_reverse); -// three_A_to_T_reverse = reverseArray(three_A_to_T_reverse); -// -// three_C_to_A_reverse = reverseArray(three_C_to_A_reverse); -// three_C_to_G_reverse = reverseArray(three_C_to_G_reverse); -// three_C_to_T_reverse = reverseArray(three_C_to_T_reverse); -// -// three_G_to_A_reverse = reverseArray(three_G_to_A_reverse); -// three_G_to_C_reverse = reverseArray(three_G_to_C_reverse); -// three_G_to_T_reverse = reverseArray(three_G_to_T_reverse); -// -// three_T_to_A_reverse = reverseArray(three_T_to_A_reverse); -// three_T_to_C_reverse = reverseArray(three_T_to_C_reverse); -// three_T_to_G_reverse = reverseArray(three_T_to_G_reverse); - - - double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), - frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); + double[] three_T_to_A_reverse = getSubArray(frequencies.getCount_T_A_3_norm(),threshold); + double[] three_T_to_C_reverse = getSubArray(frequencies.getCount_T_C_3_norm(),threshold); + double[] three_T_to_G_reverse = getSubArray(frequencies.getCount_T_G_3_norm(),threshold); - // green (deletions) - double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , - frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); - // write header - writer3PrimeAll.write("Pos\tC>T\tG>A\tA>C\tA>G\tA>T\tC>A\tC>G\tG>C\tG>T\tT>A\tT>C\tT>G\t" + - "->ACGT\tACGT>-\n"); - for(int pos = threshold-1; pos >=0; pos--){ - - writer3PrimeAll.write(pos + "\t" + - String.format("%.6f", three_C_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_A_reverse[pos])+ "\t" + - String.format("%.6f", three_A_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_A_to_G_reverse[pos]) + "\t" + - String.format("%.6f", three_A_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_C_to_A_reverse[pos]) + "\t" + - String.format("%.6f", three_C_to_G_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_A_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_G_reverse[pos]) + "\t" + - String.format("%.6f", insertions_mean_3[pos]) + "\t" + - String.format("%.6f", deletions_mean_3[pos]) + "\n"); + double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), + frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); + + // green (deletions) + double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , + frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); + // write header + writer3PrimeAll.write("Pos\tC>T\tG>A\tA>C\tA>G\tA>T\tC>A\tC>G\tG>C\tG>T\tT>A\tT>C\tT>G\t" + + "->ACGT\tACGT>-\n"); + + for(int pos = threshold-1; pos >=0; pos--){ + + writer3PrimeAll.write(pos + "\t" + + String.format("%.6f", three_C_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_A_reverse[pos])+ "\t" + + String.format("%.6f", three_A_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_A_to_G_reverse[pos]) + "\t" + + String.format("%.6f", three_A_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_C_to_A_reverse[pos]) + "\t" + + String.format("%.6f", three_C_to_G_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_A_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_G_reverse[pos]) + "\t" + + String.format("%.6f", insertions_mean_3[pos]) + "\t" + + String.format("%.6f", deletions_mean_3[pos]) + "\n"); + + } + + writer3PrimeAll.close(); } - writer3PrimeAll.close(); - writer5PrimeAll.close(); } @@ -754,10 +748,44 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep three_T_to_C_reverse = reverseArray(three_T_to_C_reverse); three_T_to_G_reverse = reverseArray(three_T_to_G_reverse); - + LinePlot damagePlot_three=null; // create plots - LinePlot damagePlot_three = new LinePlot("3' end", threshold, height, LOG); + if(!ssLibProtocolUsed){ + damagePlot_three = new LinePlot("3' end", threshold, height, LOG); + + // three prime end + // red + damagePlot_three.addData(three_C_to_T_reverse, "3'C>T"); + // blue + damagePlot_three.addData(three_G_to_A_reverse, "3'G>A"); + + // purple (insertions) + double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), + frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); + damagePlot_three.addData(insertions_mean_3, "insertions"); + + // green (deletions) + double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , + frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); + damagePlot_three.addData(deletions_mean_3, "deletions"); + + + // gray + damagePlot_three.addData(three_A_to_C_reverse, "others"); + damagePlot_three.addData(three_A_to_G_reverse, "3'A>G"); + damagePlot_three.addData(three_A_to_T_reverse, "3'A>T"); + damagePlot_three.addData(three_C_to_A_reverse, "3'C>A"); + damagePlot_three.addData(three_C_to_G_reverse, "3'C>G"); + damagePlot_three.addData(three_G_to_C_reverse, "3'G>C"); + damagePlot_three.addData(three_G_to_T_reverse, "3'G>T"); + damagePlot_three.addData(three_T_to_A_reverse, "3'T>A"); + damagePlot_three.addData(three_T_to_C_reverse, "3'T>C"); + damagePlot_three.addData(three_T_to_G_reverse, "3'T>G"); + + + } + LinePlot damagePlot_five = new LinePlot("5' end", threshold, height, LOG); /* @@ -803,48 +831,28 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep damagePlot_five.addData(frequencies.getCount_T_C_5_norm(), "5'T>C" ); damagePlot_five.addData(frequencies.getCount_T_G_5_norm(), "5'T>G" ); - // three prime end - // red - damagePlot_three.addData(three_C_to_T_reverse, "3'C>T"); - // blue - damagePlot_three.addData(three_G_to_A_reverse, "3'G>A"); - - // purple (insertions) - double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), - frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); - damagePlot_three.addData(insertions_mean_3, "insertions"); - - // green (deletions) - double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , - frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); - damagePlot_three.addData(deletions_mean_3, "deletions"); - - - // gray - damagePlot_three.addData(three_A_to_C_reverse, "others"); - damagePlot_three.addData(three_A_to_G_reverse, "3'A>G"); - damagePlot_three.addData(three_A_to_T_reverse, "3'A>T"); - damagePlot_three.addData(three_C_to_A_reverse, "3'C>A"); - damagePlot_three.addData(three_C_to_G_reverse, "3'C>G"); - damagePlot_three.addData(three_G_to_C_reverse, "3'G>C"); - damagePlot_three.addData(three_G_to_T_reverse, "3'G>T"); - damagePlot_three.addData(three_T_to_A_reverse, "3'T>A"); - damagePlot_three.addData(three_T_to_C_reverse, "3'T>C"); - damagePlot_three.addData(three_T_to_G_reverse, "3'T>G"); - // create Dataset - XYDataset dataset_three = damagePlot_three.createDataset(); XYDataset dataset_five = damagePlot_five.createDataset(); - // set equal y axis range - double ymax = Math.max(damagePlot_five.getY_max(), damagePlot_three.getY_max()); + double ymax; + if(!ssLibProtocolUsed){ + // set equal y axis range + ymax = Math.max(damagePlot_five.getY_max(), damagePlot_three.getY_max()); + } else { + ymax = damagePlot_five.getY_max(); + } + // create damage plot five prime JFreeChart chart = damagePlot_five.createChart(dataset_five, ymax, threshold); - // create damage plot three prime - JFreeChart chart1 = damagePlot_three.createChart(dataset_three, ymax, threshold); - - createPdf("/DamagePlot.pdf", new JFreeChart[]{chart, chart1}, file); + if(!ssLibProtocolUsed){ + XYDataset dataset_three = damagePlot_three.createDataset(); + // create damage plot three prime + JFreeChart chart1 = damagePlot_three.createChart(dataset_three, ymax, threshold); + createPdf("/DamagePlot.pdf", new JFreeChart[]{chart, chart1}, file); + } else { + createPdf("/DamagePlot.pdf", new JFreeChart[]{chart}, file); + } } @@ -929,8 +937,16 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws String title = splitted[splitted.length-1]; NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH); DecimalFormat df = (DecimalFormat)nf; - String read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie; + + String read_per; + if(!ssLibProtocolUsed){ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie; + } else { + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie + " | ssLib protocol"; + } + Font fontbold = FontFactory.getFont("Times-Roman", 18, Font.BOLD); Font font = FontFactory.getFont("Times-Roman", 14); diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index 05080d6..9af04a8 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -114,6 +114,10 @@ private void parse() { "Use all reads (mapped and unmapped) to calculate damage plot. Default: false "); options.addOption(use_all_reads); + Option ssLib_used = new Option("sslib", "sslib", false, + "Single-stranded library protocol was used. Default: false "); + options.addOption(ssLib_used); + HelpFormatter helpformatter = new HelpFormatter(); CommandLineParser parser = new BasicParser(); @@ -174,6 +178,10 @@ private void parse() { communicator.setUse_all_reads(false); } + if(cmd.hasOption("sslib")) { + communicator.setSsLibsProtocolUsed(true); + } + // Plotting if(cmd.hasOption("title")) { diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index 91942ec..ea8a39e 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -158,9 +158,9 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea if(actualRuntime > 60) { long minutes = actualRuntime / 60; long seconds = actualRuntime % 60; - System.out.println("Runtime per record: " + minutes + " minutes, and " + seconds + " seconds."); + System.out.println("Runtime for processing all records: " + minutes + " minutes, and " + seconds + " seconds."); } else { - System.out.println("Runtime per record: " + actualRuntime + " seconds and " + runtime_ms%60 + " milliseconds"); + System.out.println("Runtime for processing all records: " + actualRuntime + " seconds and " + runtime_ms%60 + " milliseconds"); } } @@ -207,8 +207,6 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, private void processRecord(SAMRecord record) throws Exception{ numberOfUsedReads++; - - /* If MD value is set, use it to reconstruct reference Otherwise reconstruct reference it based on the CIGAR string @@ -250,6 +248,7 @@ private void processRecord(SAMRecord record) throws Exception{ } } else if(record.getStringAttribute(SAMTag.MD.name()) != null){ + // get reference corresponding to the record if(record.getCigar().getReadLength() != 0 && record.getCigar().getReadLength() == record.getReadLength()){ // if(record.getCigarString().contains("S")){ diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index 301e295..260b8bb 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -40,6 +40,7 @@ public class StartCalculations { private double xaxis_min_length_histogram; private double xaxis_max_length_histogram; private RuntimeEstimator runtimeEstimator; + private boolean ssLibProtocolUsed; public StartCalculations(String version){ @@ -64,6 +65,7 @@ public void start(Communicator c, RuntimeEstimator runtimeEstimator) throws Exce xaxis_max_length_histogram = c.getXaxis_histo_length_max(); use_only_merged_reads = c.isUse_merged_and_mapped_reads(); use_all_reads = c.isUse_all_reads(); + ssLibProtocolUsed = c.isSsLibsProtocolUsed(); speciesListParser=null; species_name_list=null; specieHandler = new SpecieHandler(); @@ -114,16 +116,8 @@ parse species references (-sf) and run DP for each reference in the file // init Logger - logClass = new LogClass(); - logClass.updateLog4jConfiguration(output_folder + "/DamageProfiler_" + ref + "_" + speciesname +".log"); - logClass.setUp(); - - LOG = logClass.getLogger(this.getClass()); - System.out.println("DamageProfiler v" + VERSION); - LOG.info("DamageProfiler v" + VERSION); - LOG.info("Calculate damage profile for species " + ref + " (" + speciesname + ")"); - - + initLogger(output_folder + "/DamageProfiler_" + ref + "_" + speciesname +".log", + "Calculate damage profile for species " + ref + " (" + speciesname + ")"); // decompress input file if necessary if (input.endsWith(".gz")) { @@ -156,7 +150,7 @@ parse species references (-sf) and run DP for each reference in the file damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); - generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, speciesname); + generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, speciesname, ssLibProtocolUsed); } @@ -193,13 +187,7 @@ parse species reference (-s) and run DP // init Logger - logClass = new LogClass(); - logClass.updateLog4jConfiguration(output_folder + "/DamageProfiler.log"); - logClass.setUp(); - LOG = logClass.getLogger(this.getClass()); - System.out.println("DamageProfiler v" + VERSION); - LOG.info("DamageProfiler v" + VERSION); - + initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); // decompress input file if necessary if (input.endsWith(".gz")) { @@ -236,7 +224,7 @@ parse species reference (-s) and run DP damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); speciesListParser.setLOG(LOG); - generateOutput(damageProfiler,output_folder, inputfileNameWithOutExtension, null); + generateOutput(damageProfiler,output_folder, inputfileNameWithOutExtension, null, ssLibProtocolUsed); } else { /* @@ -255,13 +243,7 @@ parse species reference (-s) and run DP } // init Logger - logClass = new LogClass(); - logClass.updateLog4jConfiguration(output_folder + "/DamageProfiler.log"); - logClass.setUp(); - LOG = logClass.getLogger(this.getClass()); - System.out.println("DamageProfiler v" + VERSION); - LOG.info("DamageProfiler v" + VERSION); - + initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); // decompress input file if necessary if (input.endsWith(".gz")) { @@ -297,10 +279,8 @@ parse species reference (-s) and run DP null, LOG); damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); - speciesListParser.setLOG(LOG); - - generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, null); + generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, null, ssLibProtocolUsed); } @@ -322,8 +302,25 @@ parse species reference (-s) and run DP } - private void generateOutput(DamageProfiler damageProfiler, String output_folder, String inputfileNameWithOutExtension, String spe) - throws IOException, DocumentException { + private void initLogger(String outfolder, String log) { + + logClass = new LogClass(); + logClass.updateLog4jConfiguration(outfolder); + logClass.setUp(); + + LOG = logClass.getLogger(this.getClass()); + System.out.println("DamageProfiler v" + VERSION); + LOG.info("DamageProfiler v" + VERSION); + LOG.info(log); + + } + + private void generateOutput( + DamageProfiler damageProfiler, + String output_folder, + String inputfileNameWithOutExtension, + String spe, + boolean ssLibProtocolUsed) throws IOException, DocumentException { if (damageProfiler.getNumberOfUsedReads() != 0) { @@ -340,7 +337,8 @@ private void generateOutput(DamageProfiler damageProfiler, String output_folder, xaxis_max_length_histogram, input, LOG, - runtimeEstimator + runtimeEstimator, + ssLibProtocolUsed ); outputGenerator.writeLengthDistribution(); From 6a7d19cee97622701f490cb7dff096bdce9fdaa6 Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Fri, 20 Mar 2020 16:50:29 +0100 Subject: [PATCH 04/22] start implementing GUI for results --- build.gradle | 6 ++ .../{MainGui.java => ConfigurationGUI.java} | 12 +++- .../java/GUI/DPMainGui/ContentUpdater.java | 7 +++ src/main/java/GUI/DPMainGui/Controller.java | 56 ++++++++++++++++++ .../GUI/DPMainGui/DamageProfilerMainGui.java | 28 +++++++++ .../GUI/DPMainGui/SidePanelController.java | 56 ++++++++++++++++++ src/main/java/GUI/Plots/DamagePlot.java | 21 +++++++ src/main/java/RunDamageProfiler.java | 4 +- .../java/calculations/StartCalculations.java | 7 ++- src/main/resources/fxml/main_view.fxml | 10 ++++ src/main/resources/fxml/sidepanel.fxml | 20 +++++++ src/main/resources/logo.png | Bin 0 -> 23996 bytes src/main/resources/styles/global.css | 41 +++++++++++++ 13 files changed, 263 insertions(+), 5 deletions(-) rename src/main/java/GUI/{MainGui.java => ConfigurationGUI.java} (96%) create mode 100644 src/main/java/GUI/DPMainGui/ContentUpdater.java create mode 100644 src/main/java/GUI/DPMainGui/Controller.java create mode 100644 src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java create mode 100644 src/main/java/GUI/DPMainGui/SidePanelController.java create mode 100644 src/main/java/GUI/Plots/DamagePlot.java create mode 100644 src/main/resources/fxml/main_view.fxml create mode 100644 src/main/resources/fxml/sidepanel.fxml create mode 100644 src/main/resources/logo.png create mode 100644 src/main/resources/styles/global.css diff --git a/build.gradle b/build.gradle index 0386843..c72e527 100644 --- a/build.gradle +++ b/build.gradle @@ -32,6 +32,10 @@ sourceSets { java { srcDir 'src' } + + resources { + srcDirs "src/main/resources" + } } } @@ -46,6 +50,8 @@ dependencies { compile group: 'com.intellij', name: 'forms_rt', version: '6.0.+' compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' + compile group: 'com.jfoenix', name: 'jfoenix', version: '8.0.7' + } diff --git a/src/main/java/GUI/MainGui.java b/src/main/java/GUI/ConfigurationGUI.java similarity index 96% rename from src/main/java/GUI/MainGui.java rename to src/main/java/GUI/ConfigurationGUI.java index febf253..b3e6c78 100755 --- a/src/main/java/GUI/MainGui.java +++ b/src/main/java/GUI/ConfigurationGUI.java @@ -1,5 +1,6 @@ package GUI; +import GUI.DPMainGui.DamageProfilerMainGui; import GUI.Dialogues.AbstractDialogue; import IO.Communicator; import calculations.RuntimeEstimator; @@ -23,11 +24,12 @@ import javafx.concurrent.Task; import javafx.util.Duration; +import java.io.IOException; import java.lang.reflect.Field; -public class MainGui extends Application { +public class ConfigurationGUI extends Application { private Button btn_inputfile; private Button btn_reference; @@ -224,11 +226,17 @@ private void addListener() { (EventHandler) t -> { if(starter.isCalculationsDone()){ primaryStage.close(); + DamageProfilerMainGui damageProfilerMainGui = null; + try { + damageProfilerMainGui = new DamageProfilerMainGui(); + } catch (IOException ex) { + ex.printStackTrace(); + } } }); + new Thread(startCalculuations).start(); - //this.primaryStage.close(); } catch (Exception e1) { e1.printStackTrace(); } diff --git a/src/main/java/GUI/DPMainGui/ContentUpdater.java b/src/main/java/GUI/DPMainGui/ContentUpdater.java new file mode 100644 index 0000000..daf8947 --- /dev/null +++ b/src/main/java/GUI/DPMainGui/ContentUpdater.java @@ -0,0 +1,7 @@ +package GUI.DPMainGui; + +public interface ContentUpdater { + void updateDamagePlot(); + void updateLengthDistribution(); + void updateIdentityHistogram(); +} diff --git a/src/main/java/GUI/DPMainGui/Controller.java b/src/main/java/GUI/DPMainGui/Controller.java new file mode 100644 index 0000000..a023bf8 --- /dev/null +++ b/src/main/java/GUI/DPMainGui/Controller.java @@ -0,0 +1,56 @@ +package GUI.DPMainGui; + +import GUI.Plots.DamagePlot; +import com.jfoenix.controls.JFXDrawer; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.fxml.Initializable; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; + +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Controller implements Initializable, ContentUpdater { + + + @FXML + private JFXDrawer drawer; + + @FXML + private AnchorPane root; + + @Override + public void initialize(URL url, ResourceBundle rb) { + + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/sidepanel.fxml")); + VBox box = loader.load(); + SidePanelController controller = loader.getController(); + controller.setCallback(this); + drawer.setSidePane(box); + drawer.open(); + } catch (IOException ex) { + Logger.getLogger(DamageProfilerMainGui.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + @Override + public void updateDamagePlot() { + DamagePlot damagePlot = new DamagePlot(); + } + + @Override + public void updateLengthDistribution() { + + } + + @Override + public void updateIdentityHistogram() { + + } +} \ No newline at end of file diff --git a/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java b/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java new file mode 100644 index 0000000..9f703f2 --- /dev/null +++ b/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java @@ -0,0 +1,28 @@ +package GUI.DPMainGui; + +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Pane; +import javafx.stage.Stage; + +import java.io.IOException; + +public class DamageProfilerMainGui { + + private Stage stage; + + public DamageProfilerMainGui() throws IOException { + + Parent root = FXMLLoader.load(this.getClass().getResource("/fxml/main_view.fxml")); + stage = new Stage(); + stage.setTitle("Damage Profiler Results"); + stage.setScene(new Scene(root, 1000, 800)); + stage.show(); + + } + +} + + diff --git a/src/main/java/GUI/DPMainGui/SidePanelController.java b/src/main/java/GUI/DPMainGui/SidePanelController.java new file mode 100644 index 0000000..07d871e --- /dev/null +++ b/src/main/java/GUI/DPMainGui/SidePanelController.java @@ -0,0 +1,56 @@ +package GUI.DPMainGui; + +import com.jfoenix.controls.JFXButton; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; + +import java.net.URL; +import java.util.ResourceBundle; + +public class SidePanelController implements Initializable { + + + @FXML + private JFXButton b1; + @FXML + private JFXButton b2; + @FXML + private JFXButton b3; + @FXML + private JFXButton exit; + + private ContentUpdater callback; + + @Override + public void initialize(URL url, ResourceBundle rb) { + + } + + public void setCallback(ContentUpdater callback) { + this.callback = callback; + } + + @FXML + private void updatePanelContent(ActionEvent event) { + JFXButton btn = (JFXButton) event.getSource(); + System.out.println(btn.getText()); + switch (btn.getText()) { + case "Damage Profile": + callback.updateDamagePlot(); + break; + case "Length Distribution": + callback.updateLengthDistribution(); + break; + case "Identity Histogram": + callback.updateIdentityHistogram(); + break; + } + } + + @FXML + private void exit(ActionEvent event) { + System.exit(0); + } + +} diff --git a/src/main/java/GUI/Plots/DamagePlot.java b/src/main/java/GUI/Plots/DamagePlot.java new file mode 100644 index 0000000..51aaf55 --- /dev/null +++ b/src/main/java/GUI/Plots/DamagePlot.java @@ -0,0 +1,21 @@ +package GUI.Plots; + + +import javafx.scene.chart.LineChart; +import javafx.scene.chart.NumberAxis; + +public class DamagePlot { + + public DamagePlot() { + NumberAxis xAxis = new NumberAxis(); + xAxis.setLabel("No of employees"); + + NumberAxis yAxis = new NumberAxis(); + yAxis.setLabel("Revenue per employee"); + + LineChart lineChart = new LineChart(xAxis, yAxis); + + + + } +} diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index 7491f54..bf0ab14 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -1,4 +1,4 @@ -import GUI.MainGui; +import GUI.ConfigurationGUI; import IO.*; import calculations.RuntimeEstimator; import calculations.StartCalculations; @@ -31,7 +31,7 @@ public static void main(String[] args) throws Exception { if(args.length==0){ //MainDP damageProfilerGUI = new MainDP(c, starter, VERSION); System.out.println(VERSION); - new Thread(() -> Application.launch(MainGui.class)).start(); + new Thread(() -> Application.launch(ConfigurationGUI.class)).start(); } else { Communicator c = new Communicator(); diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index 260b8bb..f76482a 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -41,6 +41,7 @@ public class StartCalculations { private double xaxis_max_length_histogram; private RuntimeEstimator runtimeEstimator; private boolean ssLibProtocolUsed; + private DamageProfiler damageProfiler; public StartCalculations(String version){ @@ -93,7 +94,7 @@ parse species references (-sf) and run DP for each reference in the file // start DamageProfiler File file = new File(input); - DamageProfiler damageProfiler = new DamageProfiler(specieHandler); + damageProfiler = new DamageProfiler(specieHandler); String ref = specie_input_string.split("\\|")[0].trim(); @@ -405,4 +406,8 @@ private static String createOutputFolder(String path, String inputfileNameWithOu public boolean isCalculationsDone() { return calculationsDone; } + + public DamageProfiler getDamageProfiler() { + return damageProfiler; + } } diff --git a/src/main/resources/fxml/main_view.fxml b/src/main/resources/fxml/main_view.fxml new file mode 100644 index 0000000..3b6adca --- /dev/null +++ b/src/main/resources/fxml/main_view.fxml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/fxml/sidepanel.fxml b/src/main/resources/fxml/sidepanel.fxml new file mode 100644 index 0000000..e946c40 --- /dev/null +++ b/src/main/resources/fxml/sidepanel.fxml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7c839a95f949ed8f987eb55f9a9629ec1a69e0be GIT binary patch literal 23996 zcmce8cOaI18@9b?Nw@47b!R0ZlD$J3G`Oua6e`(!W`;s#BpNDNMJanHp=6cJGBYAH zeaH2_@Av2T@Atf(p7-%^-`92h&T$;ad7SqZi~R=dEL&KpsHoVD40R9SpKtK@Lna3N zIg)t$8UDfGU}B(4wNCu+cIEvPe23ZH(B>i)73)UgZ)&QW862wBVDb7-UG7%E(Z^;_WodqRKBF27bYJp(yq--OAXSuC^4|Qc=BX%MiEA-1O_?FGt0^UpTL5xMY_k zhFeJUXuCRW{CM_8-WqSTnX5z1|N9TOkiG^fhPeOdAO9a;U_~oVvWi}~(9_d%q?DAfn>V+p2yoy_NlEGU zojYPxFM>8x4jjOV6%-VB|5;O@x?NGR#cS>p_fH!W6BBPgzud=<*}i=F;=MAmU4ojQBAzO$2ymzP&wUOqTH zyuskN`@qMKwG&H8X=zcRp)?1N99b2RGBnoK)~5OX{kw&QMa}0*KT8XXg`VmoW@hY7 zO-=I3%8?Nf^pR|Qp`tpG`|t~zoTMwOFG}PjCF!&MzcYtxi)Lx~t!SAa*VkvjO>!~O zRsLhU)gF2M`lgJGjN$R|@R9l`onyy-3$I(8|NQDobE0rcny!I?K_O*|Utal)EH zJ5Ro;38tp~w@AsMT3Vj6;^E;Lo_c?uc>Ioz;sXN%ogY5X8yOk3w6^AymTr9b@L^GT zd6b28_&$-~r%#o5Hf?HM|FN>t^y1<~XSti*gGY~Y%gT7!+1Vcy78+Ptz2_e^*}Qr4 zn=B1}T;h61xQ82k`pU{>T|K>#ukE+ImnXS#T)GadvJJJ--|KQ=n(5kAvZ{EBS;bGwx7Eb*B{epVXzdz5OIJR6BP2b}s`}NHYT1m;f zK>`$Q9i60%3^v|adK`CAzw5QsREO4NNsGgW^)FuBiFd$}2Iu8T6j_rWwYss;X;0e~PN8kiLHX>QK|UW9wGNvF1brOH0c_&D`6!gFk&b zE+HWyvS$xJqH1z>HvH~g$>rtcnh|&Ti(gHd=x81vea3=d#uKZZ?JrGAN(#v}NF43T zHR$Z>3Q0`l6c7-gI5>p<`Qz_8Sh1bw2L}aZWo5k=N9n!QZ40vukxwa7W_6M5{FKwDWfg@wg^{<8)GGo<~bj-8$GuV250-Bqlgp5mse`S4*=`T4=nw6x7M zw6uJbuAZLA>}=uL*;&e&GckA`>b}cNTg|f?N?kfAZf=Q)-nxN-EzJpnI(~k8;^N|p zyyk6DQz$>CKMY@ZAuS`L<>8?qq!}3Z=8Y*2FYhQ)r1C=6_3cMSW96#WG?^6+SXprk z3dSQV$7(`o#RQy38?LxtxS%~$6(G8Odn}GJV~-aHVnD@vL1fK;@3w8*L_|fYB_$<^ z%v|~Qk*x^9kW*aDjVgpJM!{$*ac<)h79J9})=v<)a@QoSuB(fio}OM>TDoSuHD&Qj znw{9*y;aRlY_W}X@9vrupC431c>aAvwY1-pgbe8$7^rJ+XFo2xnU$Bk@BDdL>e$DR z$<(n~Swcvo;!|B>hK7cepWnaW^y=kQ*n2^6C_``awR%CdY_GrO(I1B7lLYr zaP~l?)1)RRZ+PYZb3?%ImBvKPf6;h|l<(uMc<_iq`{U*&Cai%!ziduVPZuGRXV=F= zl$4c67e?yoB*GZjX`jf`4tYe#2hVv+YW zyhxtl;NV^w*6a?(?2cwUB_hU4N)*#?-Ev%880qZobvdr%;FG1+H*VN34A=G*+0)K_dO?etA2ro^<^>J*phi zj!`>@D~dx<8-<=4J%;t@v11DUYwm2qdj(=Q%jw(Oi~jlZr|8^AWi|m7i}331?(UkQ zAz{a+I4v8S{-N(8YHDikQ|}~Q`--Rq1qE^LQo`N8SLb!i%{e==H4Ti6n9*0(V6kVDix25iw*~PZByv(ym{#bUdes1t(vCq;;Jlk620Kc;9 zK7W7pz<)noq_=HTe3Jk0Aqz@O^F($~0{&W8rrf-Fv&gxPcXp^+xWB(YIwnSY-#)6U z-*bD^eZJGVD)Xb@<0(glhtnN?Y^_yOH?hP=VP6eT4kV*YhKJ-kN>ZT}8)j!t&v8k(9)*rlbVjp1~j`~KL5B4}~s zNEF%u>f`MvPdGMi-QSQTZeVfn;BuNhNsx@bMI;cSi<_T6)?=)xc3|M9Q@eB#`B+)p zh)vnKkCAA$l$o9agnnpg>CThwH|fzViJL|t-{Upc&}$dePL*IGt!rq=^y<|sAcch? z`nY`}HA@p6d~O_Qi6j!K=Jjh9l%1loGKQ%7S~N5ThX$s{*2Oe>dU~kx5!Kbz(JqUN zi$0PrH+H&kJbwJx{m+`mrAwD6pPqY=)GkT0v9WdDHy1|WitgOG(I7#fwy^qN%uH`# zu3dE?9T~sse(_>GDvAdJ00G3c{m2ttOH1zYFJFk7_V4fSoli>9a0v)ewf^sS^?VL+ zh_NvXihWUWu_)zAe7xSNQ_{yzoG1=j4_x@^e+`cjNCKU}e@BOdlasDW+bf@?;cwsK z@nT{1Be$PEy+)l1RO960;@EXZukYE}&1J6r#2r0<{+!bD*hXGKK?_lhZ-&ZP-K%MB zWgcsauWwD+Ix;oY`uyIp^79D2AHpXtdkgyI8du-A!S}?ra+~&_t!6jr9335(zkS?{ z3=JQC^yrb}NL|F$Yu6fLHf<-__t|m#$CO&wTbt7bb!2H=O-nOybtMC(;U~h85snSf z+>~N#i$jMR=d0HfK0G?2gKo4@$~3s3V8`6&O4eh?jy*p9V#AFaH&i@E>B`Oz#vFQd z*nZ&YX*8soJ9@E(%Er<>4u60B7+(6R;=fiDz17!lWnn}I=dsV$R_K=UIc;ZWNi-rp zipPZubyWesNpyC23!*LP>+2Wx%L5+Jq&|PH^5(`)#BS;l6k89^Q}Ca@?@mcdC1_u0)qMT(EaX8|6LU&&dAUotJvTSEw4B^l zy6o>{To2k)c&UK8H`lXg&!l(k&_lhrdFvJt9605A91fZZP?`7-8a#W`8;bOre->yJ z6%|R8#g&yvoHLry`N4{azCP>m@p1Vlp4|^DpL;KgA;N}c!a93;^!4=UbIZ5|1lZ){ z$I3Yn;YNVELXlmntb?T)DjuQKsaXe_d1?y_3Y@wAq{-Pipd%33LLipmTH53d z_hkw$&0b7)UacjvDG zZxYWBPefqPWj38Cj>i9l!ulafPLzGnA(yGvQVU8>oxGZh44K?eJ`@-WOhsVEcX>t& zc&I38-s(atbAznFJJ!dJ)%W$0u3x{t_PtGx@0&(_BzwJZ&>w2$TYrbBZTDcP~;naE%&&xnI6K z*Hzl7%1WQQ<5*eE$B+CgD=WCty4o;Cf()r%{3-%MgOH;m$Hc^-2J35SQLAfc@Oj?q zFLe=DQd+L2CZSWm$<`DGfFlT1MTHuw_`=`SAsu7mm=PNwd4-d2NN+M!HzH3!KOzzn z6Pc`~-;PdB8rBs#HYX_5$%pI<9t!+z)=+xMT+oVAj7pc`{Ndpt^shSNJmTWm^lLBR zIMA)bP=IL3Xszgg+NP##Jq5>_sp6}vH4_B)tY~Q~Zu6W6-p~qTs0CI65Ot&DeU0-4 zK&=IIO}cuON+{9bz}MvDI zdCnZ}?(L0z`jV(B&0{~NZL;R>YfB_19vvaFG9?a3Fa4{w#H)swbd~o}Rl%IVt0lidU`j>BY-@@9u zMPv=Rp%Ll~5EedMUS6&P#W5*6Lds1Svqc`t1&y4HW z^=e8kd@+7=a~JFO!;kmr=+J_4f)o$GBa0opUEObm&3~^jL3qG|N62MmW$EfZiZZ*c zZEO^34p>`9Bg)WsBE8p8UO+wL1XRBdF{YzU>wsP1cBR(8&d##oeSkzLzgNB?W#^tH zm6UgTnD@&+9F$a2;t}9rL|@V|Fkq~!ulE>l;fB-%H|5Fi9iC|EU%^VO$a_`+^KwM0IESIB>&CC=G{57?eCN(2NfZ$X> z%gEv#vbL|H!LGSOt3Af_iMK$@c1QYwDjU9J)mu1p@Sr?er0b{W+~?1qH#9SA1Z@Kh zh*(~}G&w!34Wuk3CB?+TQit+p@8m?cefxIwU*vmTTN~@9O`AxXf$D$${;mCT!P45A z30bRXu#u0?NV^pJ5!tTl&(Mv-doN9L@ygkxVc)kRa_m$)>KZ z?#o_Z5$3!)H#qLq)7^a=+E8O-qxAOe1i?+ZapMZ2^bV*j_yrxgtE(%#borpmlng(w zkWd0z;M(us;@h{gYOep;iOx#U7@$`=28O!NpM?^IHTBUHQ5K?bK^N?R;Tew{=`9cB zs$T!M2UqomX*Dz~tP33z;s#%leKEPNWg>Z0?!e0(MS-E|ZJvMo#n(DRAz^}sS0#6E1N%Ucl%iEs~Dyt8oQz5#w85|!cp z{Zc}aVmUacmX?;_d-tTizRiqf-7Gu&{Yx9dhKK`@2B3*JP%}^}`Dt=wWF#PENO}2g zKsFXWK0caM1ia}jWp;x91O#XxB7wAMz-Y7K4a_!bh+W$T>y+KQDmWiSORM8EhK_%=_neNg)ki z-8mBghSTJLW1K0sZpBV?WT%)WKYO-o+xG1Qj~E?wfHXp&@I!|V^;P=qhRoB|-_N{r z=T3wh`9uW|p=#_p%e(jI_(pxp3%ImXr%&7ed0SSdJU%fI)-izx9l>_5*qZ#bynJl9 zHY{DyndP2&HiwIg3!)Fz$Lzxc7HW_al17M;pXIL0Dm(d^*M&F$^&00z3i&_E-|dxcY-A|yUO zEfh(dx4KZGrAt?5=RPDMI$B{G}`1|`4#Fc10;E4pV04rig z=z+`-B*QM~@2)J(poEUSzfBuT<46iLIO&F)yUr4HRew5t|H8|Pis6X~Mvkbkwluko z$tEEY^&=t*3f#`l&PC6jIlnU8pS|~Q&+3KRP!Cc85A8V;z*tc{#66{WOCt? zr%)m6jp*(0jtF-qCZ?LdzgMZLz&gb3NqP$gaiqng69oJ)yQN&)+|2mm#S3V*I>_Qn zo}L~{U(LLIe6*x_#DGjLT)2Q(tMwWRhysrrTO4afWH$iLqipEbC|(#hq)A2D7n7D| zB62Rb}zd$6E)o@7bM##0^@DCo+reZfX4QYed+%}cHA?TrM&9`qX0Lg7Wt2PZ2k zEe!)ThEhUB1!>f}I#2^`f{;*<7(^4V(T=b`+w(XCA{;KCPp_>vGx_f%)lSfU)9k&1 zMDFGprHIJc8yLbkr9vw7=r>C4VtR%g$s&QD7mKLrQJO}b%3>rLK@n@3c1oZ zva&wU_z(&{v<-WEd+YM^f*1%uV**bKfz%ux5mDRNNRKkNHRCRl3H6hUB|^n>nrCjP zniGMTcmMvzB8v=XR8FD-0=E`9wQd0L7Lk!*Mx`bKv$$9R32N`^YWh|N;fpTdC&ziO zvNAI+(CyRnB(6UoQh2~uyB85!226q3djlvG3Kd6`_<`E{y_v4AuJZPEbpA{2yPvy{ z&;U*>Om>O;|NYU6XyjH+d+9Y_2f1d?;s3qJokwid@n=8FZJph zFro19@ZsqXkD}w_BS2XI(I5yaAYDGa^x}ko48hsnsXkTCj)Rer5t_UMjsAoSw`PmaI%u0Or~(#-TU4OK&Pb4m|4)JA}ajc*Uw+H!D2>1I}8?kId2suv?I?H)dQ1dT(fHPTWv|JE&j zg8rT??fU$g1Hg>Inm9CJVc}65C=nxbbN`GpBZ4F;le+QkCmk^&iM!+E;2;Kkeg#zq zC=__s;*@80xK8${x}20 zgYx>C%;e-`&65)^2_5X++<~JIsZ69+WYQ?a^{Cp!@2~Od?4XB}(c6R0^ z_5fE+fT?`-c971+GMQ)@Is6NjZlJq?Zjos1iG~XzfwBkriWzT>`47&U5Y7o%3zy1d z4e&+KtmT8C^O#IJR?{`fcW()x)c$FV{w% zdyEZ_jUhy!r4rBv>8jxJRsb^4#{473foJN%nKcqNS>1zzs~EPvjbG^$7u3AEwQ_VH zMAhSwzh~&=#;OVya7Rf;VrCRD~k{XKgWW<=}}E z@j%0X(+=%7cNG;C1*fEJ92=>Qzkco7)#|gSP7U93s|v}<5fxnv2??R1+PHC}n4c4c zvX5ymDC*0XFI%h^~U&4PTl7muF;V5(*vk(A+zBXuf^> zhQ|Z-ZH`D74@{uqw(MfTXlzzN;;*?k2_pbdclnbG&GGzE82u4LK!T8FMTo6|szK|L z&>pBSs}?Z$zg~bS&do+)|E{;TwT(fS*9Ttv^<#!nLqp@#nKRl5O-zGTF3*w(5ud1i z1V`(3Ta7bM(;dL z@Ad;p;G!Z129DO*K*otg6rg>gIA@DmcLijOoFj{f1TQ{&_;6cmq*gS)gJOMg$?Ic`RG1L=?!BL*69w^!8MrwnnRvm zwy%dp#$7PcoSdBSQgn7g(X~O;9M2oW$EOU6mU}4r0y$T~fT;=U5Gj)6ORyot;OBWx=08sk~nXTBd zS+OEviu1*NhXFg=^gIc)T=}y-*7n=4I~>$iHMD5y^#i_7=Hi$ zR_M%xJWyxTlpwfWQAQQch9(W4&D59GD0rb7L&5j4$^RwCzLJE-{qNZ6FLRZe1i7pZ z{9EMOuc#=~k8TJkXlP;**62XAcSNhBcPe}*7!DBgI+Ii~HD+G9xr8U;Gqe1)b2uGH z!x3nJMs%~EEBQfrfut}9jk~;=3X-d1FcK2yM*szkTRr~%@+78gc zRoNg>z-1}U&Uz}bxGsE8>ErqKihh2647J&q(*u2SL&yNM z0seOQHt@{4%3oD<&DPeIP_zIRuYi0IG86Gs5%6R2s2V@@C#;VgY38c%LzL*S2c76$)xvt`SKCHNF{leTQ)nxXurJoR=MKV7;I$S`&>%)b%W+nExdP1L#g!k_J%o$1~v%|UtVKcZ9BW{u3t`WZtL?5Y=iZX`?w48 z=jw)qgoN_6@yez(ij*2E%ncm>{rP$7+&O1cV+ar_j@5;M;%D?DOAwSm;}jf1oU1i4 zR6;4BP=et@pdlz0IP?gakwZY_VZ!e7pF}9C=pDI-7w_q>FSN9^IbyuSHYop)f%Z>+ zlhFs8$)nAeWb)v5fil3L4X#y@60>S{F~8W+a=SF!n0Be*TgXL2Lcn#t#+wxzYb1YWA-pIG6L8Wf(oQF z7_nb=$R+G^nq6RPdM#>E7~Z`#vazXY6gZ8@7T8u=UbC@~A!*is`&d3QI;#DyjmH{! zzVO~$Gs&@fDr=h>1x>PYl9VAoH@u z^6n6;wC@f-i~0@F2QfZcNR?Icdmpd}_ucgJ0?vSILXi*WkWCIK>UpP&F;WIv%=1Z- zjabH862t|i8UlzO1_+j3Ipue%O-NmXX!M4R@(cH=>Vfi^tO2uHGfWN~NH&~agI9qt z;lOI4Ds&<#IqPJQRc`e;GgDJ2njbt(KWvBip8HnYhu6!?ODy6kWPg~`2xk(TgV}tR zw^eTBdudr+Ipf!DZJ6DpcH4l^`Yj{Hr$gykN!h{y0e{zdqbv^}j)Yc*TF*q)R~4}5 z#x6M-nUFho?nIyOgL*nVGD3}B4CboP6f^bx@t|MB=MNB#n!Vp+s<4GqNL{4T9*Br& z?>~nRWJMSYR(mgoI^F!fw8Xc4>*UUVZf7oWya%30y1wxs!#P}@M$9b0-_G#b{7|yS zkHUu!e;uBXf;R+$&-Z6wd#Af_Ls8&R(46vzSHIdka6Sq|8259to7;Sl*HI`IHzto* ziuPm9&4OzaP`ecUDj8o$wrV`*V(A^zpEC^hX>o!!yRvR;ySv=1#PbCl1 zkW?sB1R#bYan)X#g}m(A2l33X;^q_nm9mTSpl-TM+*A-gw<&gLf4D1cB&|AHW3qzyHC&pAObQWL?* zg2CP-Qj!l&t0*ca`wyX<r3z-Bl>J( z!HX}B11i9vCInH%S^B_%-^Z!^E$qwXs{bTgo(P2hwl#8UdK$HgMmy)KrAz-yFF9Bd zP&P1f<~!Pq1aNB6u4L{*^kY<#JLn9dH7?r|o;t`JD6a+wm!Xaj?jKfG*2tdX`1p3a z%d~B%mk?GkQ)r-l@$#i3FtXDLdj!!i>T5Q!+6%m$v$Rxk#kHCcX2hn8?i zq^73oR+b=fK~bHk&ms!Y4fy^?`mA4Ekklc)@(X$Pa{BcQO=P2kJw#vYic2zZ#;^dJ zVjPfLRh4zgN?5~}2lwgtI0I1?l-L$0-KAX-v-iYIx@<&u<&5{l+f3b}&}lUxf^!L| z1S48LRR?81eQ7}fKIi0>JsyqO0I0LI6Zh;9yMT!7pnrVAk1BUYp#bQDlR$AoFQx|6 zBUEWrV@hei`=v`xvo5XBhu`~v!#9*#w8c#hJ`+BwcI~YyrnilKhy5WY5y~)RJ^W|- z0r+e&3W+KRTJmz8*us79#+m&a4j(*tySO;X z-^>HBeADxa3c`Xho`s2gJ-iMWjuTFr{-UfJkSZo{r#stPNa>;*yejbYw83=bke?2Arwo-{tS#y&E?ot9+~dK`HS>VFb%7$Uds7 zbvMClwomK(97u)p+Z_bFI&W)XDz3NScQj?|jvevTv<%BzA~PWn zcHJ>=FTKPF4__B^6?z1rSYp6B3fCuw3)72|gm&cGUvl>dcS?{3r6S4^GSODYMi}M5 z*yVTcCQ1e7j7DyxLoS4{25b=nl85OpZa*UDj(Pd+BwAmq-1+A@E43DMK?owTN0oTM zi|xCI_QCItn}~DPzf^DA>q_r~*Zg-fS(MO3XGBLZy01Of)F(aU%p|O2g zI;=Tn4?jFf&xinpkS-mr!HCtOn9INWJTVf))zXns9a`SLJ;^jYH909Cz5M$r_)ybc zBNPlI%gVG3^mTV6s(RobYbP_?)w@M*6~os)>zo9KDk-qW(*b*+qJny5ZEZ~`Q)@8x z5W+ZS@-(S)dnCc1a`5Oegop4?hzeqK*)Vl6S3w(xQAok5g{$P<)kcS;lO0eL9ME&2 z*T9O*2mN@#PQKM^Q67COE;D&`eyABl1J(~l=xQZwskSaKJ%(Jl!i-*JNJ_;>9x&*8 z?ONvu>BAv2o0BK+MZ4r2RfUw@KeN9T2cZAW8EnYy)4l!KVL9cKAduJ8Bp?VvBOe_d zU0CYSB;Xuj?o4ZwJUjGKjhn6(=QbMke#2k2hl(~(u=H?GS7QE>%n8ne?M4b*q1NziEwPh$H46pFSDJ26`1?+2D~u5f$aseaptq-Mf4*w}1Ye zRXpH_JjttpnypEg3^9BlWKc+bhRTnB(;PP5jd315v|BA`W_TqFTiXOsDc znoPlNNZi<~k%t!C^E6cGw~YXk#uW)?&zy-)*T+;6<33Wx-E!A-IE!IzUucu74z3@8 zmj?8N8c!K0*lAyaBA|Qv&6|WRh*&X#{*#oQod||PQ}#JnJ6>%snQYmnaK@}hu+>Pwd!Y$omdFi5y^raCN)7U9VT zy%#Nt7SEE15+5H`v)p7q!V%t0PC!EUzi;-tE$2#=b=-0g)zqA{5n-uzzC}M5vY+M!;_*A}h;*`-8Dyts~@1yat>R&kV$dPw$NBkJ8rCsB3`2n)qkVR1>Rman`|TlfNYhDo#-E+-ZCMo* z5Flkm40OD!ls5VinF({NQ$6&JsG6F682;sA8v(=Y@X{jd$F@cl5J+EDR*uZfnDm_f z(;NSz%&h^p8~b=A3%&R9w*h(-UmC*scJpQoCYvbqc!98D<2kIVh`e4q`1k9Hm{fRM znm60|*RJh5@R?YEz#f5ksDI(>$gbMDFBc%W)D7Ff^Sm~+{%^Hs!l;7(`m{VV+N)%-*XL|Xksp?H`qc4o!)eXgyC zKS@za^1j(E2Hg8`XvkoMaq?vNqKI`p7|GCq0Oz96)DIp$Jo<9JDhyo#vxOFEiFd2@ zuM#{jUmiu9C!X!;{`E9A^>tb+hPGCj?L7zg}#Rr>k? zNxsrM9rO~p7m=i93xferEydBXeweV864#A?zY2X95A_JAf7o}ft8cP<0a|lnhQGI-#j;%7@5kos%CoaDc&TcL~zJ76Q=@%j_WWory ze?JGd_nHmg9}ur2tgAbANV4wVsi=q*9@@xDR}BZu4{U%YiP=~vKrd360mcTV2<_RA z<(vrE%1C=ST!^g>v@!SyFwTnsm{qKKoRbrR|C20P>~>bp_7%nH8^OJR;gi+wJvucv z@Qf8pQe2BDTdp@=B{4<=J1=JO2;RWonKl0UjU@>xH}TqqXNUXgq%BY0{%4^ z;W1bv5F=qmY-k8~-F}aum{{LI|8A3!WZ8JG{U#z7mo`()OFDINc}~hYf3Q2 z217`pKgeU7mQq3(LcF_g!Zeq5k`S;>r@NX>wo9tkFDA{V<50K=m?~$8`s#FnMFm1 zQ74#Pa+rX_2uBQ77GPtOH2w`lSNJUCsOvnlJmefP3Rqh$CJ}(zYSxqAWDicKzmBxD zCq0vr!y(SP@WE1wf+`Ajc-i>fmtzQYVnr4CLzqCsz8COVqmV}c^%1+pEJRTwmJ0|S z0db~HrwTytzBsCv^vxawU$ts&G;T6w`9v6u~% zQrY{B(ZMgQhlKGqF>E8OoY-KD{>8MbL;KmJ6`iKII4$HHCN{QkG=E~-5jg}EwL~hB zhBe@rhm}7io!$Cy=ko9{LA4vkH%W?4 zOt@a;xeQGztb%ONKK$l)XFaKZj2ZL0Ic>=;4D4GZHbl}hGNz2k84otXdx28c(%vq~ z%$#Gfrq#&RD0J^um!~@#FTsnjwoz65AGD7xWY|(1?@K%z*rTqVQC#qRkF~VkYuFHP zW890yZ!MSxp(#NBPzepEqaw}^TD=g*(TGVc2ID$w)7U6Ld}i!mq@3(JN@GVaFuxx46~^6NcRRDue` z=K>JB0_Q)e5MDjZqLfo&nFQ>Q1e%nR$zOz&0U5P9L z7SJCfTB0b_+DLbN-v%dNV@nGY6p}c3*TvCB=v!bc47k19_wO5YZ#BV^gP{0jcls!*_3* zmxhlBC_dXOONX$fe>~_}k1{fhRT3z~!`N(adc#9KU)FoTwUC;`0`?`z#Ln)#z=yJm zrGphxBwX!Wq2?aEYPFm!EDphv%F2hshoLWG)N+4+rZ#LKI#t)7@ar?0fX4$28mOCK zl@lL>Ky(%uYTc@SGGL1|1SbY+T=V4u-#f#a>?I)}yREEtnoqlq41+xBTYg6hQvD;J zKakM~Dxtf37Ci_CNZlkwaq%$j(Bl5tpaN2(=IeSQT`><9JKlr`f@3DS8%UCQVX3aZ z{)SNVf|a=|!|zcbF~vq^g`}!7XX>X7MBpbnD8-i z!`1~S6R~*6(*txUwrJt z_2}8+e%HGAKG(9omwyHY2)P;i5{BmH2GAXB)QvlUTir ztdeQkU@0PO2e5(yG$bo$ZrXnMHUtR_;+xQFh*e))1>q@!`3?^TnpYisWqha3_hB}T`L5~B<1TN~yK;LLantxrf@r*tBcfDy#v1PXg*5Dp zRdpTMT3jhf!FZ$9%ng=gXb}I|XvkMH@ha-HYQ{2|&vh4AY9%jzgQIg3&vZ+pMeTzU4d#OdSz?h@bnT#W+(5?$5{U^or{sdRfk710%sqLH%L#~wKKDG}w=xQgJxrH` zl@FR4@o5Q|Lfd>ZFc&n3ovo^>iul+BfJc0EfbXp9Jt>{_LaQgJ$;9Xc698h#3$AMi z%#8jc7r~u`3l>pTW$poqGC+@Be;mz z1Ioa9hv76CkeP6g6T87UcYL71@hblt;D_bXMu!&ig|B^!H0`f!7>d|Jn>;3#0Nz{oreik8}2uZgFSw)oP$vDpPA^xhuSC( z`!m((A*>N@6zC$TX&4cOVpI>4JrPGx>=8=!|F!?Z1b#L#W-H>lSv1 zKH$2&217W}7~n*Qfl3rMTf*K= z{4foTyxV8>KN!Lnm6T}1u5&dbBhKpne$j2)SYX5XkdumHt21ar3L`NM(9I-tIuUj z{2sZQG2+huWWx^QYkD72#q$%6DVbUD{N#LR(q$qi<9p_vtsf`Xa;J%$#*cRbGCMv$Ts7p@V8|=kajJB0aIk1=#?RCVztxG# z3-t9PTz3yJ_q+18pWLYVcgkFW#D+R_b^m=2sI1r8oOQ*xu^YTG=;`Gf)(!iUaq?p>p*{`<|%vfwbDlRSydI>)B4*HK2R zX6aIT_Mh>sSDpEi4CzMPNrBbtG%B)eL!Fjf>!1DRM>vDlXz8@}DQ$@mVH#H95NOV^ zkj96KFyE2JL_O3~yUKHhH}Gehox{nK3?O=IABX-$!s~mxcV=XB^%{NPN@?~8yp|2K zvt-o%xC8m ^(q+5HPWE*o|EW&F{C$RIrMwaMH>3o`HG+dcDOyo|(ZAB)}sk;-*UaT}xtPKetaT6$gl1Pm!3G&aNFFm-rm``y5$Twr+ma@xp}-7`@`fTs7q) zO@gN`sjdAe42swMx0uKjRgag)YuD&BE~$$pF`2#(fA|o7P-)&+VyzK-5Q(RhV(_J( z8}i}9q2twof;CH2wl4?u%Rdf&*y}c%w)zt@mDSB1|-2Cnktfm)LMc$IALdTmaP=T|2IubJT3rTXD3NRXn}Ulflyx@4TZrXt`i zG^x&3h^+`NI_d~*YRrfY?;hBk+_a;nvxv-Uo~2$3@zv&aVEISA`|q{xzYn=1J=F5u z)A6c@oY4l{7rx$2DIw++R8^;r2B=ZH$diJ{R2I||TU(8K&e|qR(1mGr$g#AQ6uo$H z1!8&b;CVlWo>~f3)&!z_p^4v3M1aGtPw6~OB<~HwRcX)c^S%SFdX~2zZeyztK7CW( z>|$D0W%f2aQf_=P(c!7+TI#9@?B%YDwESSkqsPNSZ;CrjG8EYouP8Hf-E8ScuU+oJ zZ3=!(v8u@_;}9#?=Dey|vnJ&BjY&~X<*?V+eEljVr0yN8pIbW{za-t0IXt4mQEVL- zvh{|k@0}9%D4ofQ1h_he(f8%q>a99)6aMplL-pv=FXnhJiv{OINcH@^@FEVdSZNFU zy|)>?T8yqL0-+N=<4ZocBBxTD28Uv|Wp|%`7rw|4__$-Zg?ybeK96i=KLPN5K$m_8YR2?Vk zfb6By+Fbu3x$@5#oM1g_XUStzw(IYw*q_odGDunmx$--=8n{ zy8E_zTg~E6e|a`q#120{|EcniZ$9c*YrZ}TM*>r5u!S_8O={Qts)lOI^7)uM``#<% z9gqpv&SBjeyg693v%x{ZFqtl4?DmWrTYU{h-utdZLdQfsMLw9^*7xaCIJs?DB|+~) zVhQiHr1mBChaYh03v5cL{DbE=-@K>b_mxITwqO1?-_@JPHOw&{$u*k_yyJIJKm>`CC=UeOBw~DFCw><{*c&K0FeX2 zbXev5KAc?rjjvA6OiAa2 z(3VGG!*M>xD=uB3-pa!wct(Rs$qg|;#-EW{BkgNS$bDt)-#=};&O(e2 z^eitMNy)tmknjLBWr?8S-Ml$z|NZ9I9sKm|$i(8Rs=3nx90d~(XvLBYXI}>{{QirN zkeJocI(4Bm+a-TojdE(_<2PlD-RdXfUeU#$`$&|rDu_0vJU$cinbWuINfta2J~`7r z)bQn7Da6{Mrr~g&CMu>1n>92>$xVCzpi;!^(_)KGX8Omk;^*H_53Zb%G7%Z^5ketG z2T7I?<&7L?>|c&HylTvb7n7n_ZWzIn{8!8 zEFPhXqApu~lcs+yb48YF=Y@SvHcimCEM?O)4sC5YN#I#qzi-cUUKnOxN&g!toVlN| zgq(X^79Cf+_s0oah20WjNeBIZe;m?R%M@zc<9t&JDk(ry=;fCI)1mQx&f!*Z#$0sh zznGAwW*hX6xERGR@yPG*B&;FEpQyv|hPw((Z(K%);H`c9ucwnD?b@XB93txYt$W2dL= zhASDrUU!N&+cydFykU*1fAHbVY}tx~rAk7WJt;0OY&KkHP-NY2x9>a}kf~G{m;+NN zl})Ps&95dMA^)nM%si%+r4O^C+fqH0Xia9wnpniAF_{mxKl#+c!5{fhKVYx0>qq@Z zAL>x=z#=UleV}|)_RezIpY)zdpo3b6@y3DiTkZE;LR1DsPV@q{Ts6K6;F0i$JfLLE z_}WR4{8H=Cp(Fcr@&fQk59H&c0R+9@|N0wfnB0&-U3M-z|0(a*VCjXAGe3wuN0d`V zqy4!LFO!2k&X)|$8&uj39ZH^QJbCJ76<95N!;~S?{&v5sVsrD2op%H`M0ZnM62yF__Op5?u*>iF3>{PHp7CrN zAN?SOJ}4biH*NiiO1jwtoqX!j%@_9uZ!6y6?^QBGwMgZ8G31vr9@{)-%C7O~w#VD- zQST3DHqFe;^!4|no!Os0@|LbQC4HutCUV=3jaTT%ZQ2Egm*RHER+SE(uU9gY*uc!Y z*_~AhC^Xgin}e^%*vqJT(W3>tTjCiImUp@)t8VA)e=l)5QHH$_@dBGdC#A2+NS)0y!WRsy*%;N=R1oMkM6T`{Qa&g7M3ev9AzR*cpMZ3f%30f zLtQgJI!`H~7T-8gDtrpDKk!ZYXhF}5D^C;ESWMqL4d)+zByYA67|uGAu9<^$UoFX0 z3I}IxU|+azCy9+D+-lg;e@f}9snqHrkAxDRP?6h*ANkzj=<+&!GxGAw_L8hs zUxtGF5=N7k)UrY&Uz0G6hylKO)6wCGLW{nst(JN6O+F%}?A$!frjYg>=2B&NvAXgb@dn`4=N%6|=&)&57Oq(ZpX%@Mkptru+c__Ms z6HPX7Ax!v{{Ew*bYySWZan~JpCc2kb3(7xhE8lXSPCobXabDhI0wME!@Se4kW`$9295UCFqmlX1FYU{Yj`5oe0k|Eb{G5zB4j%&<>WO<(+=EzlMTmoA~I7Z*}=zIw}+7iYB7P?MmqA;N-~f%Beu8 zVPNA&@KeuEna7fCt6RtYmoHmHqVyn+L+~A@nQ`+lZJ`0nhBnvr zFn6WFwa)8a0P8lr_OAQ%NdNM~Xv5gjoycw#`{NDXpPgb(S?w8>cy>SRsz6c_F5dkx z5$LGs&J@CtgCoy-YLd8zCzziv8B!bn8jDPtA*-hO-c%W}8H++oZ=3cy?pLYNttPY; zM~!>>==T4v&GwIcL$tHl^)^wBXmMcI7kKgRz$9+CMSJf=6`b3|e0BNQUJ}&2_SHwl z7Wt>t^jSA;OZ)3aB$syFHz{){fA1Ko3Y&pCwI9Z#PngX4=y`5Ju+`~@{DKW&nC zla5B;ai;LoBM~DLv{?X--({wiPDPW*vP0_v%R?dAz^E#79_4MO)7b(jsnt7CEuR|d;gqqwgX7KEhqL?$b_4D5G)j;JA?&B`Yyn6DTj0s0*NkY$ zDy4=sPp{X9XW`Yt`t&Z;$he%SlU>_f;p3MIkckWg{8<>kB$_x?>wlT>od3Kf_cM6j zeyqfT5SmlfX4=)|LCl8VbB$WA#hj+DqGTw&=QF|a!(KkzDT2FV5 z^I$L-iM7*N>1$Hc*fKUhH&-`7&YVuHY?Oqj31lmdK0a{f`+|7?$NG~;-5p1490#aNL!&kXQMyb8Eldd6|^FMVfE@1aEc)WH#$$t(9F+=cskT zqyWGe$PMhnzIOA))gM8N_v4BR&$plo9DxbI7YNW5NbHW;ZWbK{-#B+cEmjP$PrvO_ z-|5k=vwW-ikLMBI?-;-0##j0>vgcYnSbcd(xC)eX2AeblE3&buutP+&f2d`UdZ1#Q zH~6!8GjVm18MfvfQZL504$WYRy6>?B%v2Zwrt*7!`C9eA59^f`^M3rRX!&!qe!FwQ zJJjO0%g`IUAVHy|f9il%?}ki;@rVwABiA9NvS>C|8j89V3+op5~N(f>uk8MJ&PN* zsd6)JUi#i->hFY+S=|H$&HM5JR-uF8^gMzehAUYN;WQDv;-w0dfyTok%nb zE#QUt69^c#KiX2SaBP?u)$XM2k@f0P_Sfc*<9H>QN>7tW!o^S5V-K#1I(vB;N!RNV z=`V{*7XdNAcYxVg0|RrSwxu!^3UF*J;7%YwbSl|?GLq?H+yZB%g5Gn<0NLzYw-m4? zpK5=use!ngW>|Ad5g_;{;kOd8~pSDpz?v$TD`Mb4M+KfccMm#drg@pzDd<<6S zmv870cI9*m-t=h~ha=Bsi?ge-R-*|E!ZQ$v>SrPG@#V!A4Skd70bD`)u+1ibkgu{o zehxG*Etj~mQc7K}%G6B(_#kj88;J!kC9huECGrzfA}?GxN1^Bf)1o%c-@SehF%!Gc zzFjj%T{W|kMtiijhW=$UD#9hldXs)2!c1HiTGe6T=c9X#VQChK`|+aiU`*VDmDL|z zvN%D4l(%6!2>)DOkt^~=4zB2Av$Y;uasgr^Oj3fx0gC3jY}CeH+L%7GJA{DKB9@qU zsJpR7T;Xc)E<#=v_8U`ZiQKtR0qW`$G+?M>V8i>q#=KNnHTtNxE_6}$n{t6rcF|jN zOM<^ynFCzlg_&M^n@EpVNq+G9()G-6stHiOh>jiSkJ&q=WCzck?sL$~3=I(2MEMO- zxB9C!poM#;){^&XWj;VKgr>PCyj+Nkf(FbTiz7q2X9-BU`v_=V0mTTMK28)S7&n(U zlwYr8q^=B3-HSIPKgZe~2ZaZS`v3p{ literal 0 HcmV?d00001 diff --git a/src/main/resources/styles/global.css b/src/main/resources/styles/global.css new file mode 100644 index 0000000..a8c437d --- /dev/null +++ b/src/main/resources/styles/global.css @@ -0,0 +1,41 @@ +.root { + -fx-base: white; + -fx-color: -fx-base; + + -fx-font-family: "Montserrat"; + -fx-accent: rgb(246, 246, 246); + -fx-default-button: -fx-accent; + -jfx-primary-color: -fx-accent; + -jfx-light-primary-color: -fx-accent; + -jfx-dark-primary-color: -fx-accent; + -fx-focus-color: rgb(222, 222, 222); + -jfx-secondary-color: -fx-focus-color; + -jfx-light-secondary-color: -fx-focus-color; + -jfx-dark-secondary-color: -fx-focus-color; +} + +/******************************************************************************* + * * + * JFX Tab Pane * + * * + ******************************************************************************/ + +.jfx-tab-pane .headers-region { + -fx-background-color: -fx-accent; +} + +.jfx-tab-pane .tab-header-background { + -fx-background-color: -fx-accent; +} + +.jfx-tab-pane .tab-selected-line { + -fx-stroke: -fx-accent; +} + +.jfx-tab-pane .tab-header-area .jfx-rippler { + -jfx-rippler-fill: -fx-focus-color; +} + +.tab-selected-line { + -fx-background-color: -fx-focus-color; +} \ No newline at end of file From 7b09ecd2cdb49c945f1d888c1cac2f086fa89d8c Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Mon, 23 Mar 2020 14:51:45 +0100 Subject: [PATCH 05/22] restart result GUI --- build.gradle | 2 +- .../java/GUI/DPMainGui/ContentUpdater.java | 7 - src/main/java/GUI/DPMainGui/Controller.java | 56 ---- .../GUI/DPMainGui/DamageProfilerMainGui.java | 28 -- .../GUI/DPMainGui/SidePanelController.java | 56 ---- ...java => DamageProfilerMainController.java} | 291 ++++++++---------- src/main/java/GUI/DamageProfilerMainGUI.java | 279 +++++++++++++++++ src/main/java/GUI/Plots/DamagePlot.java | 64 +++- src/main/java/GUI/Plots/IdentityHistPlot.java | 113 +++++++ src/main/java/GUI/Plots/LengthDistPlot.java | 56 ++++ src/main/java/RunDamageProfiler.java | 15 +- src/main/java/StarterCLI.java | 15 + src/main/java/StarterGUI.java | 27 ++ src/main/resources/fxml/main_view.fxml | 10 - src/main/resources/fxml/sidepanel.fxml | 20 -- src/main/resources/styles/global.css | 41 --- 16 files changed, 689 insertions(+), 391 deletions(-) delete mode 100644 src/main/java/GUI/DPMainGui/ContentUpdater.java delete mode 100644 src/main/java/GUI/DPMainGui/Controller.java delete mode 100644 src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java delete mode 100644 src/main/java/GUI/DPMainGui/SidePanelController.java rename src/main/java/GUI/{ConfigurationGUI.java => DamageProfilerMainController.java} (59%) mode change 100755 => 100644 create mode 100644 src/main/java/GUI/DamageProfilerMainGUI.java create mode 100644 src/main/java/GUI/Plots/IdentityHistPlot.java create mode 100644 src/main/java/GUI/Plots/LengthDistPlot.java create mode 100644 src/main/java/StarterCLI.java create mode 100755 src/main/java/StarterGUI.java delete mode 100644 src/main/resources/fxml/main_view.fxml delete mode 100644 src/main/resources/fxml/sidepanel.fxml delete mode 100644 src/main/resources/styles/global.css diff --git a/build.gradle b/build.gradle index c72e527..46d5de4 100644 --- a/build.gradle +++ b/build.gradle @@ -50,7 +50,7 @@ dependencies { compile group: 'com.intellij', name: 'forms_rt', version: '6.0.+' compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' - compile group: 'com.jfoenix', name: 'jfoenix', version: '8.0.7' + compile 'org.jfxtras:jmetro:8.6.5' } diff --git a/src/main/java/GUI/DPMainGui/ContentUpdater.java b/src/main/java/GUI/DPMainGui/ContentUpdater.java deleted file mode 100644 index daf8947..0000000 --- a/src/main/java/GUI/DPMainGui/ContentUpdater.java +++ /dev/null @@ -1,7 +0,0 @@ -package GUI.DPMainGui; - -public interface ContentUpdater { - void updateDamagePlot(); - void updateLengthDistribution(); - void updateIdentityHistogram(); -} diff --git a/src/main/java/GUI/DPMainGui/Controller.java b/src/main/java/GUI/DPMainGui/Controller.java deleted file mode 100644 index a023bf8..0000000 --- a/src/main/java/GUI/DPMainGui/Controller.java +++ /dev/null @@ -1,56 +0,0 @@ -package GUI.DPMainGui; - -import GUI.Plots.DamagePlot; -import com.jfoenix.controls.JFXDrawer; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.VBox; - -import java.io.IOException; -import java.net.URL; -import java.util.ResourceBundle; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Controller implements Initializable, ContentUpdater { - - - @FXML - private JFXDrawer drawer; - - @FXML - private AnchorPane root; - - @Override - public void initialize(URL url, ResourceBundle rb) { - - try { - FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/sidepanel.fxml")); - VBox box = loader.load(); - SidePanelController controller = loader.getController(); - controller.setCallback(this); - drawer.setSidePane(box); - drawer.open(); - } catch (IOException ex) { - Logger.getLogger(DamageProfilerMainGui.class.getName()).log(Level.SEVERE, null, ex); - } - - } - - @Override - public void updateDamagePlot() { - DamagePlot damagePlot = new DamagePlot(); - } - - @Override - public void updateLengthDistribution() { - - } - - @Override - public void updateIdentityHistogram() { - - } -} \ No newline at end of file diff --git a/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java b/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java deleted file mode 100644 index 9f703f2..0000000 --- a/src/main/java/GUI/DPMainGui/DamageProfilerMainGui.java +++ /dev/null @@ -1,28 +0,0 @@ -package GUI.DPMainGui; - -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.Pane; -import javafx.stage.Stage; - -import java.io.IOException; - -public class DamageProfilerMainGui { - - private Stage stage; - - public DamageProfilerMainGui() throws IOException { - - Parent root = FXMLLoader.load(this.getClass().getResource("/fxml/main_view.fxml")); - stage = new Stage(); - stage.setTitle("Damage Profiler Results"); - stage.setScene(new Scene(root, 1000, 800)); - stage.show(); - - } - -} - - diff --git a/src/main/java/GUI/DPMainGui/SidePanelController.java b/src/main/java/GUI/DPMainGui/SidePanelController.java deleted file mode 100644 index 07d871e..0000000 --- a/src/main/java/GUI/DPMainGui/SidePanelController.java +++ /dev/null @@ -1,56 +0,0 @@ -package GUI.DPMainGui; - -import com.jfoenix.controls.JFXButton; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; - -import java.net.URL; -import java.util.ResourceBundle; - -public class SidePanelController implements Initializable { - - - @FXML - private JFXButton b1; - @FXML - private JFXButton b2; - @FXML - private JFXButton b3; - @FXML - private JFXButton exit; - - private ContentUpdater callback; - - @Override - public void initialize(URL url, ResourceBundle rb) { - - } - - public void setCallback(ContentUpdater callback) { - this.callback = callback; - } - - @FXML - private void updatePanelContent(ActionEvent event) { - JFXButton btn = (JFXButton) event.getSource(); - System.out.println(btn.getText()); - switch (btn.getText()) { - case "Damage Profile": - callback.updateDamagePlot(); - break; - case "Length Distribution": - callback.updateLengthDistribution(); - break; - case "Identity Histogram": - callback.updateIdentityHistogram(); - break; - } - } - - @FXML - private void exit(ActionEvent event) { - System.exit(0); - } - -} diff --git a/src/main/java/GUI/ConfigurationGUI.java b/src/main/java/GUI/DamageProfilerMainController.java old mode 100755 new mode 100644 similarity index 59% rename from src/main/java/GUI/ConfigurationGUI.java rename to src/main/java/GUI/DamageProfilerMainController.java index b3e6c78..a76edc7 --- a/src/main/java/GUI/ConfigurationGUI.java +++ b/src/main/java/GUI/DamageProfilerMainController.java @@ -1,36 +1,29 @@ package GUI; -import GUI.DPMainGui.DamageProfilerMainGui; import GUI.Dialogues.AbstractDialogue; +import GUI.Plots.DamagePlot; +import GUI.Plots.IdentityHistPlot; +import GUI.Plots.LengthDistPlot; import IO.Communicator; import calculations.RuntimeEstimator; import calculations.StartCalculations; import javafx.animation.KeyFrame; import javafx.animation.Timeline; -import javafx.application.Application; - +import javafx.concurrent.Task; import javafx.concurrent.WorkerStateEvent; import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; import javafx.scene.control.*; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.text.Font; -import javafx.scene.text.FontWeight; -import javafx.stage.Stage; -import javafx.concurrent.Task; import javafx.util.Duration; -import java.io.IOException; import java.lang.reflect.Field; +public class DamageProfilerMainController { - -public class ConfigurationGUI extends Application { - + private final Button btn_leftpane_info; + private final Button btn_leftpane_identityDist; + private final Button btn_leftpane_damageProfile; + private final Button btn_leftpane_lengthDist; + private Communicator communicator; private Button btn_inputfile; private Button btn_reference; private Button btn_output; @@ -45,56 +38,43 @@ public class ConfigurationGUI extends Application { private TextField textfield_title; //private CheckBox checkbox_dynamic_y_axis_height; private TextField textfield_y_axis_height; - private Communicator communicator = new Communicator(); private StartCalculations starter = new StartCalculations(null); - private Stage primaryStage; private ProgressBar progressBar; private Task startCalculuations; + private DamageProfilerMainGUI mainGUI; + + + public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI){ + this.mainGUI = damageProfilerMainGUI; + this.communicator = mainGUI.getCommunicator(); + this.btn_inputfile = mainGUI.getBtn_inputfile(); + this.btn_reference = mainGUI.getBtn_reference(); + this.btn_output = mainGUI.getBtn_output(); + this.btn_plotting_options = mainGUI.getBtn_plotting_options(); + this.btn_run = mainGUI.getBtn_run(); + this.btn_specieList = mainGUI.getBtn_specieList(); + this.textfield_threshold = mainGUI.getTextfield_threshold(); + this.textfield_length = mainGUI.getTextfield_length(); + this.textfield_specie = mainGUI.getTextfield_specie(); + this.checkbox_use_merged_reads = mainGUI.getCheckbox_use_merged_reads(); + this.checkbos_ssLibs_protocol = mainGUI.getCheckbos_ssLibs_protocol(); + this.textfield_title = mainGUI.getTextfield_title(); + //this.checkbox_dynamic_y_axis_height = mainGUI.get??; + this.textfield_y_axis_height = mainGUI.getTextfield_y_axis_height(); + this.progressBar = mainGUI.getProgressBar(); + + this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); + this.btn_leftpane_info = mainGUI.getBtn_leftpane_info(); + this.btn_leftpane_damageProfile = mainGUI.getBtn_leftpane_damageProfile(); + this.btn_leftpane_lengthDist = mainGUI.getBtn_leftpane_lengthDist(); - @Override - public void start(Stage primaryStage) { - this.primaryStage = primaryStage; - - this.primaryStage.setTitle("DamageProfiler configuration"); - - GridPane root = new GridPane(); - root.setAlignment(Pos.CENTER); - root.setHgap(7); - root.setVgap(7); - - addComponents(root); addListener(); - this.primaryStage.setScene(new Scene(root, 750, 500)); - this.primaryStage.setResizable(true); - this.primaryStage.show(); - - - } - public Task startCalculations(Communicator communicator, RuntimeEstimator runtimeEstimator) { - return new Task() { - @Override - protected Object call() throws Exception { - starter.start(communicator, runtimeEstimator); - return true; - } - }; } - private void addListener() { - -// checkbox_dynamic_y_axis_height.selectedProperty().addListener((ov, old_val, new_val) -> { -// if(new_val){ -// textfield_y_axis_height.setDisable(true); -// } else if(!new_val){ -// textfield_y_axis_height.setDisable(false); -// } -// }); - - btn_inputfile.setOnAction(e -> { BamFileChooser fqfc = new BamFileChooser(communicator); @@ -127,6 +107,8 @@ private void addListener() { }); + + btn_output.setOnAction(e -> { OutputDirChooser rfc = new OutputDirChooser(communicator); @@ -143,17 +125,7 @@ private void addListener() { }); - btn_specieList.setOnAction(e -> { - - SpeciesListFileChooser slfc = new SpeciesListFileChooser(communicator); - if (checkIfInputWasSelected()) { - btn_specieList.setDisable(false); - } else { - btn_specieList.setDisable(true); - } - - }); btn_run.setOnAction(e -> { @@ -201,13 +173,13 @@ private void addListener() { else communicator.setSpecies_ref_identifier(textfield_specie.getText()); - // if(!checkbox_dynamic_y_axis_height.isSelected()){ - // try { - // communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); - // } catch (Exception ex){ - // System.out.println("Height value not valid."); - // } - // } + // if(!checkbox_dynamic_y_axis_height.isSelected()){ + // try { + // communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); + // } catch (Exception ex){ + // System.out.println("Height value not valid."); + // } + // } if(!textfield_title.getText().equals("")){ @@ -225,13 +197,11 @@ private void addListener() { startCalculuations.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, // (EventHandler) t -> { if(starter.isCalculationsDone()){ - primaryStage.close(); - DamageProfilerMainGui damageProfilerMainGui = null; - try { - damageProfilerMainGui = new DamageProfilerMainGui(); - } catch (IOException ex) { - ex.printStackTrace(); - } + // replace config with result GUI + btn_leftpane_lengthDist.setDisable(false); + btn_leftpane_identityDist.setDisable(false); + btn_leftpane_damageProfile.setDisable(false); + generateDamageProfile(); } }); @@ -250,90 +220,99 @@ private void addListener() { }); + btn_specieList.setOnAction(e -> { + + SpeciesListFileChooser slfc = new SpeciesListFileChooser(communicator); + if (checkIfInputWasSelected()) { + btn_specieList.setDisable(false); + } else { + btn_specieList.setDisable(true); + } + + + }); + + + btn_leftpane_damageProfile.setOnAction(e -> { + if(starter.isCalculationsDone()){ + if(plotAlreadyGenerated()){ + // show plot + } else { + // generate plot + generateDamageProfile(); + + } + } else { + mainGUI.getRoot().setCenter(null); + } + }); + + + btn_leftpane_identityDist.setOnAction(e -> { + if(starter.isCalculationsDone()){ + if(plotAlreadyGenerated()){ + // show plot + } else { + // generate plot + generateIdentityDist(); + + } + } else { + mainGUI.getRoot().setCenter(null); } + }); + + btn_leftpane_lengthDist.setOnAction(e -> { + if(starter.isCalculationsDone()){ + if(plotAlreadyGenerated()){ + // show plot + } else { + // generate plot + generateLengthDist(); + + } + } else { + mainGUI.getRoot().setCenter(null); + } + }); + + } + private void generateLengthDist() { + LengthDistPlot lengthDistPlot = new LengthDistPlot(); + mainGUI.getRoot().setCenter(lengthDistPlot.getBc()); + } - private void addComponents(GridPane root) { - - btn_inputfile = new Button("Select input file"); - btn_reference = new Button("Select reference"); - btn_output = new Button("Select output"); - btn_plotting_options = new Button("Plotting options"); - btn_specieList = new Button("Set list"); - btn_run = new Button("Run"); - - Label label_threshold = new Label("Number of bases (x-axis)"); - Label label_yaxis = new Label("Height y-axis"); - Label label_length = new Label("Set number of bases (calculations)"); - Label label_specie = new Label("Filter for specie"); - Label label_title = new Label("Set title"); - Label label_plot = new Label("Plot"); - label_plot.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - Label label_files = new Label("Files"); - label_files.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - - Label label_calculations = new Label("Calculations"); - label_calculations.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - - progressBar = new ProgressBar(0); - - textfield_threshold = new TextField(); - textfield_length = new TextField(); - textfield_specie = new TextField(); - textfield_title = new TextField(); - textfield_y_axis_height = new TextField(); - - checkbox_use_merged_reads = new CheckBox("Only merged reads"); - checkbos_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); - //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); - - btn_run.setDisable(true); - textfield_length.setText("100"); - textfield_threshold.setText("25"); - textfield_y_axis_height.setText("0.4"); - //checkbox_dynamic_y_axis_height.setSelected(true); - //textfield_y_axis_height.setDisable(true); - - - // add components to grid - - int row = 0; - - root.add(label_files, 0, row, 1,1); - root.add(btn_inputfile, 0, ++row,1,1); - root.add(btn_reference, 1, row,1,1); - root.add(btn_output, 2, row,1,1); - root.add(new Separator(), 0, ++row,3,1); - - // PLOT - - root.add(label_plot, 0, ++row, 1,1); - root.add(label_title, 0, ++row, 1,1); - root.add(textfield_title, 1, row, 2,1); - root.add(label_yaxis, 0, ++row, 1,1); - //root.add(checkbox_dynamic_y_axis_height, 1, row, 1,1); - root.add(textfield_y_axis_height, 1, row, 2,1); - root.add(label_threshold, 0, ++row, 1,1); - root.add(textfield_threshold, 1, row, 2,1); - root.add(label_specie, 0, ++row, 1,1); - root.add(textfield_specie, 1, row, 2,1); - root.add(btn_specieList, 3, row, 1,1); - root.add(new Separator(), 0, ++row,3,1); - - // CALCULATIONS - root.add(label_calculations, 0, ++row, 1,1); - root.add(checkbox_use_merged_reads, 0, ++row,1,1); - root.add(checkbos_ssLibs_protocol, 0, ++row, 1,1); - root.add(label_length, 0, ++row, 1,1); - root.add(textfield_length, 1, row, 2,1); - root.add(new Separator(), 0, ++row,3,1); - root.add(btn_run, 0, ++row,1,1); - root.add(progressBar, 1, row,1,1); + private void generateIdentityDist() { + IdentityHistPlot identityHistPlot = new IdentityHistPlot(); + mainGUI.getRoot().setCenter(identityHistPlot.getRoot()); } + private void generateDamageProfile() { + DamagePlot damagePlot = new DamagePlot(); + mainGUI.getRoot().setCenter(damagePlot.getLineChart()); + } + + // todo + private boolean plotAlreadyGenerated() { + return false; + } + + + public Task startCalculations(Communicator communicator, RuntimeEstimator runtimeEstimator) { + return new Task() { + @Override + protected Object call() throws Exception { + starter.start(communicator, runtimeEstimator); + return true; + } + }; + } + + private boolean checkIfInputWasSelected() { boolean tmp = false; if (communicator.getInput() != null && communicator.getReference() != null && communicator.getOutfolder() != null) { diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java new file mode 100644 index 0000000..2015203 --- /dev/null +++ b/src/main/java/GUI/DamageProfilerMainGUI.java @@ -0,0 +1,279 @@ +package GUI; + +import IO.Communicator; +import calculations.StartCalculations; +import javafx.concurrent.Task; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.stage.Stage; +import jfxtras.styles.jmetro.JMetro; +import jfxtras.styles.jmetro.Style; + +public class DamageProfilerMainGUI { + + + private final String version; + private Stage primaryStage; + private Button btn_inputfile; + private Button btn_reference; + private Button btn_output; + private Button btn_plotting_options; + private Button btn_run; + private Button btn_specieList; + private TextField textfield_threshold; + private TextField textfield_length; + private TextField textfield_specie; + private CheckBox checkbox_use_merged_reads; + private CheckBox checkbos_ssLibs_protocol; + private TextField textfield_title; + //private CheckBox checkbox_dynamic_y_axis_height; + private TextField textfield_y_axis_height; + private Communicator communicator = new Communicator(); + private StartCalculations starter = new StartCalculations(null); + private ProgressBar progressBar; + private BorderPane root; + private GridPane config_gridpane; + private Button btn_leftpane_identityDist; + private Button btn_leftpane_info; + private Button btn_leftpane_damageProfile; + private Button btn_leftpane_lengthDist; + + + public DamageProfilerMainGUI(String version) { + this.version = version; + } + + public void init(Stage primaryStage){ + + //JMetro jMetro = new JMetro(Style.LIGHT); + + this.primaryStage = primaryStage; + this.primaryStage.setTitle("DamageProfiler v" + version); + + root = new BorderPane(); + + config_gridpane = new GridPane(); + config_gridpane.setAlignment(Pos.CENTER); + config_gridpane.setHgap(7); + config_gridpane.setVgap(7); + config_gridpane.setPadding(new Insets(10,10,10,10)); + + addComponents(config_gridpane); + addLeftPane(); + + root.setCenter(config_gridpane); + //jMetro.setScene(new Scene(root, 750, 500)); + //this.primaryStage.setScene(jMetro.getScene()); + this.primaryStage.setScene(new Scene(root, 900, 600)); + this.primaryStage.setResizable(true); + this.primaryStage.show(); + + } + + private void addLeftPane() { + VBox leftPanel = new VBox(); + btn_leftpane_damageProfile = new Button("Damage Plot"); + btn_leftpane_info = new Button("Run Configuration"); + btn_leftpane_lengthDist = new Button("Length Distribution"); + btn_leftpane_identityDist = new Button("Identity Distribution"); + + // style buttons + btn_leftpane_info.setPrefHeight(30); + btn_leftpane_info.setPrefWidth(200); + + btn_leftpane_damageProfile.setPrefHeight(30); + btn_leftpane_damageProfile.setPrefWidth(200); + btn_leftpane_damageProfile.setDisable(true); + + btn_leftpane_lengthDist.setPrefHeight(30); + btn_leftpane_lengthDist.setPrefWidth(200); + btn_leftpane_lengthDist.setDisable(true); + + btn_leftpane_identityDist.setPrefHeight(30); + btn_leftpane_identityDist.setPrefWidth(200); + btn_leftpane_identityDist.setDisable(true); + + leftPanel.getChildren().addAll(btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist); + leftPanel.setPadding(new Insets(10,10,10,10)); + root.setLeft(leftPanel); + } + + private void addComponents(GridPane root) { + + btn_inputfile = new Button("Select input file"); + btn_reference = new Button("Select reference"); + btn_output = new Button("Select output"); + btn_plotting_options = new Button("Plotting options"); + btn_specieList = new Button("Set list"); + btn_run = new Button("Run"); + + Label label_threshold = new Label("Number of bases (x-axis)"); + Label label_yaxis = new Label("Height y-axis"); + Label label_length = new Label("Set number of bases (calculations)"); + Label label_specie = new Label("Filter for specie"); + Label label_title = new Label("Set title"); + Label label_plot = new Label("Plot"); + label_plot.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + Label label_files = new Label("Files"); + label_files.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_calculations = new Label("Calculations"); + label_calculations.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_title_config = new Label("Configuration"); + label_title_config.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + progressBar = new ProgressBar(0); + + textfield_threshold = new TextField(); + textfield_length = new TextField(); + textfield_specie = new TextField(); + textfield_title = new TextField(); + textfield_y_axis_height = new TextField(); + + checkbox_use_merged_reads = new CheckBox("Only merged reads"); + checkbos_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); + //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); + + btn_run.setDisable(true); + textfield_length.setText("100"); + textfield_threshold.setText("25"); + textfield_y_axis_height.setText("0.4"); + //checkbox_dynamic_y_axis_height.setSelected(true); + //textfield_y_axis_height.setDisable(true); + + + // add components to grid + + int row = 0; + + root.add(label_title_config, 0, row, 1,1); + root.add(new Separator(), 0, ++row,3,1); + + + root.add(label_files, 0, ++row, 1,1); + root.add(btn_inputfile, 0, ++row,1,1); + root.add(btn_reference, 1, row,1,1); + root.add(btn_output, 2, row,1,1); + root.add(new Separator(), 0, ++row,3,1); + + // PLOT + + root.add(label_plot, 0, ++row, 1,1); + root.add(label_title, 0, ++row, 1,1); + root.add(textfield_title, 1, row, 2,1); + root.add(label_yaxis, 0, ++row, 1,1); + //root.add(checkbox_dynamic_y_axis_height, 1, row, 1,1); + root.add(textfield_y_axis_height, 1, row, 2,1); + root.add(label_threshold, 0, ++row, 1,1); + root.add(textfield_threshold, 1, row, 2,1); + root.add(label_specie, 0, ++row, 1,1); + root.add(textfield_specie, 1, row, 2,1); + root.add(btn_specieList, 3, row, 1,1); + root.add(new Separator(), 0, ++row,3,1); + + // CALCULATIONS + root.add(label_calculations, 0, ++row, 1,1); + root.add(checkbox_use_merged_reads, 0, ++row,1,1); + root.add(checkbos_ssLibs_protocol, 0, ++row, 1,1); + root.add(label_length, 0, ++row, 1,1); + root.add(textfield_length, 1, row, 2,1); + root.add(new Separator(), 0, ++row,3,1); + root.add(btn_run, 0, ++row,1,1); + root.add(progressBar, 1, row,1,1); + + + } + + + public Button getBtn_inputfile() { + return btn_inputfile; + } + + public Button getBtn_reference() { + return btn_reference; + } + + public Button getBtn_output() { + return btn_output; + } + + public Button getBtn_plotting_options() { + return btn_plotting_options; + } + + public Button getBtn_run() { + return btn_run; + } + + public Button getBtn_specieList() { + return btn_specieList; + } + + public TextField getTextfield_threshold() { + return textfield_threshold; + } + + public TextField getTextfield_length() { + return textfield_length; + } + + public TextField getTextfield_specie() { + return textfield_specie; + } + + public CheckBox getCheckbox_use_merged_reads() { + return checkbox_use_merged_reads; + } + + public CheckBox getCheckbos_ssLibs_protocol() { + return checkbos_ssLibs_protocol; + } + + public TextField getTextfield_title() { + return textfield_title; + } + + public TextField getTextfield_y_axis_height() { + return textfield_y_axis_height; + } + + public Communicator getCommunicator() { + return communicator; + } + + public ProgressBar getProgressBar() { + return progressBar; + } + + public BorderPane getRoot() { + return root; + } + + public GridPane getConfig_gridpane() { + return config_gridpane; + } + + public Button getBtn_leftpane_identityDist() { + return btn_leftpane_identityDist; + } + + public Button getBtn_leftpane_info() { + return btn_leftpane_info; + } + + public Button getBtn_leftpane_damageProfile() { + return btn_leftpane_damageProfile; + } + + public Button getBtn_leftpane_lengthDist() { + return btn_leftpane_lengthDist; + } +} diff --git a/src/main/java/GUI/Plots/DamagePlot.java b/src/main/java/GUI/Plots/DamagePlot.java index 51aaf55..d8b88ce 100644 --- a/src/main/java/GUI/Plots/DamagePlot.java +++ b/src/main/java/GUI/Plots/DamagePlot.java @@ -1,21 +1,77 @@ package GUI.Plots; +import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; public class DamagePlot { + private final LineChart lineChart; + public DamagePlot() { - NumberAxis xAxis = new NumberAxis(); - xAxis.setLabel("No of employees"); + CategoryAxis xAxis = new CategoryAxis(); NumberAxis yAxis = new NumberAxis(); - yAxis.setLabel("Revenue per employee"); + xAxis.setLabel("Month"); + lineChart = + new LineChart(xAxis,yAxis); + + lineChart.setTitle("Stock Monitoring, 2010"); + + XYChart.Series series1 = new XYChart.Series(); + series1.setName("Portfolio 1"); + + series1.getData().add(new XYChart.Data("Jan", 23)); + series1.getData().add(new XYChart.Data("Feb", 14)); + series1.getData().add(new XYChart.Data("Mar", 15)); + series1.getData().add(new XYChart.Data("Apr", 24)); + series1.getData().add(new XYChart.Data("May", 34)); + series1.getData().add(new XYChart.Data("Jun", 36)); + series1.getData().add(new XYChart.Data("Jul", 22)); + series1.getData().add(new XYChart.Data("Aug", 45)); + series1.getData().add(new XYChart.Data("Sep", 43)); + series1.getData().add(new XYChart.Data("Oct", 17)); + series1.getData().add(new XYChart.Data("Nov", 29)); + series1.getData().add(new XYChart.Data("Dec", 25)); - LineChart lineChart = new LineChart(xAxis, yAxis); + XYChart.Series series2 = new XYChart.Series(); + series2.setName("Portfolio 2"); + series2.getData().add(new XYChart.Data("Jan", 33)); + series2.getData().add(new XYChart.Data("Feb", 34)); + series2.getData().add(new XYChart.Data("Mar", 25)); + series2.getData().add(new XYChart.Data("Apr", 44)); + series2.getData().add(new XYChart.Data("May", 39)); + series2.getData().add(new XYChart.Data("Jun", 16)); + series2.getData().add(new XYChart.Data("Jul", 55)); + series2.getData().add(new XYChart.Data("Aug", 54)); + series2.getData().add(new XYChart.Data("Sep", 48)); + series2.getData().add(new XYChart.Data("Oct", 27)); + series2.getData().add(new XYChart.Data("Nov", 37)); + series2.getData().add(new XYChart.Data("Dec", 29)); + XYChart.Series series3 = new XYChart.Series(); + series3.setName("Portfolio 3"); + series3.getData().add(new XYChart.Data("Jan", 44)); + series3.getData().add(new XYChart.Data("Feb", 35)); + series3.getData().add(new XYChart.Data("Mar", 36)); + series3.getData().add(new XYChart.Data("Apr", 33)); + series3.getData().add(new XYChart.Data("May", 31)); + series3.getData().add(new XYChart.Data("Jun", 26)); + series3.getData().add(new XYChart.Data("Jul", 22)); + series3.getData().add(new XYChart.Data("Aug", 25)); + series3.getData().add(new XYChart.Data("Sep", 43)); + series3.getData().add(new XYChart.Data("Oct", 44)); + series3.getData().add(new XYChart.Data("Nov", 45)); + series3.getData().add(new XYChart.Data("Dec", 44)); + lineChart.getData().addAll(series1, series2, series3); + + + } + public LineChart getLineChart() { + return lineChart; } } diff --git a/src/main/java/GUI/Plots/IdentityHistPlot.java b/src/main/java/GUI/Plots/IdentityHistPlot.java new file mode 100644 index 0000000..360fd21 --- /dev/null +++ b/src/main/java/GUI/Plots/IdentityHistPlot.java @@ -0,0 +1,113 @@ +package GUI.Plots; + +import javafx.scene.Scene; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.CategoryAxis; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; +import javafx.scene.control.Label; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; + +import java.util.Random; + +public class IdentityHistPlot { + + + private final StackPane root; + int DATA_SIZE = 1000; + int data[] = new int[DATA_SIZE]; + int group[] = new int[10]; + + + public IdentityHistPlot(){ + + + prepareData(); + groupData(); + + Label labelInfo = new Label(); + labelInfo.setText( + "java.version: " + System.getProperty("java.version") + "\n" + + "javafx.runtime.version: " + System.getProperty("javafx.runtime.version") + ); + + final CategoryAxis xAxis = new CategoryAxis(); + final NumberAxis yAxis = new NumberAxis(); + final BarChart barChart = + new BarChart<>(xAxis,yAxis); + barChart.setCategoryGap(0); + barChart.setBarGap(0); + + xAxis.setLabel("Range"); + yAxis.setLabel("Population"); + + XYChart.Series series1 = new XYChart.Series(); + series1.setName("Histogram"); + series1.getData().add(new XYChart.Data("0-10", group[0])); + series1.getData().add(new XYChart.Data("10-20", group[1])); + series1.getData().add(new XYChart.Data("20-30", group[2])); + series1.getData().add(new XYChart.Data("30-40", group[3])); + series1.getData().add(new XYChart.Data("40-50", group[4])); + + series1.getData().add(new XYChart.Data("50-60", group[5])); + series1.getData().add(new XYChart.Data("60-70", group[6])); + series1.getData().add(new XYChart.Data("70-80", group[7])); + series1.getData().add(new XYChart.Data("80-90", group[8])); + series1.getData().add(new XYChart.Data("90-100", group[9])); + + barChart.getData().addAll(series1); + + VBox vBox = new VBox(); + vBox.getChildren().addAll(labelInfo, barChart); + + root = new StackPane(); + root.getChildren().add(vBox); + + + } + + + //generate dummy random data + private void prepareData(){ + + Random random = new Random(); + for(int i=0; i bc; + + public LengthDistPlot(){ + CategoryAxis xAxis = new CategoryAxis(); + NumberAxis yAxis = new NumberAxis(); + bc = new BarChart(xAxis,yAxis); + bc.setTitle("Country Summary"); + xAxis.setLabel("Country"); + yAxis.setLabel("Value"); + + XYChart.Series series1 = new XYChart.Series(); + series1.setName("2003"); + series1.getData().add(new XYChart.Data(austria, 25601.34)); + series1.getData().add(new XYChart.Data(brazil, 20148.82)); + series1.getData().add(new XYChart.Data(france, 10000)); + series1.getData().add(new XYChart.Data(italy, 35407.15)); + series1.getData().add(new XYChart.Data(usa, 12000)); + + XYChart.Series series2 = new XYChart.Series(); + series2.setName("2004"); + series2.getData().add(new XYChart.Data(austria, 57401.85)); + series2.getData().add(new XYChart.Data(brazil, 41941.19)); + series2.getData().add(new XYChart.Data(france, 45263.37)); + series2.getData().add(new XYChart.Data(italy, 117320.16)); + series2.getData().add(new XYChart.Data(usa, 14845.27)); + + XYChart.Series series3 = new XYChart.Series(); + series3.setName("2005"); + series3.getData().add(new XYChart.Data(austria, 45000.65)); + series3.getData().add(new XYChart.Data(brazil, 44835.76)); + series3.getData().add(new XYChart.Data(france, 18722.18)); + series3.getData().add(new XYChart.Data(italy, 17557.31)); + series3.getData().add(new XYChart.Data(usa, 92633.68)); + + bc.getData().addAll(series1, series2, series3); + } + + public BarChart getBc() { + return bc; + } +} diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index bf0ab14..ff36daa 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -1,7 +1,3 @@ -import GUI.ConfigurationGUI; -import IO.*; -import calculations.RuntimeEstimator; -import calculations.StartCalculations; import javafx.application.Application; /** @@ -29,16 +25,11 @@ public static void main(String[] args) throws Exception { System.setProperty("java.awt.headless", "true"); if(args.length==0){ - //MainDP damageProfilerGUI = new MainDP(c, starter, VERSION); - System.out.println(VERSION); - new Thread(() -> Application.launch(ConfigurationGUI.class)).start(); + new Thread(() -> Application.launch(StarterGUI.class)).start(); } else { - Communicator c = new Communicator(); - StartCalculations starter = new StartCalculations(VERSION); - UserOptionsParser userOptions = new UserOptionsParser(args, c, VERSION); - RuntimeEstimator runtimeEstimator = new RuntimeEstimator(c.getInput()); - starter.start(c, runtimeEstimator); + StarterCLI starterCLI = new StarterCLI(VERSION, args); + } diff --git a/src/main/java/StarterCLI.java b/src/main/java/StarterCLI.java new file mode 100644 index 0000000..e59ea85 --- /dev/null +++ b/src/main/java/StarterCLI.java @@ -0,0 +1,15 @@ +import IO.Communicator; +import IO.UserOptionsParser; +import calculations.RuntimeEstimator; +import calculations.StartCalculations; + +public class StarterCLI { + + public StarterCLI(String version, String[] args) throws Exception { + Communicator c = new Communicator(); + StartCalculations starter = new StartCalculations(version); + UserOptionsParser userOptions = new UserOptionsParser(args, c, version); + RuntimeEstimator runtimeEstimator = new RuntimeEstimator(c.getInput()); + starter.start(c, runtimeEstimator); + } +} diff --git a/src/main/java/StarterGUI.java b/src/main/java/StarterGUI.java new file mode 100755 index 0000000..6560571 --- /dev/null +++ b/src/main/java/StarterGUI.java @@ -0,0 +1,27 @@ +import GUI.DamageProfilerMainController; +import GUI.DamageProfilerMainGUI; +import javafx.application.Application; + +import javafx.stage.Stage; + + + +public class StarterGUI extends Application { + + private static final String VERSION = "0.4.9"; + + + @Override + public void start(Stage primaryStage) { + + DamageProfilerMainGUI damageProfilerMainGUI = new DamageProfilerMainGUI(VERSION); + damageProfilerMainGUI.init(primaryStage); + + DamageProfilerMainController damageProfilerMainController = new DamageProfilerMainController(damageProfilerMainGUI); + + + + } + + +} diff --git a/src/main/resources/fxml/main_view.fxml b/src/main/resources/fxml/main_view.fxml deleted file mode 100644 index 3b6adca..0000000 --- a/src/main/resources/fxml/main_view.fxml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/main/resources/fxml/sidepanel.fxml b/src/main/resources/fxml/sidepanel.fxml deleted file mode 100644 index e946c40..0000000 --- a/src/main/resources/fxml/sidepanel.fxml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/styles/global.css b/src/main/resources/styles/global.css deleted file mode 100644 index a8c437d..0000000 --- a/src/main/resources/styles/global.css +++ /dev/null @@ -1,41 +0,0 @@ -.root { - -fx-base: white; - -fx-color: -fx-base; - - -fx-font-family: "Montserrat"; - -fx-accent: rgb(246, 246, 246); - -fx-default-button: -fx-accent; - -jfx-primary-color: -fx-accent; - -jfx-light-primary-color: -fx-accent; - -jfx-dark-primary-color: -fx-accent; - -fx-focus-color: rgb(222, 222, 222); - -jfx-secondary-color: -fx-focus-color; - -jfx-light-secondary-color: -fx-focus-color; - -jfx-dark-secondary-color: -fx-focus-color; -} - -/******************************************************************************* - * * - * JFX Tab Pane * - * * - ******************************************************************************/ - -.jfx-tab-pane .headers-region { - -fx-background-color: -fx-accent; -} - -.jfx-tab-pane .tab-header-background { - -fx-background-color: -fx-accent; -} - -.jfx-tab-pane .tab-selected-line { - -fx-stroke: -fx-accent; -} - -.jfx-tab-pane .tab-header-area .jfx-rippler { - -jfx-rippler-fill: -fx-focus-color; -} - -.tab-selected-line { - -fx-background-color: -fx-focus-color; -} \ No newline at end of file From 1f8122cd05a2e113a9045937e31f80f40b85a39c Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Tue, 24 Mar 2020 09:50:39 +0100 Subject: [PATCH 06/22] Gui working with dummy plots --- src/main/java/GUI/DamageProfilerMainGUI.java | 196 ++---------------- .../GUI/Dialogues/ConfigurationDialogue.java | 189 +++++++++++++++++ src/main/java/IO/OutputGenerator.java | 2 + .../java/IO/{ => PDFoutput}/Histogram.java | 2 +- .../java/IO/{ => PDFoutput}/LinePlot.java | 2 +- src/main/java/StarterGUI.java | 10 +- .../SpeciesListParser.java | 3 +- .../DamageProfilerMainController.java | 145 ++++++------- .../controller/ProgressBarController.java | 34 +++ 9 files changed, 317 insertions(+), 266 deletions(-) create mode 100644 src/main/java/GUI/Dialogues/ConfigurationDialogue.java rename src/main/java/IO/{ => PDFoutput}/Histogram.java (99%) rename src/main/java/IO/{ => PDFoutput}/LinePlot.java (99%) rename src/main/java/{IO => calculations}/SpeciesListParser.java (96%) rename src/main/java/{GUI => controller}/DamageProfilerMainController.java (71%) create mode 100644 src/main/java/controller/ProgressBarController.java diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java index 2015203..8364c0f 100644 --- a/src/main/java/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/GUI/DamageProfilerMainGUI.java @@ -1,53 +1,33 @@ package GUI; +import GUI.Dialogues.ConfigurationDialogue; import IO.Communicator; -import calculations.StartCalculations; -import javafx.concurrent.Task; +import controller.ProgressBarController; import javafx.geometry.Insets; -import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.BorderPane; -import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import javafx.scene.text.Font; -import javafx.scene.text.FontWeight; import javafx.stage.Stage; -import jfxtras.styles.jmetro.JMetro; -import jfxtras.styles.jmetro.Style; public class DamageProfilerMainGUI { private final String version; + private final ProgressBarController progressBarController; private Stage primaryStage; - private Button btn_inputfile; - private Button btn_reference; - private Button btn_output; - private Button btn_plotting_options; - private Button btn_run; - private Button btn_specieList; - private TextField textfield_threshold; - private TextField textfield_length; - private TextField textfield_specie; - private CheckBox checkbox_use_merged_reads; - private CheckBox checkbos_ssLibs_protocol; - private TextField textfield_title; - //private CheckBox checkbox_dynamic_y_axis_height; - private TextField textfield_y_axis_height; private Communicator communicator = new Communicator(); - private StartCalculations starter = new StartCalculations(null); - private ProgressBar progressBar; private BorderPane root; - private GridPane config_gridpane; + private ConfigurationDialogue config_dialogue; private Button btn_leftpane_identityDist; private Button btn_leftpane_info; private Button btn_leftpane_damageProfile; private Button btn_leftpane_lengthDist; - public DamageProfilerMainGUI(String version) { + public DamageProfilerMainGUI(String version, ProgressBarController progressBarController) { this.version = version; + this.progressBarController = progressBarController; } public void init(Stage primaryStage){ @@ -59,16 +39,11 @@ public void init(Stage primaryStage){ root = new BorderPane(); - config_gridpane = new GridPane(); - config_gridpane.setAlignment(Pos.CENTER); - config_gridpane.setHgap(7); - config_gridpane.setVgap(7); - config_gridpane.setPadding(new Insets(10,10,10,10)); + config_dialogue = new ConfigurationDialogue(progressBarController.getProgressBar()); - addComponents(config_gridpane); - addLeftPane(); + root.setCenter(config_dialogue.getConfig_gridpane()); + root.setLeft(generateLeftPane()); - root.setCenter(config_gridpane); //jMetro.setScene(new Scene(root, 750, 500)); //this.primaryStage.setScene(jMetro.getScene()); this.primaryStage.setScene(new Scene(root, 900, 600)); @@ -77,7 +52,7 @@ public void init(Stage primaryStage){ } - private void addLeftPane() { + private VBox generateLeftPane() { VBox leftPanel = new VBox(); btn_leftpane_damageProfile = new Button("Damage Plot"); btn_leftpane_info = new Button("Run Configuration"); @@ -102,165 +77,20 @@ private void addLeftPane() { leftPanel.getChildren().addAll(btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist); leftPanel.setPadding(new Insets(10,10,10,10)); - root.setLeft(leftPanel); - } - - private void addComponents(GridPane root) { - - btn_inputfile = new Button("Select input file"); - btn_reference = new Button("Select reference"); - btn_output = new Button("Select output"); - btn_plotting_options = new Button("Plotting options"); - btn_specieList = new Button("Set list"); - btn_run = new Button("Run"); - - Label label_threshold = new Label("Number of bases (x-axis)"); - Label label_yaxis = new Label("Height y-axis"); - Label label_length = new Label("Set number of bases (calculations)"); - Label label_specie = new Label("Filter for specie"); - Label label_title = new Label("Set title"); - Label label_plot = new Label("Plot"); - label_plot.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - Label label_files = new Label("Files"); - label_files.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - - Label label_calculations = new Label("Calculations"); - label_calculations.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - - Label label_title_config = new Label("Configuration"); - label_title_config.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); - - progressBar = new ProgressBar(0); - - textfield_threshold = new TextField(); - textfield_length = new TextField(); - textfield_specie = new TextField(); - textfield_title = new TextField(); - textfield_y_axis_height = new TextField(); - - checkbox_use_merged_reads = new CheckBox("Only merged reads"); - checkbos_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); - //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); - - btn_run.setDisable(true); - textfield_length.setText("100"); - textfield_threshold.setText("25"); - textfield_y_axis_height.setText("0.4"); - //checkbox_dynamic_y_axis_height.setSelected(true); - //textfield_y_axis_height.setDisable(true); - - - // add components to grid - - int row = 0; - - root.add(label_title_config, 0, row, 1,1); - root.add(new Separator(), 0, ++row,3,1); - - - root.add(label_files, 0, ++row, 1,1); - root.add(btn_inputfile, 0, ++row,1,1); - root.add(btn_reference, 1, row,1,1); - root.add(btn_output, 2, row,1,1); - root.add(new Separator(), 0, ++row,3,1); - - // PLOT - - root.add(label_plot, 0, ++row, 1,1); - root.add(label_title, 0, ++row, 1,1); - root.add(textfield_title, 1, row, 2,1); - root.add(label_yaxis, 0, ++row, 1,1); - //root.add(checkbox_dynamic_y_axis_height, 1, row, 1,1); - root.add(textfield_y_axis_height, 1, row, 2,1); - root.add(label_threshold, 0, ++row, 1,1); - root.add(textfield_threshold, 1, row, 2,1); - root.add(label_specie, 0, ++row, 1,1); - root.add(textfield_specie, 1, row, 2,1); - root.add(btn_specieList, 3, row, 1,1); - root.add(new Separator(), 0, ++row,3,1); - - // CALCULATIONS - root.add(label_calculations, 0, ++row, 1,1); - root.add(checkbox_use_merged_reads, 0, ++row,1,1); - root.add(checkbos_ssLibs_protocol, 0, ++row, 1,1); - root.add(label_length, 0, ++row, 1,1); - root.add(textfield_length, 1, row, 2,1); - root.add(new Separator(), 0, ++row,3,1); - root.add(btn_run, 0, ++row,1,1); - root.add(progressBar, 1, row,1,1); - + return leftPanel; } - public Button getBtn_inputfile() { - return btn_inputfile; - } - - public Button getBtn_reference() { - return btn_reference; - } - - public Button getBtn_output() { - return btn_output; - } - - public Button getBtn_plotting_options() { - return btn_plotting_options; - } - - public Button getBtn_run() { - return btn_run; - } - - public Button getBtn_specieList() { - return btn_specieList; - } - - public TextField getTextfield_threshold() { - return textfield_threshold; - } - - public TextField getTextfield_length() { - return textfield_length; - } - - public TextField getTextfield_specie() { - return textfield_specie; - } - - public CheckBox getCheckbox_use_merged_reads() { - return checkbox_use_merged_reads; - } - - public CheckBox getCheckbos_ssLibs_protocol() { - return checkbos_ssLibs_protocol; - } - - public TextField getTextfield_title() { - return textfield_title; - } - - public TextField getTextfield_y_axis_height() { - return textfield_y_axis_height; - } public Communicator getCommunicator() { return communicator; } - public ProgressBar getProgressBar() { - return progressBar; - } - public BorderPane getRoot() { return root; } - public GridPane getConfig_gridpane() { - return config_gridpane; - } - public Button getBtn_leftpane_identityDist() { return btn_leftpane_identityDist; } @@ -276,4 +106,8 @@ public Button getBtn_leftpane_damageProfile() { public Button getBtn_leftpane_lengthDist() { return btn_leftpane_lengthDist; } + + public ConfigurationDialogue getConfig_dialogue() { + return config_dialogue; + } } diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java new file mode 100644 index 0000000..d1716bb --- /dev/null +++ b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java @@ -0,0 +1,189 @@ +package GUI.Dialogues; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; + +public class ConfigurationDialogue { + + + private GridPane config_gridpane; + + private Button btn_inputfile; + private Button btn_reference; + private Button btn_output; + private Button btn_plotting_options; + private Button btn_run; + private Button btn_specieList; + + private TextField textfield_threshold; + private TextField textfield_length; + private TextField textfield_specie; + private CheckBox checkbox_use_merged_reads; + private CheckBox checkbox_ssLibs_protocol; + private TextField textfield_title; + //private CheckBox checkbox_dynamic_y_axis_height; + private TextField textfield_y_axis_height; + + private ProgressBar progressBar; + + + public ConfigurationDialogue(ProgressBar progressBar){ + + config_gridpane = new GridPane(); + config_gridpane.setAlignment(Pos.CENTER); + config_gridpane.setHgap(7); + config_gridpane.setVgap(7); + config_gridpane.setPadding(new Insets(10,10,10,10)); + + this.progressBar = progressBar; + addComponents(); + + } + + private void addComponents() { + + btn_inputfile = new Button("Select input file"); + btn_reference = new Button("Select reference"); + btn_output = new Button("Select output"); + btn_plotting_options = new Button("Plotting options"); + btn_specieList = new Button("Set list"); + btn_run = new Button("Run"); + + Label label_threshold = new Label("Number of bases (x-axis)"); + Label label_yaxis = new Label("Height y-axis"); + Label label_length = new Label("Set number of bases (calculations)"); + Label label_specie = new Label("Filter for specie"); + Label label_title = new Label("Set title"); + + Label label_plot = new Label("Plot"); + label_plot.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_files = new Label("Files"); + label_files.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_calculations = new Label("Calculations"); + label_calculations.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_title_config = new Label("Configuration"); + label_title_config.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + textfield_threshold = new TextField(); + textfield_length = new TextField(); + textfield_specie = new TextField(); + textfield_title = new TextField(); + textfield_y_axis_height = new TextField(); + + checkbox_use_merged_reads = new CheckBox("Only merged reads"); + checkbox_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); + //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); + + btn_run.setDisable(true); + textfield_length.setText("100"); + textfield_threshold.setText("25"); + textfield_y_axis_height.setText("0.4"); + //checkbox_dynamic_y_axis_height.setSelected(true); + //textfield_y_axis_height.setDisable(true); + + + // add components to grid + + int row = 0; + + config_gridpane.add(label_title_config, 0, row, 1,1); + config_gridpane.add(new Separator(), 0, ++row,3,1); + + + config_gridpane.add(label_files, 0, ++row, 1,1); + config_gridpane.add(btn_inputfile, 0, ++row,1,1); + config_gridpane.add(btn_reference, 1, row,1,1); + config_gridpane.add(btn_output, 2, row,1,1); + config_gridpane.add(new Separator(), 0, ++row,3,1); + + // PLOT + + config_gridpane.add(label_plot, 0, ++row, 1,1); + config_gridpane.add(label_title, 0, ++row, 1,1); + config_gridpane.add(textfield_title, 1, row, 2,1); + config_gridpane.add(label_yaxis, 0, ++row, 1,1); + //config_gridpane.add(checkbox_dynamic_y_axis_height, 1, row, 1,1); + config_gridpane.add(textfield_y_axis_height, 1, row, 2,1); + config_gridpane.add(label_threshold, 0, ++row, 1,1); + config_gridpane.add(textfield_threshold, 1, row, 2,1); + config_gridpane.add(label_specie, 0, ++row, 1,1); + config_gridpane.add(textfield_specie, 1, row, 2,1); + config_gridpane.add(btn_specieList, 3, row, 1,1); + config_gridpane.add(new Separator(), 0, ++row,3,1); + + // CALCULATIONS + config_gridpane.add(label_calculations, 0, ++row, 1,1); + config_gridpane.add(checkbox_use_merged_reads, 0, ++row,1,1); + config_gridpane.add(checkbox_ssLibs_protocol, 0, ++row, 1,1); + config_gridpane.add(label_length, 0, ++row, 1,1); + config_gridpane.add(textfield_length, 1, row, 2,1); + config_gridpane.add(new Separator(), 0, ++row,3,1); + config_gridpane.add(btn_run, 0, ++row,1,1); + config_gridpane.add(progressBar, 1, row,1,1); + + } + + public GridPane getConfig_gridpane() { + return config_gridpane; + } + + public Button getBtn_inputfile() { + return btn_inputfile; + } + + public Button getBtn_reference() { + return btn_reference; + } + + public Button getBtn_output() { + return btn_output; + } + + public Button getBtn_plotting_options() { + return btn_plotting_options; + } + + public Button getBtn_run() { + return btn_run; + } + + public Button getBtn_specieList() { + return btn_specieList; + } + + public TextField getTextfield_threshold() { + return textfield_threshold; + } + + public TextField getTextfield_length() { + return textfield_length; + } + + public TextField getTextfield_specie() { + return textfield_specie; + } + + public CheckBox getCheckbox_use_merged_reads() { + return checkbox_use_merged_reads; + } + + public CheckBox getCheckbox_ssLibs_protocol() { + return checkbox_ssLibs_protocol; + } + + public TextField getTextfield_title() { + return textfield_title; + } + + public TextField getTextfield_y_axis_height() { + return textfield_y_axis_height; + } + +} diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index 31fa340..07d3c3f 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -1,5 +1,7 @@ package IO; +import IO.PDFoutput.Histogram; +import IO.PDFoutput.LinePlot; import calculations.DamageProfiler; import calculations.Frequencies; import calculations.RuntimeEstimator; diff --git a/src/main/java/IO/Histogram.java b/src/main/java/IO/PDFoutput/Histogram.java similarity index 99% rename from src/main/java/IO/Histogram.java rename to src/main/java/IO/PDFoutput/Histogram.java index c36cf7c..5a12dc8 100755 --- a/src/main/java/IO/Histogram.java +++ b/src/main/java/IO/PDFoutput/Histogram.java @@ -1,4 +1,4 @@ -package IO; +package IO.PDFoutput; import org.apache.log4j.Logger; import org.jfree.chart.ChartFactory; diff --git a/src/main/java/IO/LinePlot.java b/src/main/java/IO/PDFoutput/LinePlot.java similarity index 99% rename from src/main/java/IO/LinePlot.java rename to src/main/java/IO/PDFoutput/LinePlot.java index 89caf7f..ee871fa 100755 --- a/src/main/java/IO/LinePlot.java +++ b/src/main/java/IO/PDFoutput/LinePlot.java @@ -1,4 +1,4 @@ -package IO; +package IO.PDFoutput; import org.apache.log4j.Logger; import org.jfree.chart.ChartFactory; diff --git a/src/main/java/StarterGUI.java b/src/main/java/StarterGUI.java index 6560571..fb8db4c 100755 --- a/src/main/java/StarterGUI.java +++ b/src/main/java/StarterGUI.java @@ -1,5 +1,6 @@ -import GUI.DamageProfilerMainController; +import controller.DamageProfilerMainController; import GUI.DamageProfilerMainGUI; +import controller.ProgressBarController; import javafx.application.Application; import javafx.stage.Stage; @@ -14,10 +15,13 @@ public class StarterGUI extends Application { @Override public void start(Stage primaryStage) { - DamageProfilerMainGUI damageProfilerMainGUI = new DamageProfilerMainGUI(VERSION); + ProgressBarController progressBarController = new ProgressBarController(); + progressBarController.create(); + + DamageProfilerMainGUI damageProfilerMainGUI = new DamageProfilerMainGUI(VERSION, progressBarController); damageProfilerMainGUI.init(primaryStage); - DamageProfilerMainController damageProfilerMainController = new DamageProfilerMainController(damageProfilerMainGUI); + DamageProfilerMainController damageProfilerMainController = new DamageProfilerMainController(damageProfilerMainGUI, progressBarController); diff --git a/src/main/java/IO/SpeciesListParser.java b/src/main/java/calculations/SpeciesListParser.java similarity index 96% rename from src/main/java/IO/SpeciesListParser.java rename to src/main/java/calculations/SpeciesListParser.java index e3ce623..d057f45 100755 --- a/src/main/java/IO/SpeciesListParser.java +++ b/src/main/java/calculations/SpeciesListParser.java @@ -1,6 +1,5 @@ -package IO; +package calculations; -import calculations.SpecieHandler; import org.apache.log4j.Logger; import java.io.BufferedReader; diff --git a/src/main/java/GUI/DamageProfilerMainController.java b/src/main/java/controller/DamageProfilerMainController.java similarity index 71% rename from src/main/java/GUI/DamageProfilerMainController.java rename to src/main/java/controller/DamageProfilerMainController.java index a76edc7..137c462 100644 --- a/src/main/java/GUI/DamageProfilerMainController.java +++ b/src/main/java/controller/DamageProfilerMainController.java @@ -1,5 +1,6 @@ -package GUI; +package controller; +import GUI.*; import GUI.Dialogues.AbstractDialogue; import GUI.Plots.DamagePlot; import GUI.Plots.IdentityHistPlot; @@ -10,7 +11,7 @@ import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.concurrent.Task; -import javafx.concurrent.WorkerStateEvent; +import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.control.*; import javafx.util.Duration; @@ -19,58 +20,57 @@ public class DamageProfilerMainController { - private final Button btn_leftpane_info; + private final Button btn_leftpane_run_config; private final Button btn_leftpane_identityDist; private final Button btn_leftpane_damageProfile; private final Button btn_leftpane_lengthDist; + private final ProgressBarController progressBarController; private Communicator communicator; private Button btn_inputfile; private Button btn_reference; private Button btn_output; - private Button btn_plotting_options; private Button btn_run; private Button btn_specieList; private TextField textfield_threshold; private TextField textfield_length; private TextField textfield_specie; private CheckBox checkbox_use_merged_reads; - private CheckBox checkbos_ssLibs_protocol; + private CheckBox checkbox_ssLibs_protocol; private TextField textfield_title; - //private CheckBox checkbox_dynamic_y_axis_height; private TextField textfield_y_axis_height; private StartCalculations starter = new StartCalculations(null); - private ProgressBar progressBar; - private Task startCalculuations; private DamageProfilerMainGUI mainGUI; + private boolean damagePlotGenerated = false; + private boolean idPlotsGenerated = false; + private boolean lengthPlotsGenerated = false; - public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI){ + public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, ProgressBarController progressBarController){ this.mainGUI = damageProfilerMainGUI; + this.progressBarController = progressBarController; this.communicator = mainGUI.getCommunicator(); - this.btn_inputfile = mainGUI.getBtn_inputfile(); - this.btn_reference = mainGUI.getBtn_reference(); - this.btn_output = mainGUI.getBtn_output(); - this.btn_plotting_options = mainGUI.getBtn_plotting_options(); - this.btn_run = mainGUI.getBtn_run(); - this.btn_specieList = mainGUI.getBtn_specieList(); - this.textfield_threshold = mainGUI.getTextfield_threshold(); - this.textfield_length = mainGUI.getTextfield_length(); - this.textfield_specie = mainGUI.getTextfield_specie(); - this.checkbox_use_merged_reads = mainGUI.getCheckbox_use_merged_reads(); - this.checkbos_ssLibs_protocol = mainGUI.getCheckbos_ssLibs_protocol(); - this.textfield_title = mainGUI.getTextfield_title(); - //this.checkbox_dynamic_y_axis_height = mainGUI.get??; - this.textfield_y_axis_height = mainGUI.getTextfield_y_axis_height(); - this.progressBar = mainGUI.getProgressBar(); + this.btn_inputfile = mainGUI.getConfig_dialogue().getBtn_inputfile(); + this.btn_reference = mainGUI.getConfig_dialogue().getBtn_reference(); + this.btn_output = mainGUI.getConfig_dialogue().getBtn_output(); + this.btn_run = mainGUI.getConfig_dialogue().getBtn_run(); + this.btn_specieList = mainGUI.getConfig_dialogue().getBtn_specieList(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); - this.btn_leftpane_info = mainGUI.getBtn_leftpane_info(); + this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); this.btn_leftpane_damageProfile = mainGUI.getBtn_leftpane_damageProfile(); this.btn_leftpane_lengthDist = mainGUI.getBtn_leftpane_lengthDist(); - addListener(); + this.textfield_threshold = mainGUI.getConfig_dialogue().getTextfield_threshold(); + this.textfield_length = mainGUI.getConfig_dialogue().getTextfield_length(); + this.textfield_specie = mainGUI.getConfig_dialogue().getTextfield_specie(); + this.textfield_title = mainGUI.getConfig_dialogue().getTextfield_title(); + this.textfield_y_axis_height = mainGUI.getConfig_dialogue().getTextfield_y_axis_height(); + this.checkbox_use_merged_reads = mainGUI.getConfig_dialogue().getCheckbox_use_merged_reads(); + this.checkbox_ssLibs_protocol = mainGUI.getConfig_dialogue().getCheckbox_ssLibs_protocol(); + //this.checkbox_dynamic_y_axis_height = mainGUI.getConfig_dialogue().get??; + addListener(); } @@ -166,7 +166,9 @@ private void addListener() { // set all user options communicator.setLength(Integer.parseInt(textfield_length.getText())); communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); - communicator.setSsLibsProtocolUsed(checkbos_ssLibs_protocol.isSelected()); + communicator.setSsLibsProtocolUsed(checkbox_ssLibs_protocol.isSelected()); + communicator.setUse_merged_and_mapped_reads(checkbox_use_merged_reads.isSelected()); + communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); if(textfield_specie.getText().equals("")) communicator.setSpecies_ref_identifier(null); @@ -189,24 +191,29 @@ private void addListener() { try { // add progress indicator - progressBar.setProgress(0); - startCalculuations = startCalculations(communicator, runtimeEstimator); - progressBar.progressProperty().unbind(); - progressBar.progressProperty().bind(startCalculuations.progressProperty()); - - startCalculuations.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, // - (EventHandler) t -> { - if(starter.isCalculationsDone()){ - // replace config with result GUI - btn_leftpane_lengthDist.setDisable(false); - btn_leftpane_identityDist.setDisable(false); - btn_leftpane_damageProfile.setDisable(false); - generateDamageProfile(); - } - }); + Task startCalculuations = new Task() { + @Override + protected Object call() throws Exception { + starter.start(communicator, runtimeEstimator); + + return true; + } + }; + + progressBarController.activate(startCalculuations); + startCalculuations.setOnSucceeded((EventHandler) event -> { + // replace config with result GUI + btn_leftpane_lengthDist.setDisable(false); + btn_leftpane_identityDist.setDisable(false); + btn_leftpane_damageProfile.setDisable(false); + generateDamageProfile(); + progressBarController.stop(); + + }); new Thread(startCalculuations).start(); + } catch (Exception e1) { e1.printStackTrace(); } @@ -235,43 +242,37 @@ private void addListener() { btn_leftpane_damageProfile.setOnAction(e -> { if(starter.isCalculationsDone()){ - if(plotAlreadyGenerated()){ - // show plot - } else { - // generate plot - generateDamageProfile(); - - } - } else { - mainGUI.getRoot().setCenter(null); + // generate plot + generateDamageProfile(); } }); btn_leftpane_identityDist.setOnAction(e -> { + if(starter.isCalculationsDone()){ - if(plotAlreadyGenerated()){ - // show plot - } else { - // generate plot - generateIdentityDist(); + // generate plot + generateIdentityDist(); + } - } - } else { - mainGUI.getRoot().setCenter(null); } }); btn_leftpane_lengthDist.setOnAction(e -> { + + if(starter.isCalculationsDone()){ - if(plotAlreadyGenerated()){ - // show plot - } else { - // generate plot - generateLengthDist(); + // generate plot + generateLengthDist(); + } - } + }); + + btn_leftpane_run_config.setOnAction(e -> { + if(plotAlreadyGenerated()){ + // show info (parameter / input / output / ...) + // ask for new configuration } else { - mainGUI.getRoot().setCenter(null); + mainGUI.getRoot().setCenter(mainGUI.getConfig_dialogue().getConfig_gridpane()); } }); @@ -302,17 +303,6 @@ private boolean plotAlreadyGenerated() { } - public Task startCalculations(Communicator communicator, RuntimeEstimator runtimeEstimator) { - return new Task() { - @Override - protected Object call() throws Exception { - starter.start(communicator, runtimeEstimator); - return true; - } - }; - } - - private boolean checkIfInputWasSelected() { boolean tmp = false; if (communicator.getInput() != null && communicator.getReference() != null && communicator.getOutfolder() != null) { @@ -324,7 +314,6 @@ private boolean checkIfInputWasSelected() { } - private static void setTooltipDelay(Tooltip tooltip) { try { Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR"); diff --git a/src/main/java/controller/ProgressBarController.java b/src/main/java/controller/ProgressBarController.java new file mode 100644 index 0000000..b4dd92d --- /dev/null +++ b/src/main/java/controller/ProgressBarController.java @@ -0,0 +1,34 @@ +package controller; + +import javafx.concurrent.Task; +import javafx.geometry.Insets; +import javafx.scene.control.ProgressBar; + +public class ProgressBarController { + + private ProgressBar progressBar; + + + public void create(){ + progressBar = new ProgressBar(0); + progressBar.setDisable(true); + progressBar.setPadding(new Insets(5,5,5,5)); + } + + public void activate(Task task){ + progressBar.progressProperty().unbind(); + progressBar.setProgress(0); + progressBar.progressProperty().bind(task.progressProperty()); + + } + + public void stop(){ + progressBar.progressProperty().unbind(); + progressBar.setProgress(0); + progressBar.setDisable(true); + } + + public ProgressBar getProgressBar() { + return progressBar; + } +} From e898f12780bbc57152aea67de953f021a249ce2b Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Tue, 24 Mar 2020 16:24:31 +0100 Subject: [PATCH 07/22] GUI visualized actual results --- src/main/java/GUI/DamageProfilerMainGUI.java | 4 + .../GUI/Dialogues/AbstractApplication.java | 48 ++++ .../java/GUI/Dialogues/AbstractDialogue.java | 42 +--- .../GUI/Dialogues/ConfigurationDialogue.java | 20 +- .../java/GUI/Dialogues/RunInfoDialogue.java | 65 ++++++ .../Dialogues/RuntimeEstimatorDialogue.java | 49 ++++ src/main/java/GUI/Plots/DamagePlot.java | 142 +++++++----- src/main/java/GUI/Plots/IdentityHistPlot.java | 118 ++++------ src/main/java/GUI/Plots/LengthDistPlot.java | 182 +++++++++++---- src/main/java/IO/OutputGenerator.java | 29 ++- src/main/java/RunDamageProfiler.java | 2 - src/main/java/StarterCLI.java | 5 +- .../java/calculations/DamageProfiler.java | 9 +- .../java/calculations/RuntimeEstimator.java | 18 +- .../java/calculations/StartCalculations.java | 38 +-- .../DamageProfilerMainController.java | 218 ++++++++++-------- 16 files changed, 647 insertions(+), 342 deletions(-) create mode 100644 src/main/java/GUI/Dialogues/AbstractApplication.java create mode 100644 src/main/java/GUI/Dialogues/RunInfoDialogue.java create mode 100644 src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java index 8364c0f..419fb01 100644 --- a/src/main/java/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/GUI/DamageProfilerMainGUI.java @@ -110,4 +110,8 @@ public Button getBtn_leftpane_lengthDist() { public ConfigurationDialogue getConfig_dialogue() { return config_dialogue; } + + public String getVersion() { + return version; + } } diff --git a/src/main/java/GUI/Dialogues/AbstractApplication.java b/src/main/java/GUI/Dialogues/AbstractApplication.java new file mode 100644 index 0000000..21604d6 --- /dev/null +++ b/src/main/java/GUI/Dialogues/AbstractApplication.java @@ -0,0 +1,48 @@ +package GUI.Dialogues; + +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.layout.GridPane; +import javafx.stage.Modality; +import javafx.stage.Stage; + +public class AbstractApplication { + + private final Stage stage; + protected GridPane gridPane; + protected int row; + + public AbstractApplication(String header, String message){ + + stage = new Stage(); + stage.setTitle(header); + stage.initModality(Modality.APPLICATION_MODAL); + stage.initOwner(new Stage()); + + gridPane = new GridPane(); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(10); + gridPane.setVgap(10); + + fillGrid(message); + + } + + private void fillGrid(String message) { + row = 0; + gridPane.add(new Label(message), 0,row,2,1); + gridPane.add(new Separator(), 0,++row,2,1); + } + + public void show(){ + Scene dialogScene = new Scene(gridPane, 600, 200); + stage.setScene(dialogScene); + stage.show(); + } + + public void close() { + stage.close(); + } +} diff --git a/src/main/java/GUI/Dialogues/AbstractDialogue.java b/src/main/java/GUI/Dialogues/AbstractDialogue.java index d167785..9f6df78 100644 --- a/src/main/java/GUI/Dialogues/AbstractDialogue.java +++ b/src/main/java/GUI/Dialogues/AbstractDialogue.java @@ -1,57 +1,39 @@ package GUI.Dialogues; +import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.Separator; import javafx.scene.layout.GridPane; -import javafx.stage.Modality; -import javafx.stage.Stage; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; public class AbstractDialogue { - private final Stage stage; - private GridPane gridPane; - private int row; - - public AbstractDialogue (String header, String message){ - - stage = new Stage(); - stage.setTitle(header); - stage.initModality(Modality.APPLICATION_MODAL); - stage.initOwner(new Stage()); + protected GridPane gridPane; + protected int row; + public AbstractDialogue(String message){ gridPane = new GridPane(); gridPane.setAlignment(Pos.CENTER); gridPane.setHgap(10); gridPane.setVgap(10); + gridPane.setPadding(new Insets(15,15,15,15)); fillGrid(message); - } private void fillGrid(String message) { + + Label label_message = new Label(message); + label_message.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + row = 0; - gridPane.add(new Label(message), 0,row,2,1); + gridPane.add(label_message, 0,row,2,1); gridPane.add(new Separator(), 0,++row,2,1); } - public void show(){ - Scene dialogScene = new Scene(gridPane, 600, 200); - stage.setScene(dialogScene); - stage.show(); - } - public GridPane getGridPane() { return gridPane; } - - public int getRow() { - return row; - } - - - public void close() { - stage.close(); - } } diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java index d1716bb..0cc7b67 100644 --- a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java @@ -15,8 +15,8 @@ public class ConfigurationDialogue { private Button btn_inputfile; private Button btn_reference; private Button btn_output; - private Button btn_plotting_options; private Button btn_run; + private Button btn_estimate_runtime; private Button btn_specieList; private TextField textfield_threshold; @@ -49,9 +49,9 @@ private void addComponents() { btn_inputfile = new Button("Select input file"); btn_reference = new Button("Select reference"); btn_output = new Button("Select output"); - btn_plotting_options = new Button("Plotting options"); btn_specieList = new Button("Set list"); btn_run = new Button("Run"); + btn_estimate_runtime = new Button("Estimate Runtime"); Label label_threshold = new Label("Number of bases (x-axis)"); Label label_yaxis = new Label("Height y-axis"); @@ -82,12 +82,10 @@ private void addComponents() { //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); btn_run.setDisable(true); + btn_estimate_runtime.setDisable(true); textfield_length.setText("100"); textfield_threshold.setText("25"); textfield_y_axis_height.setText("0.4"); - //checkbox_dynamic_y_axis_height.setSelected(true); - //textfield_y_axis_height.setDisable(true); - // add components to grid @@ -125,8 +123,9 @@ private void addComponents() { config_gridpane.add(label_length, 0, ++row, 1,1); config_gridpane.add(textfield_length, 1, row, 2,1); config_gridpane.add(new Separator(), 0, ++row,3,1); - config_gridpane.add(btn_run, 0, ++row,1,1); - config_gridpane.add(progressBar, 1, row,1,1); + config_gridpane.add(btn_estimate_runtime, 0, ++row,1,1); + config_gridpane.add(btn_run, 1, row,1,1); + config_gridpane.add(progressBar, 2, row,1,1); } @@ -146,10 +145,6 @@ public Button getBtn_output() { return btn_output; } - public Button getBtn_plotting_options() { - return btn_plotting_options; - } - public Button getBtn_run() { return btn_run; } @@ -186,4 +181,7 @@ public TextField getTextfield_y_axis_height() { return textfield_y_axis_height; } + public Button getBtn_estimate_runtime() { + return btn_estimate_runtime; + } } diff --git a/src/main/java/GUI/Dialogues/RunInfoDialogue.java b/src/main/java/GUI/Dialogues/RunInfoDialogue.java new file mode 100644 index 0000000..53ca676 --- /dev/null +++ b/src/main/java/GUI/Dialogues/RunInfoDialogue.java @@ -0,0 +1,65 @@ +package GUI.Dialogues; + +import IO.Communicator; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.Separator; + +public class RunInfoDialogue extends AbstractDialogue { + + private final Communicator communicator; + private Button btn_new_config; + private ScrollPane scrollPaneRef; + private ScrollPane scrollPaneInput; + private ScrollPane scrollPaneOutput; + + public RunInfoDialogue(String message, Communicator communicator){ + super(message); + this.communicator = communicator; + btn_new_config = new Button("New configuration"); + init(); + } + + + public void init() { + + scrollPaneInput = new ScrollPane( new Label(communicator.getInput())); + scrollPaneOutput = new ScrollPane( new Label(communicator.getOutfolder())); + scrollPaneRef = new ScrollPane( new Label(communicator.getReference())); + + + Label label_input = new Label("Input file: "); + Label label_output = new Label("Output folder: "); + Label label_ref = new Label("Reference file: "); + + + gridPane.add(label_input, 0,++row, 1,1); + gridPane.add(scrollPaneInput, 1,row, 2,1); + + gridPane.add(label_output, 0,++row, 1,1); + gridPane.add(scrollPaneOutput, 1,row, 2,1); + + gridPane.add(label_ref, 0,++row, 1,1); + gridPane.add(scrollPaneRef, 1,row, 2,1); + + gridPane.add(new Separator(), 0,++row, 1,2); + + + + gridPane.add(btn_new_config, 0, ++row, 1,1); + + } + + public void updateParameters(){ + scrollPaneInput.setContent(new Label(communicator.getInput())); + scrollPaneOutput.setContent( new Label(communicator.getOutfolder())); + scrollPaneRef.setContent(new Label(communicator.getReference())); + + } + + + public Button getBtn_new_config() { + return btn_new_config; + } +} diff --git a/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java b/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java new file mode 100644 index 0000000..09f94d6 --- /dev/null +++ b/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java @@ -0,0 +1,49 @@ +package GUI.Dialogues; + +import javafx.scene.control.Button; +import javafx.scene.control.Label; + +public class RuntimeEstimatorDialogue extends AbstractApplication { + + private final Button btn_proceed; + private final Button btn_cancel; + private int numberOfRecords; + private String text_estimatedRuntime; + + public RuntimeEstimatorDialogue(String header, String message) { + super(header, message); + + + btn_proceed = new Button("Proceed"); + btn_cancel = new Button("Cancel"); + + + } + + public void setNumberOfRecords(int numberOfRecords) { + this.numberOfRecords = numberOfRecords; + } + + public void setResultText(String text_estimatedRuntime) { + this.text_estimatedRuntime = text_estimatedRuntime; + } + + public void addComponents(){ + this.gridPane.add(new Label("Number of reads: " + numberOfRecords), 0, ++row, 2,1); + this.gridPane.add(new Label(text_estimatedRuntime), 0, ++row, 2,1); + this.gridPane.add(btn_cancel, 0, ++row, 1,1); + this.gridPane.add(btn_proceed, 1, row, 1,1); + + + } + + + public Button getBtn_proceed() { + return btn_proceed; + } + + public Button getBtn_cancel() { + return btn_cancel; + } + +} diff --git a/src/main/java/GUI/Plots/DamagePlot.java b/src/main/java/GUI/Plots/DamagePlot.java index d8b88ce..a80e63c 100644 --- a/src/main/java/GUI/Plots/DamagePlot.java +++ b/src/main/java/GUI/Plots/DamagePlot.java @@ -1,77 +1,111 @@ package GUI.Plots; +import IO.OutputGenerator; +import calculations.StartCalculations; import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; +import javafx.scene.layout.HBox; public class DamagePlot { - private final LineChart lineChart; - public DamagePlot() { + private final StartCalculations starter; + private OutputGenerator outputGenerator; + private LineChart lineChart3prime; + private LineChart lineChart5prime; - CategoryAxis xAxis = new CategoryAxis(); - NumberAxis yAxis = new NumberAxis(); - xAxis.setLabel("Month"); - lineChart = - new LineChart(xAxis,yAxis); + public DamagePlot(OutputGenerator outputGenerator, StartCalculations starter) { - lineChart.setTitle("Stock Monitoring, 2010"); + this.outputGenerator = outputGenerator; + this.starter = starter; + + CategoryAxis xAxis_5 = new CategoryAxis(); + NumberAxis yAxis_5 = new NumberAxis(0.0, outputGenerator.getMaxYdamapePlot(), 0.05); + + CategoryAxis xAxis_3 = new CategoryAxis(); + NumberAxis yAxis_3 = new NumberAxis(0.0, outputGenerator.getMaxYdamapePlot(), 0.05); + + lineChart5prime = new LineChart(xAxis_5,yAxis_5); + lineChart5prime.setCreateSymbols(false); + + lineChart3prime = new LineChart(xAxis_3,yAxis_3); + lineChart3prime.setCreateSymbols(false); + + createFivePrimePlot(); + createThreePrimePlot(); + + } + + + private void createFivePrimePlot() { + + lineChart5prime.setTitle("5' end"); + + // C -> T misincorporations 5' + XYChart.Series series1 = new XYChart.Series(); + series1.setName("C -> T"); + + double[] data_C_T_5 = starter.getDamageProfiler().getFrequencies().getCount_C_T_5_norm(); + for(int i = 0; i < outputGenerator.getThreshold(); i++){ + series1.getData().add(new XYChart.Data(String.valueOf(i+1), data_C_T_5[i])); + } + + // G -> A misincorporations 5' + XYChart.Series series2 = new XYChart.Series(); + series2.setName("G -> A"); + + double[] data_G_A_5 = starter.getDamageProfiler().getFrequencies().getCount_G_A_5_norm(); + for(int i = 0; i < outputGenerator.getThreshold(); i++){ + series2.getData().add(new XYChart.Data(String.valueOf(i+1), data_G_A_5[i])); + } + + lineChart5prime.getData().addAll(series1, series2); + + } + + private void createThreePrimePlot() { + + lineChart3prime.setTitle("3' end"); + + // C -> T misincorporations 3' XYChart.Series series1 = new XYChart.Series(); - series1.setName("Portfolio 1"); - - series1.getData().add(new XYChart.Data("Jan", 23)); - series1.getData().add(new XYChart.Data("Feb", 14)); - series1.getData().add(new XYChart.Data("Mar", 15)); - series1.getData().add(new XYChart.Data("Apr", 24)); - series1.getData().add(new XYChart.Data("May", 34)); - series1.getData().add(new XYChart.Data("Jun", 36)); - series1.getData().add(new XYChart.Data("Jul", 22)); - series1.getData().add(new XYChart.Data("Aug", 45)); - series1.getData().add(new XYChart.Data("Sep", 43)); - series1.getData().add(new XYChart.Data("Oct", 17)); - series1.getData().add(new XYChart.Data("Nov", 29)); - series1.getData().add(new XYChart.Data("Dec", 25)); + series1.setName("C -> T"); + double[] data_C_T_3 = this.outputGenerator.getThree_C_to_T_reverse(); + + for(int i = 0; i < outputGenerator.getThreshold(); i++){ + series1.getData().add(new XYChart.Data(String.valueOf(i+1), data_C_T_3[i])); + } + + + + // G -> A misincorporations 3' XYChart.Series series2 = new XYChart.Series(); - series2.setName("Portfolio 2"); - series2.getData().add(new XYChart.Data("Jan", 33)); - series2.getData().add(new XYChart.Data("Feb", 34)); - series2.getData().add(new XYChart.Data("Mar", 25)); - series2.getData().add(new XYChart.Data("Apr", 44)); - series2.getData().add(new XYChart.Data("May", 39)); - series2.getData().add(new XYChart.Data("Jun", 16)); - series2.getData().add(new XYChart.Data("Jul", 55)); - series2.getData().add(new XYChart.Data("Aug", 54)); - series2.getData().add(new XYChart.Data("Sep", 48)); - series2.getData().add(new XYChart.Data("Oct", 27)); - series2.getData().add(new XYChart.Data("Nov", 37)); - series2.getData().add(new XYChart.Data("Dec", 29)); - - XYChart.Series series3 = new XYChart.Series(); - series3.setName("Portfolio 3"); - series3.getData().add(new XYChart.Data("Jan", 44)); - series3.getData().add(new XYChart.Data("Feb", 35)); - series3.getData().add(new XYChart.Data("Mar", 36)); - series3.getData().add(new XYChart.Data("Apr", 33)); - series3.getData().add(new XYChart.Data("May", 31)); - series3.getData().add(new XYChart.Data("Jun", 26)); - series3.getData().add(new XYChart.Data("Jul", 22)); - series3.getData().add(new XYChart.Data("Aug", 25)); - series3.getData().add(new XYChart.Data("Sep", 43)); - series3.getData().add(new XYChart.Data("Oct", 44)); - series3.getData().add(new XYChart.Data("Nov", 45)); - series3.getData().add(new XYChart.Data("Dec", 44)); - - lineChart.getData().addAll(series1, series2, series3); + series2.setName("G -> A"); + double[] data_G_A_3 = this.outputGenerator.getThree_G_to_A_reverse(); + + for(int i = 0; i < outputGenerator.getThreshold(); i++){ + series2.getData().add(new XYChart.Data(String.valueOf(i+1), data_G_A_3[i])); + } + lineChart3prime.getData().addAll(series1, series2); } - public LineChart getLineChart() { - return lineChart; + public HBox getDamageProfile() { + HBox plots_combined = new HBox(); + + lineChart5prime.prefHeightProperty().bind(plots_combined.heightProperty()); + lineChart5prime.prefWidthProperty().bind(plots_combined.widthProperty()); + + lineChart3prime.prefHeightProperty().bind(plots_combined.heightProperty()); + lineChart3prime.prefWidthProperty().bind(plots_combined.widthProperty()); + + plots_combined.getChildren().addAll(lineChart5prime, lineChart3prime); + return plots_combined; } } diff --git a/src/main/java/GUI/Plots/IdentityHistPlot.java b/src/main/java/GUI/Plots/IdentityHistPlot.java index 360fd21..11176e6 100644 --- a/src/main/java/GUI/Plots/IdentityHistPlot.java +++ b/src/main/java/GUI/Plots/IdentityHistPlot.java @@ -1,113 +1,79 @@ package GUI.Plots; -import javafx.scene.Scene; -import javafx.scene.chart.BarChart; -import javafx.scene.chart.CategoryAxis; -import javafx.scene.chart.NumberAxis; -import javafx.scene.chart.XYChart; -import javafx.scene.control.Label; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; +import javafx.scene.chart.*; +import java.util.*; -import java.util.Random; public class IdentityHistPlot { + private BarChart barChart; - private final StackPane root; - int DATA_SIZE = 1000; - int data[] = new int[DATA_SIZE]; - int group[] = new int[10]; + private Double[] data; + private HashMap idents_count; - public IdentityHistPlot(){ + public IdentityHistPlot(ArrayList identity_data) { - - prepareData(); + prepareData(identity_data); groupData(); - Label labelInfo = new Label(); - labelInfo.setText( - "java.version: " + System.getProperty("java.version") + "\n" + - "javafx.runtime.version: " + System.getProperty("javafx.runtime.version") - ); - final CategoryAxis xAxis = new CategoryAxis(); final NumberAxis yAxis = new NumberAxis(); - final BarChart barChart = - new BarChart<>(xAxis,yAxis); + barChart = new BarChart<>(xAxis,yAxis); + barChart.setCategoryGap(0); - barChart.setBarGap(0); + barChart.setBarGap(1); + barChart.setTitle("Read identity"); - xAxis.setLabel("Range"); - yAxis.setLabel("Population"); + yAxis.setLabel("Number of reads"); + xAxis.setLabel("Read identity"); XYChart.Series series1 = new XYChart.Series(); - series1.setName("Histogram"); - series1.getData().add(new XYChart.Data("0-10", group[0])); - series1.getData().add(new XYChart.Data("10-20", group[1])); - series1.getData().add(new XYChart.Data("20-30", group[2])); - series1.getData().add(new XYChart.Data("30-40", group[3])); - series1.getData().add(new XYChart.Data("40-50", group[4])); - - series1.getData().add(new XYChart.Data("50-60", group[5])); - series1.getData().add(new XYChart.Data("60-70", group[6])); - series1.getData().add(new XYChart.Data("70-80", group[7])); - series1.getData().add(new XYChart.Data("80-90", group[8])); - series1.getData().add(new XYChart.Data("90-100", group[9])); - barChart.getData().addAll(series1); + List targetList = new ArrayList<>(idents_count.keySet()); + Collections.sort(targetList); - VBox vBox = new VBox(); - vBox.getChildren().addAll(labelInfo, barChart); + for(double d : targetList){ + if (idents_count.containsKey(d)){ + series1.getData().add(new XYChart.Data(String.valueOf(d), idents_count.get(d))); + } else { + series1.getData().add(new XYChart.Data(String.valueOf(d), 0)); + } - root = new StackPane(); - root.getChildren().add(vBox); + } + barChart.getData().addAll(series1); } - //generate dummy random data - private void prepareData(){ - Random random = new Random(); - for(int i=0; i identity_data){ + data = new Double[identity_data.size()]; + for(int i=0; i < identity_data.size(); i++){ + data[i] = Math.round(identity_data.get(i) * 1000.0) / 1000.0; } } - //count data population in groups + //count data identities in groups private void groupData(){ - for(int i=0; i<10; i++){ - group[i]=0; - } - for(int i=0; i(); + + for (double ident : data) { + if (!idents_count.containsKey(ident)) { + idents_count.put(ident, 1); + } else { + int count_tmp = idents_count.get(ident); + count_tmp=count_tmp+1; + idents_count.put(ident, count_tmp); } } + } - public StackPane getRoot() { - return root; + public BarChart getBarChart() { + return barChart; } } diff --git a/src/main/java/GUI/Plots/LengthDistPlot.java b/src/main/java/GUI/Plots/LengthDistPlot.java index 1a98e66..05b1ae2 100644 --- a/src/main/java/GUI/Plots/LengthDistPlot.java +++ b/src/main/java/GUI/Plots/LengthDistPlot.java @@ -1,56 +1,156 @@ package GUI.Plots; -import javafx.scene.Scene; +import calculations.DamageProfiler; import javafx.scene.chart.BarChart; import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; +import javafx.scene.layout.HBox; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; public class LengthDistPlot { - final static String austria = "Austria"; - final static String brazil = "Brazil"; - final static String france = "France"; - final static String italy = "Italy"; - final static String usa = "USA"; - private final BarChart bc; - - public LengthDistPlot(){ - CategoryAxis xAxis = new CategoryAxis(); - NumberAxis yAxis = new NumberAxis(); - bc = new BarChart(xAxis,yAxis); - bc.setTitle("Country Summary"); - xAxis.setLabel("Country"); - yAxis.setLabel("Value"); + private BarChart bc_data_all; + private BarChart bc_data_split; + + public LengthDistPlot(DamageProfiler damageProfiler){ + + generate_alldata(damageProfiler.getLength_all()); + generate_split_data(damageProfiler.getLength_distribution_map_forward(), + damageProfiler.getLength_distribution_map_reverse()); + + + } + + private void generate_split_data(HashMap length_distribution_map_forward, HashMap length_distribution_map_reverse) { + + //Double[] data_forward = prepareData((List) length_distribution_map_forward); + //Double[] data_reverse = prepareData((List) length_distribution_map_reverse); + + HashMap length_map_forward = length_distribution_map_forward; + HashMap length_map_reverse = length_distribution_map_reverse; + + final CategoryAxis xAxis = new CategoryAxis(); + final NumberAxis yAxis = new NumberAxis(); + bc_data_split = new BarChart<>(xAxis,yAxis); + + bc_data_split.setCategoryGap(0); + bc_data_split.setBarGap(1); + bc_data_split.setTitle("Read length distribution"); + + yAxis.setLabel("Number of reads"); + xAxis.setLabel("Read length"); + + XYChart.Series series_forward = new XYChart.Series(); + + List targetList_forward = new ArrayList<>(length_map_forward.keySet()); + Collections.sort(targetList_forward); + + for(int d : targetList_forward){ + if (length_map_forward.containsKey(d)){ + series_forward.getData().add(new XYChart.Data(String.valueOf(d), length_map_forward.get(d))); + } else { + series_forward.getData().add(new XYChart.Data(String.valueOf(d), 0)); + } + + } + + + XYChart.Series series_reverse = new XYChart.Series(); + + List targetList_reverse = new ArrayList<>(length_map_reverse.keySet()); + Collections.sort(targetList_reverse); + + for(double d : targetList_reverse){ + if (length_map_reverse.containsKey(d)){ + series_reverse.getData().add(new XYChart.Data(String.valueOf(d), length_map_reverse.get(d))); + } else { + series_reverse.getData().add(new XYChart.Data(String.valueOf(d), 0)); + } + + } + bc_data_split.getData().addAll(series_forward, series_reverse); + + + } + + private void generate_alldata(List length_all) { + + Double[] data_all = prepareData(length_all); + HashMap length_map_all = groupData(data_all); + + + final CategoryAxis xAxis = new CategoryAxis(); + final NumberAxis yAxis = new NumberAxis(); + bc_data_all = new BarChart<>(xAxis,yAxis); + + bc_data_all.setCategoryGap(0); + bc_data_all.setBarGap(1); + bc_data_all.setTitle("Read length distribution"); + + yAxis.setLabel("Number of reads"); + xAxis.setLabel("Read length"); XYChart.Series series1 = new XYChart.Series(); - series1.setName("2003"); - series1.getData().add(new XYChart.Data(austria, 25601.34)); - series1.getData().add(new XYChart.Data(brazil, 20148.82)); - series1.getData().add(new XYChart.Data(france, 10000)); - series1.getData().add(new XYChart.Data(italy, 35407.15)); - series1.getData().add(new XYChart.Data(usa, 12000)); - - XYChart.Series series2 = new XYChart.Series(); - series2.setName("2004"); - series2.getData().add(new XYChart.Data(austria, 57401.85)); - series2.getData().add(new XYChart.Data(brazil, 41941.19)); - series2.getData().add(new XYChart.Data(france, 45263.37)); - series2.getData().add(new XYChart.Data(italy, 117320.16)); - series2.getData().add(new XYChart.Data(usa, 14845.27)); - - XYChart.Series series3 = new XYChart.Series(); - series3.setName("2005"); - series3.getData().add(new XYChart.Data(austria, 45000.65)); - series3.getData().add(new XYChart.Data(brazil, 44835.76)); - series3.getData().add(new XYChart.Data(france, 18722.18)); - series3.getData().add(new XYChart.Data(italy, 17557.31)); - series3.getData().add(new XYChart.Data(usa, 92633.68)); - - bc.getData().addAll(series1, series2, series3); + + List targetList = new ArrayList<>(length_map_all.keySet()); + Collections.sort(targetList); + + for(double d : targetList){ + if (length_map_all.containsKey(d)){ + series1.getData().add(new XYChart.Data(String.valueOf(d), length_map_all.get(d))); + } else { + series1.getData().add(new XYChart.Data(String.valueOf(d), 0)); + } + + } + + bc_data_all.getData().addAll(series1); + + } + + private HashMap groupData(Double[] data_all) { + + HashMap idents_count = new HashMap(); + + for (double ident : data_all) { + if (!idents_count.containsKey(ident)) { + idents_count.put(ident, 1); + } else { + int count_tmp = idents_count.get(ident); + count_tmp=count_tmp+1; + idents_count.put(ident, count_tmp); + } + } + + return idents_count; + } + + private Double[] prepareData(List length_data_all) { + + + Double[] data_all = new Double[length_data_all.size()]; + for(int i=0; i < length_data_all.size(); i++){ + data_all[i] = Math.round(length_data_all.get(i) * 1000.0) / 1000.0; + } + + return data_all; } - public BarChart getBc() { - return bc; + public HBox getBc() { + HBox plots_combined = new HBox(); + + bc_data_all.prefHeightProperty().bind(plots_combined.heightProperty()); + bc_data_all.prefWidthProperty().bind(plots_combined.widthProperty()); + + bc_data_split.prefHeightProperty().bind(plots_combined.heightProperty()); + bc_data_split.prefWidthProperty().bind(plots_combined.widthProperty()); + + plots_combined.getChildren().addAll(bc_data_all, bc_data_split); + return plots_combined; } } diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index 07d3c3f..b3b23b5 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -47,7 +47,7 @@ public class OutputGenerator { private String outpath; private Frequencies frequencies; private DamageProfiler damageProfiler; - private RuntimeEstimator runtimeEstimator; + private int numberOfRecords; private int max_length; private int min_length; private String specie; @@ -55,13 +55,14 @@ public class OutputGenerator { private int length; private String input; private HashMap json_map = new HashMap<>(); - + private double[] three_C_to_T_reverse; + private double[] three_G_to_A_reverse; public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, - RuntimeEstimator runtimeEstimator, boolean ssLibProtocolUsed) { + int numberOfRecords, boolean ssLibProtocolUsed) { this.outpath = outputFolder; this.frequencies = damageProfiler.getFrequencies(); @@ -76,7 +77,7 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.x_axis_max_length_histo = x_axis_max_length_histo; this.input = input; this.LOG = LOG; - this.runtimeEstimator = runtimeEstimator; + this.numberOfRecords = numberOfRecords; this.ssLibProtocolUsed = ssLibProtocolUsed; // set tax id if specified by user @@ -724,9 +725,9 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep double[] three_C_to_A_reverse = getSubArray(frequencies.getCount_C_A_3_norm(), threshold); double[] three_C_to_G_reverse = getSubArray(frequencies.getCount_C_G_3_norm(), threshold); - double[] three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); + three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); - double[] three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); + three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); double[] three_G_to_C_reverse = getSubArray(frequencies.getCount_G_C_3_norm(),threshold); double[] three_G_to_T_reverse = getSubArray(frequencies.getCount_G_T_3_norm(),threshold); @@ -932,7 +933,7 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws document.open(); // compute percentage of used reads - double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / (double) runtimeEstimator.getNumberOfRecords(); + double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / numberOfRecords; // draw text String[] splitted = file.split("/"); @@ -984,5 +985,19 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws document.close(); } + public int getThreshold() { + return threshold; + } + + public double[] getThree_C_to_T_reverse() { + return three_C_to_T_reverse; + } + public double[] getThree_G_to_A_reverse() { + return three_G_to_A_reverse; + } + + public double getMaxYdamapePlot() { + return height; + } } diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index ff36daa..a57a0dc 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -29,8 +29,6 @@ public static void main(String[] args) throws Exception { } else { StarterCLI starterCLI = new StarterCLI(VERSION, args); - - } diff --git a/src/main/java/StarterCLI.java b/src/main/java/StarterCLI.java index e59ea85..2816d40 100644 --- a/src/main/java/StarterCLI.java +++ b/src/main/java/StarterCLI.java @@ -7,9 +7,10 @@ public class StarterCLI { public StarterCLI(String version, String[] args) throws Exception { Communicator c = new Communicator(); - StartCalculations starter = new StartCalculations(version); + StartCalculations starter = new StartCalculations(); + starter.setVERSION(version); UserOptionsParser userOptions = new UserOptionsParser(args, c, version); RuntimeEstimator runtimeEstimator = new RuntimeEstimator(c.getInput()); - starter.start(c, runtimeEstimator); + starter.start(c); } } diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index ea8a39e..5196083 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -24,6 +24,7 @@ public class DamageProfiler { private Logger LOG=null; private IndexedFastaSequenceFile fastaSequenceFile; private int numberOfUsedReads; + private int numberOfRecords; private int threshold; private int length; private Frequencies frequencies; @@ -67,6 +68,7 @@ public void init(File input, File reference, int threshold, int length, String s validationStringency(ValidationStringency.LENIENT).open(input); numberOfUsedReads = 0; + numberOfRecords = 0; this.LOG = LOG; this.threshold = threshold; this.length = length; @@ -111,6 +113,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea long startTime = System.currentTimeMillis(); for(SAMRecord record : inputSam) { + numberOfRecords++; if (this.specie == null) { @@ -321,7 +324,8 @@ public int getNumberOfUsedReads() { return numberOfUsedReads; } - public ArrayList getIdentity() { return identity; } + public ArrayList getIdentity() { + return identity; } public String getSpeciesname(File file, String ref) { @@ -342,4 +346,7 @@ public long getActualRuntime() { return actualRuntime; } + public int getNumberOfRecords() { + return numberOfRecords; + } } diff --git a/src/main/java/calculations/RuntimeEstimator.java b/src/main/java/calculations/RuntimeEstimator.java index 572972e..eb826b1 100644 --- a/src/main/java/calculations/RuntimeEstimator.java +++ b/src/main/java/calculations/RuntimeEstimator.java @@ -19,11 +19,12 @@ public RuntimeEstimator(String inputfile){ validationStringency(ValidationStringency.LENIENT).open(new File(inputfile)); estimate(); + } - private void estimate() { + public void estimate() { // estimate runtime: - numberOfRecords = getNumberOfrecords(); + numberOfRecords = getNumberOfRecordsIntern(); System.out.println("Number of records to process: " + numberOfRecords); estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); @@ -38,24 +39,21 @@ private void estimate() { } - private long getNumberOfrecords() { + private long getNumberOfRecordsIntern() { long count = 0; for(SAMRecord record : input){ count++; } - input=null; - return count; } - public long getNumberOfRecords() { - return numberOfRecords; - } - - public long getEstimatedRuntimeInSeconds() { return estimatedRuntimeInSeconds; } + + public int getNumberOfRecords() { + return (int)numberOfRecords; + } } diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index f76482a..59c4439 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -16,10 +16,10 @@ */ public class StartCalculations { - private final String VERSION; + private String VERSION; private LogClass logClass; private long currtime_prior_execution; // start time to get overall runtime - private boolean calculationsDone = true; + private boolean calculationsDone = false; private Logger LOG; private List specieslist = null; private List species_name_list; @@ -39,19 +39,21 @@ public class StartCalculations { private double xaxis_max_id_histogram; private double xaxis_min_length_histogram; private double xaxis_max_length_histogram; - private RuntimeEstimator runtimeEstimator; private boolean ssLibProtocolUsed; private DamageProfiler damageProfiler; + private OutputGenerator outputGenerator; - public StartCalculations(String version){ - VERSION = version; + public StartCalculations(){ + } - public void start(Communicator c, RuntimeEstimator runtimeEstimator) throws Exception { + public void setVERSION(String version){ + VERSION = version; + } + public void start(Communicator c) throws Exception { currtime_prior_execution = System.currentTimeMillis(); - input = c.getInput(); outfolder = c.getOutfolder(); reference = c.getReference(); @@ -69,8 +71,7 @@ public void start(Communicator c, RuntimeEstimator runtimeEstimator) throws Exce ssLibProtocolUsed = c.isSsLibsProtocolUsed(); speciesListParser=null; species_name_list=null; - specieHandler = new SpecieHandler(); - this.runtimeEstimator = runtimeEstimator; + SpeciesListParser speciesListParser = new SpeciesListParser( specieslist_filepath, @@ -158,7 +159,7 @@ parse species references (-sf) and run DP for each reference in the file } else if(species_ref_identifier != null){ // start DamageProfiler - DamageProfiler damageProfiler = new DamageProfiler( + damageProfiler = new DamageProfiler( specieHandler); @@ -271,7 +272,7 @@ parse species reference (-s) and run DP // start DamageProfiler - DamageProfiler damageProfiler = new DamageProfiler(specieHandler); + damageProfiler = new DamageProfiler(specieHandler); damageProfiler.init(file, new File(reference), @@ -300,7 +301,6 @@ parse species reference (-s) and run DP calculationsDone=true; - } private void initLogger(String outfolder, String log) { @@ -325,7 +325,7 @@ private void generateOutput( if (damageProfiler.getNumberOfUsedReads() != 0) { - OutputGenerator outputGenerator = new OutputGenerator( + outputGenerator = new OutputGenerator( output_folder, damageProfiler, spe, @@ -338,7 +338,7 @@ private void generateOutput( xaxis_max_length_histogram, input, LOG, - runtimeEstimator, + damageProfiler.getNumberOfRecords(), ssLibProtocolUsed ); @@ -407,7 +407,15 @@ public boolean isCalculationsDone() { return calculationsDone; } - public DamageProfiler getDamageProfiler() { + public void setCalculationsDone(boolean calculationsDone) { + this.calculationsDone = calculationsDone; + } + + public DamageProfiler getDamageProfiler(){ return damageProfiler; } + + public OutputGenerator getOutputGenerator() { + return outputGenerator; + } } diff --git a/src/main/java/controller/DamageProfilerMainController.java b/src/main/java/controller/DamageProfilerMainController.java index 137c462..12e751e 100644 --- a/src/main/java/controller/DamageProfilerMainController.java +++ b/src/main/java/controller/DamageProfilerMainController.java @@ -1,7 +1,8 @@ package controller; import GUI.*; -import GUI.Dialogues.AbstractDialogue; +import GUI.Dialogues.RunInfoDialogue; +import GUI.Dialogues.RuntimeEstimatorDialogue; import GUI.Plots.DamagePlot; import GUI.Plots.IdentityHistPlot; import GUI.Plots.LengthDistPlot; @@ -14,6 +15,8 @@ import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.control.*; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.util.Duration; import java.lang.reflect.Field; @@ -25,6 +28,8 @@ public class DamageProfilerMainController { private final Button btn_leftpane_damageProfile; private final Button btn_leftpane_lengthDist; private final ProgressBarController progressBarController; + private final Button btn_estimate_runtime; + private RunInfoDialogue runInfoDialogue; private Communicator communicator; private Button btn_inputfile; private Button btn_reference; @@ -38,22 +43,24 @@ public class DamageProfilerMainController { private CheckBox checkbox_ssLibs_protocol; private TextField textfield_title; private TextField textfield_y_axis_height; - private StartCalculations starter = new StartCalculations(null); + private StartCalculations starter = new StartCalculations(); private DamageProfilerMainGUI mainGUI; - private boolean damagePlotGenerated = false; - private boolean idPlotsGenerated = false; - private boolean lengthPlotsGenerated = false; + private RuntimeEstimatorDialogue runtimeInfoDialogue; + private long numberOfRecords; public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, ProgressBarController progressBarController){ this.mainGUI = damageProfilerMainGUI; this.progressBarController = progressBarController; this.communicator = mainGUI.getCommunicator(); + runInfoDialogue = new RunInfoDialogue("Run configuration", communicator); + starter.setVERSION(damageProfilerMainGUI.getVersion()); this.btn_inputfile = mainGUI.getConfig_dialogue().getBtn_inputfile(); this.btn_reference = mainGUI.getConfig_dialogue().getBtn_reference(); this.btn_output = mainGUI.getConfig_dialogue().getBtn_output(); this.btn_run = mainGUI.getConfig_dialogue().getBtn_run(); + this.btn_estimate_runtime = mainGUI.getConfig_dialogue().getBtn_estimate_runtime(); this.btn_specieList = mainGUI.getConfig_dialogue().getBtn_specieList(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); @@ -70,6 +77,10 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.checkbox_ssLibs_protocol = mainGUI.getConfig_dialogue().getCheckbox_ssLibs_protocol(); //this.checkbox_dynamic_y_axis_height = mainGUI.getConfig_dialogue().get??; + runtimeInfoDialogue = new RuntimeEstimatorDialogue("Runtime information", + "This gives you an estimate of the runtime. For large files with a long runtime,\n" + + "it's recommended to use the command line version of DamageProfiler."); + addListener(); } @@ -84,9 +95,11 @@ private void addListener() { if (checkIfInputWasSelected()) { btn_run.setDisable(false); + btn_estimate_runtime.setDisable(false); } else { btn_run.setDisable(true); + btn_estimate_runtime.setDisable(true); } }); @@ -101,8 +114,10 @@ private void addListener() { if (checkIfInputWasSelected()) { btn_run.setDisable(false); + btn_estimate_runtime.setDisable(false); } else { btn_run.setDisable(true); + btn_estimate_runtime.setDisable(true); } }); @@ -118,22 +133,24 @@ private void addListener() { if (checkIfInputWasSelected()) { btn_run.setDisable(false); + btn_estimate_runtime.setDisable(false); } else { btn_run.setDisable(true); + btn_estimate_runtime.setDisable(true); } }); - - btn_run.setOnAction(e -> { + btn_estimate_runtime.setOnAction(e -> { RuntimeEstimator runtimeEstimator = new RuntimeEstimator(communicator.getInput()); long estimatedRuntimeInSeconds = runtimeEstimator.getEstimatedRuntimeInSeconds(); String text_estimatedRuntime; + if(estimatedRuntimeInSeconds > 60) { long minutes = estimatedRuntimeInSeconds / 60; long seconds = estimatedRuntimeInSeconds % 60; @@ -147,86 +164,23 @@ private void addListener() { } - AbstractDialogue runtimeInfoDialogue = new AbstractDialogue("Runtime information", "This gives you an estimate of the runtime. For large files with a long runtime,\nit's recommended to use the command line version of DamageProfiler."); - Button btn_start = new Button("Proceed"); - Button btn_cancel = new Button("Cancel"); - - int row = runtimeInfoDialogue.getRow(); - runtimeInfoDialogue.getGridPane().add(new Label("Number of reads: " + runtimeEstimator.getNumberOfRecords()), 0, ++row, 2,1); - runtimeInfoDialogue.getGridPane().add(new Label(text_estimatedRuntime), 0, ++row, 2,1); - runtimeInfoDialogue.getGridPane().add(btn_cancel, 0, ++row, 1,1); - runtimeInfoDialogue.getGridPane().add(btn_start, 1, row, 1,1); - + runtimeInfoDialogue.setNumberOfRecords(runtimeEstimator.getNumberOfRecords()); + runtimeInfoDialogue.setResultText(text_estimatedRuntime); + runtimeInfoDialogue.addComponents(); runtimeInfoDialogue.show(); + }); - btn_start.setOnAction(e_start -> { - - runtimeInfoDialogue.close(); - - // set all user options - communicator.setLength(Integer.parseInt(textfield_length.getText())); - communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); - communicator.setSsLibsProtocolUsed(checkbox_ssLibs_protocol.isSelected()); - communicator.setUse_merged_and_mapped_reads(checkbox_use_merged_reads.isSelected()); - communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); - - if(textfield_specie.getText().equals("")) - communicator.setSpecies_ref_identifier(null); - else - communicator.setSpecies_ref_identifier(textfield_specie.getText()); - - // if(!checkbox_dynamic_y_axis_height.isSelected()){ - // try { - // communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); - // } catch (Exception ex){ - // System.out.println("Height value not valid."); - // } - // } - - - if(!textfield_title.getText().equals("")){ - communicator.setTitle_plots(textfield_title.getText()); - } - - - try { - // add progress indicator - Task startCalculuations = new Task() { - @Override - protected Object call() throws Exception { - starter.start(communicator, runtimeEstimator); - - return true; - } - }; - - progressBarController.activate(startCalculuations); - startCalculuations.setOnSucceeded((EventHandler) event -> { - // replace config with result GUI - btn_leftpane_lengthDist.setDisable(false); - btn_leftpane_identityDist.setDisable(false); - btn_leftpane_damageProfile.setDisable(false); - generateDamageProfile(); - progressBarController.stop(); - - }); - - new Thread(startCalculuations).start(); - - - } catch (Exception e1) { - e1.printStackTrace(); - } - }); - - btn_cancel.setOnAction(e_cancel -> { + runtimeInfoDialogue.getBtn_proceed().setOnAction(e_start -> { + runtimeInfoDialogue.close(); + runDamageProfiler(); + }); - runtimeInfoDialogue.close(); + runtimeInfoDialogue.getBtn_cancel().setOnAction(e_cancel -> runtimeInfoDialogue.close()); - }); + btn_run.setOnAction(e -> { + runDamageProfiler(); }); - btn_specieList.setOnAction(e -> { SpeciesListFileChooser slfc = new SpeciesListFileChooser(communicator); @@ -268,7 +222,8 @@ protected Object call() throws Exception { }); btn_leftpane_run_config.setOnAction(e -> { - if(plotAlreadyGenerated()){ + if(starter.isCalculationsDone()){ + mainGUI.getRoot().setCenter(runInfoDialogue.getGridPane()); // show info (parameter / input / output / ...) // ask for new configuration } else { @@ -276,33 +231,104 @@ protected Object call() throws Exception { } }); + runInfoDialogue.getBtn_new_config().setOnAction(e -> { + mainGUI.getRoot().setCenter(mainGUI.getConfig_dialogue().getConfig_gridpane()); + clear(); + }); + + + } + + private void clear() { + btn_leftpane_lengthDist.setDisable(true); + btn_leftpane_identityDist.setDisable(true); + btn_leftpane_damageProfile.setDisable(true); + starter.setCalculationsDone(false); + btn_inputfile.setTooltip(null); + btn_output.setTooltip(null); + btn_reference.setTooltip(null); + } + + private void runDamageProfiler() { + + // set all user options + communicator.setLength(Integer.parseInt(textfield_length.getText())); + communicator.setThreshold(Integer.parseInt(textfield_threshold.getText())); + communicator.setSsLibsProtocolUsed(checkbox_ssLibs_protocol.isSelected()); + communicator.setUse_merged_and_mapped_reads(checkbox_use_merged_reads.isSelected()); + communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); + communicator.setTitle_plots(textfield_title.getText()); + + if(textfield_specie.getText().equals("")) + communicator.setSpecies_ref_identifier(null); + else + communicator.setSpecies_ref_identifier(textfield_specie.getText()); + + if(!textfield_title.getText().equals("")){ + communicator.setTitle_plots(textfield_title.getText()); + } + + + try { + // add progress indicator + Task startCalculuations = new Task() { + @Override + protected Object call() throws Exception { + starter.start(communicator); + runInfoDialogue.updateParameters(); + return true; + } + }; + + progressBarController.activate(startCalculuations); + + startCalculuations.setOnSucceeded((EventHandler) event -> { + // replace config with result GUI + btn_leftpane_lengthDist.setDisable(false); + btn_leftpane_identityDist.setDisable(false); + btn_leftpane_damageProfile.setDisable(false); + generateDamageProfile(); + progressBarController.stop(); + }); + + new Thread(startCalculuations).start(); + + } catch (Exception e1) { + e1.printStackTrace(); + } } + /** + * The following methods generate the result plots after successful damage profile calculations. + * todo: if plot already created, just reload + */ + private void generateLengthDist() { - LengthDistPlot lengthDistPlot = new LengthDistPlot(); + LengthDistPlot lengthDistPlot = new LengthDistPlot(starter.getDamageProfiler()); mainGUI.getRoot().setCenter(lengthDistPlot.getBc()); } private void generateIdentityDist() { - - IdentityHistPlot identityHistPlot = new IdentityHistPlot(); - mainGUI.getRoot().setCenter(identityHistPlot.getRoot()); + IdentityHistPlot identityHistPlot = new IdentityHistPlot(starter.getDamageProfiler().getIdentity()); + mainGUI.getRoot().setCenter(identityHistPlot.getBarChart()); } private void generateDamageProfile() { - DamagePlot damagePlot = new DamagePlot(); - mainGUI.getRoot().setCenter(damagePlot.getLineChart()); - } - - // todo - private boolean plotAlreadyGenerated() { - return false; + DamagePlot damagePlot = new DamagePlot(starter.getOutputGenerator(), starter); + HBox dp_plots = damagePlot.getDamageProfile(); + dp_plots.prefHeightProperty().bind(mainGUI.getRoot().heightProperty()); + dp_plots.prefWidthProperty().bind(mainGUI.getRoot().widthProperty()); + mainGUI.getRoot().setCenter(dp_plots); } + /** + * This method checks if all mandatory fields are set. Otherwise, it's not possible to run the tool. + * @return + */ private boolean checkIfInputWasSelected() { boolean tmp = false; if (communicator.getInput() != null && communicator.getReference() != null && communicator.getOutfolder() != null) { @@ -314,6 +340,12 @@ private boolean checkIfInputWasSelected() { } + /** + * This method overrides the default tooltip delay and sets it to 0 seconds. So the tooptip + * pops up immediately when hovering over the item. + * + * @param tooltip + */ private static void setTooltipDelay(Tooltip tooltip) { try { Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR"); From 4e6bad7e62791549e433d5e645d583093b0b1d83 Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Thu, 26 Mar 2020 16:49:46 +0100 Subject: [PATCH 08/22] Clean up and adding CRAM reader --- src/main/java/IO/OutputGenerator.java | 2 - src/main/java/StarterCLI.java | 2 - src/main/java/calculations/Aligner.java | 97 ----------------- .../java/calculations/DamageProfiler.java | 101 +++++++----------- src/main/java/calculations/Frequencies.java | 4 - src/main/java/calculations/Functions.java | 5 +- .../java/calculations/LengthDistribution.java | 4 - .../java/calculations/RuntimeEstimator.java | 18 ++-- 8 files changed, 47 insertions(+), 186 deletions(-) delete mode 100755 src/main/java/calculations/Aligner.java diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index b3b23b5..a40e63f 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -4,7 +4,6 @@ import IO.PDFoutput.LinePlot; import calculations.DamageProfiler; import calculations.Frequencies; -import calculations.RuntimeEstimator; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.itextpdf.awt.PdfGraphics2D; @@ -19,7 +18,6 @@ import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.xy.XYDataset; - import java.awt.*; import java.io.*; import java.math.BigDecimal; diff --git a/src/main/java/StarterCLI.java b/src/main/java/StarterCLI.java index 2816d40..74f0b3a 100644 --- a/src/main/java/StarterCLI.java +++ b/src/main/java/StarterCLI.java @@ -1,6 +1,5 @@ import IO.Communicator; import IO.UserOptionsParser; -import calculations.RuntimeEstimator; import calculations.StartCalculations; public class StarterCLI { @@ -10,7 +9,6 @@ public StarterCLI(String version, String[] args) throws Exception { StartCalculations starter = new StartCalculations(); starter.setVERSION(version); UserOptionsParser userOptions = new UserOptionsParser(args, c, version); - RuntimeEstimator runtimeEstimator = new RuntimeEstimator(c.getInput()); starter.start(c); } } diff --git a/src/main/java/calculations/Aligner.java b/src/main/java/calculations/Aligner.java deleted file mode 100755 index 38b0f5f..0000000 --- a/src/main/java/calculations/Aligner.java +++ /dev/null @@ -1,97 +0,0 @@ -package calculations; - -import htsjdk.samtools.CigarElement; -import htsjdk.samtools.SAMRecord; -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Created by neukamm on 06.10.2016. - */ -public class Aligner { - - private final Logger LOG; - - public Aligner(Logger LOG){ - this.LOG = LOG; - - } - - /* - # from Martin Kircher, description of CIGAR operations - # BAM Description - #M 0 alignment match (can be a sequence match or mismatch) - #I 1 insertion to the reference - #D 2 deletion from the reference - #N 3 skipped region from the reference - #S 4 soft clipping (clipped sequences present in SEQ) - #H 5 hard clipping (clipped sequences NOT present in SEQ) - #P 6 padding (silent deletion from padded reference) - #= 7 sequence match - #X 8 sequence mismatch - */ - - /** - * align reference and read according cigar string - * - * @param seq - * @param ref - * @param record - * @return - */ - public String[] align(String seq, String ref, SAMRecord record){ - - List cigar_elements = record.getCigar().getCigarElements(); - - String ref_aligned = ref; - List coord = parseCigar(cigar_elements,1); - for(int i = 0; i < coord.size(); i++){ - double[] entry = coord.get(i); - ref_aligned = new StringBuilder(ref_aligned).insert((int)entry[1], StringUtils.repeat("-", (int)entry[0])).toString(); - } - String read_aligned = seq; - coord.clear(); - coord = parseCigar(cigar_elements,2); - for(int i = 0; i < coord.size(); i++){ - double[] entry = coord.get(i); - read_aligned = new StringBuilder(read_aligned).insert((int)entry[1]-1, StringUtils.repeat("-", (int)entry[0])).toString(); - } - - return new String[]{read_aligned, ref_aligned}; - - } - - - /** - * parse CIGAR string, get length of each operation and position of operation in read - * - * @param cigar - * @param ope - * @return double[] coordinates = position in record sequence and number of occurrences - */ - private List parseCigar(List cigar, int ope){ - List coordinates = new ArrayList<>(); - int tlength = 0; - - //count matches, indels and mismatches - List oplist = Arrays.asList(0, 1, 2, 7, 8); - - for(int i = 0; i < cigar.size(); i++){ - int length = cigar.get(i).getLength(); - int op = cigar.get(i).getOperator().ordinal(); - if(op == ope){ - coordinates.add(new double[]{length, tlength}); - - } - if(oplist.contains(op)){ - tlength+= length; - } - } - - return coordinates; - } -} diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index 5196083..81372ba 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -3,13 +3,13 @@ import IO.FastACacher; import htsjdk.samtools.*; +import htsjdk.samtools.cram.ref.CRAMReferenceSource; +import htsjdk.samtools.cram.ref.ReferenceSource; import htsjdk.samtools.reference.IndexedFastaSequenceFile; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; +import java.io.*; import java.util.*; @@ -34,7 +34,6 @@ public class DamageProfiler { private ArrayList identity; private SpecieHandler specieHandler; private long actualRuntime=0; - private long runtime_ms; /** @@ -56,7 +55,7 @@ public DamageProfiler(SpecieHandler specieHandler) { * @param LOG */ public void init(File input, File reference, int threshold, int length, String specie, Logger LOG){ - // read bam/sam file + // read bam/sam/cram file if (!input.exists()){ System.err.println("SAM/BAM file not found. Please check your file path.\nInput: " + input.getAbsolutePath()); @@ -64,8 +63,22 @@ public void init(File input, File reference, int threshold, int length, String s } else { try{ - inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). - validationStringency(ValidationStringency.LENIENT).open(input); + if(input.getAbsolutePath().endsWith(".sam") || input.getAbsolutePath().endsWith(".bam") ) { + + inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). + validationStringency(ValidationStringency.LENIENT).open(input); + + } else if(input.getAbsolutePath().endsWith(".cram")){ + System.out.println(reference.getName()); + if(!reference.isFile()){ + System.err.println("Reference file is needed to reads CRAM files."); + System.exit(1); + } else { + inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). + referenceSequence(reference).validationStringency(ValidationStringency.LENIENT).open(input); + + } + } numberOfUsedReads = 0; numberOfRecords = 0; @@ -84,8 +97,8 @@ public void init(File input, File reference, int threshold, int length, String s } catch (Exception e){ System.err.println("Invalid SAM/BAM file. Please check your file."); LOG.error("Invalid SAM/BAM file. Please check your file."); - System.out.println(e.toString()); - System.exit(0); + System.err.println(e.toString()); + System.exit(-1); } } } @@ -105,7 +118,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea if(use_all_reads && use_only_merged_reads){ LOG.info("-------------------"); LOG.info("0 reads processed.\nRunning not possible. 'use_only_merged_reads' and 'use_all_reads' was set to 'true'"); - System.exit(0); + System.exit(1); } else { @@ -149,9 +162,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } } - - - frequencies.normalizeValues(); LOG.info("-------------------"); @@ -165,7 +175,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } else { System.out.println("Runtime for processing all records: " + actualRuntime + " seconds and " + runtime_ms%60 + " milliseconds"); } - } @@ -173,8 +182,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, SAMRecord record) throws Exception { - - if(use_all_reads && !use_only_merged_reads){ // process all reads processRecord(record); @@ -212,7 +219,7 @@ private void processRecord(SAMRecord record) throws Exception{ /* If MD value is set, use it to reconstruct reference - Otherwise reconstruct reference it based on the CIGAR string + Otherwise reconstruct it based on reference. */ @@ -223,56 +230,27 @@ private void processRecord(SAMRecord record) throws Exception{ // check if record has MD tag and no reference file is specified if(record.getStringAttribute(SAMTag.MD.name()) == null && this.reference == null){ - LOG.error("SAM/BAM file has no MD tag. Please specify reference file "); - System.exit(0); - - } else if (record.getStringAttribute(SAMTag.MD.name()) == null){ - - readReferenceInCache(); - Aligner aligner = new Aligner(LOG); - // SAMRecord has 1-based coordinate system -> closed interval [..,..] - // normal Array 0-based coordinate system -> interval half-cloded-half-open [...,...) - int start = record.getAlignmentStart() - 1; - int stop = record.getAlignmentEnd(); - - // get reference sequence - byte[] refSeq = Arrays.copyOfRange(cache.getData().get(cache.getKeyName(record.getReferenceName())), start, stop); - String reference = new String(refSeq, "UTF-8"); - // align record and reference + LOG.error("SAM/BAM file has no MD tag. Please specify reference file which is needed for MD tag calculations."); + System.exit(1); - if (record.getReadLength() != reference.length()) { - String[] record_reference = aligner.align(record.getReadString(), reference, record); - reference_aligned = record_reference[1]; - record_aligned = record_reference[0]; + } else { - } else { - reference_aligned = record.getReadString(); - record_aligned = record.getReadString(); + // MD tag needs to be calculated --> REF needs to be specified + if (record.getStringAttribute(SAMTag.MD.name()) == null){ + if(!reference.isFile()){ + System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag calculations."); + System.exit(1); + } + readReferenceInCache(); + SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, false); } - } else if(record.getStringAttribute(SAMTag.MD.name()) != null){ - - // get reference corresponding to the record - if(record.getCigar().getReadLength() != 0 && record.getCigar().getReadLength() == record.getReadLength()){ -// if(record.getCigarString().contains("S")){ -// System.out.println("Cigar contains soft clipping"); -// } else if(record.getCigarString().contains("D")){ -// System.out.println("Cigar contains deletion"); -// } else { - byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); - reference_aligned = new String(ref_seq, "UTF-8"); - record_aligned = record.getReadString(); - // } - - - - } else { - LOG.info("Skipped record (length does not match): " + record.getReadName()); - } + byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); + reference_aligned = new String(ref_seq, "UTF-8"); + record_aligned = record.getReadString(); } - // report length distribution this.lengthDistribution.fillDistributionTable(record,record_aligned); int hamming = useful_functions.getHammingDistance(record_aligned, reference_aligned); @@ -342,9 +320,6 @@ public String getSpeciesname(File file, String ref) { return null; } - public long getActualRuntime() { - return actualRuntime; - } public int getNumberOfRecords() { return numberOfRecords; diff --git a/src/main/java/calculations/Frequencies.java b/src/main/java/calculations/Frequencies.java index ba08833..2fad807 100755 --- a/src/main/java/calculations/Frequencies.java +++ b/src/main/java/calculations/Frequencies.java @@ -2,9 +2,6 @@ import htsjdk.samtools.SAMRecord; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; - -import java.util.LinkedList; -import java.util.List; import java.util.stream.IntStream; /** @@ -693,7 +690,6 @@ public void calculateMisincorporations(SAMRecord record, String record_aligned, * compare each position in aligned record with reference to get misincorporations * @param seq * @param ref - * @param mis_positions * @param a_c * @param a_g * @param a_t diff --git a/src/main/java/calculations/Functions.java b/src/main/java/calculations/Functions.java index 2a62748..c84d185 100755 --- a/src/main/java/calculations/Functions.java +++ b/src/main/java/calculations/Functions.java @@ -24,14 +24,14 @@ public Functions(Logger LOG){ public static int getHammingDistance(String sequence1, String sequence2){ int distance =0; if(sequence1 == null || sequence2==null) - System.exit(0); + System.exit(1); sequence1 = sequence1.toUpperCase(); sequence2 = sequence2.toUpperCase(); if(sequence1.length() != sequence2.length()) { - System.out.println("The string are not equal in length ,Please enter the strings wit equal lengths "); + System.out.println("Functions:getHammingDistance(): Different length, please enter the strings with equal length."); } for(int i=0;i < sequence1.length();i++) @@ -40,6 +40,7 @@ public static int getHammingDistance(String sequence1, String sequence2){ distance++; } + //System.out.println("Hamming Distance: " + distance); return distance; } diff --git a/src/main/java/calculations/LengthDistribution.java b/src/main/java/calculations/LengthDistribution.java index 2780967..b63eeec 100755 --- a/src/main/java/calculations/LengthDistribution.java +++ b/src/main/java/calculations/LengthDistribution.java @@ -114,10 +114,6 @@ public HashMap getLength_distribution_map_reverse() { return length_distribution_map_reverse; } - public HashMap getLength_distribution_map() { - return length_distribution_map; - } - public List getLength_forward() { return length_forward; } diff --git a/src/main/java/calculations/RuntimeEstimator.java b/src/main/java/calculations/RuntimeEstimator.java index eb826b1..36e76fd 100644 --- a/src/main/java/calculations/RuntimeEstimator.java +++ b/src/main/java/calculations/RuntimeEstimator.java @@ -1,6 +1,5 @@ package calculations; -import htsjdk.samtools.SAMRecord; import htsjdk.samtools.SamReader; import htsjdk.samtools.SamReaderFactory; import htsjdk.samtools.ValidationStringency; @@ -22,9 +21,14 @@ public RuntimeEstimator(String inputfile){ } + /** + * Estimate runtime based on the time needed in previous runs and the number of reads in the + * current input file. + * + */ public void estimate() { // estimate runtime: - numberOfRecords = getNumberOfRecordsIntern(); + numberOfRecords = input.iterator().toList().size(); System.out.println("Number of records to process: " + numberOfRecords); estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); @@ -39,16 +43,6 @@ public void estimate() { } - private long getNumberOfRecordsIntern() { - long count = 0; - for(SAMRecord record : input){ - count++; - } - - return count; - } - - public long getEstimatedRuntimeInSeconds() { return estimatedRuntimeInSeconds; } From 767711d0f6743360ce5e6dfaa942cfb4b002dd82 Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Fri, 27 Mar 2020 09:28:10 +0100 Subject: [PATCH 09/22] export figures as SVG --- build.gradle | 1 + src/main/java/IO/OutputGenerator.java | 52 +++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 46d5de4..75c86c7 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,7 @@ dependencies { compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' compile 'org.jfxtras:jmetro:8.6.5' + compile group: 'org.jfree', name: 'jfreesvg', version: '2.0' } diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index a40e63f..81361a4 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -1,5 +1,7 @@ package IO; +import GUI.Plots.IdentityHistPlot; +import GUI.Plots.LengthDistPlot; import IO.PDFoutput.Histogram; import IO.PDFoutput.LinePlot; import calculations.DamageProfiler; @@ -12,13 +14,17 @@ import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.PdfWriter; +import javafx.scene.chart.BarChart; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.log4j.Logger; import org.jfree.chart.JFreeChart; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.xy.XYDataset; +import org.jfree.graphics2d.svg.SVGGraphics2D; +import org.jfree.graphics2d.svg.SVGUtils; import java.awt.*; +import java.awt.Rectangle; import java.io.*; import java.math.BigDecimal; import java.text.DecimalFormat; @@ -459,6 +465,8 @@ public void plotLengthHistogram(List length_all, List length_for "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo); createPdf("/Length_plot.pdf", new JFreeChart[]{chart_all, chart_separated}, file); + createSVG("/Length_plot_combined_data.svg", chart_all); + createSVG("/Length_plot_forward_reverse_separated.svg", chart_separated); } @@ -479,9 +487,11 @@ public void plotIdentitiyHistogram(ArrayList distances, String title, String fil JFreeChart chart_all = hist_all.createChart(dataset, "Read identity distribution", "Identity", "Occurrences", x_axis_min_id_histo, x_axis_max_id_histo); createPdf("/identity_histogram.pdf", new JFreeChart[]{chart_all}, file); + createSVG("/identity_histogram.svg", chart_all); } + /** * write percentage of misincorporations per read position * @@ -843,17 +853,22 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep ymax = damagePlot_five.getY_max(); } - + JFreeChart[] charts; // create damage plot five prime JFreeChart chart = damagePlot_five.createChart(dataset_five, ymax, threshold); if(!ssLibProtocolUsed){ XYDataset dataset_three = damagePlot_three.createDataset(); // create damage plot three prime JFreeChart chart1 = damagePlot_three.createChart(dataset_three, ymax, threshold); - createPdf("/DamagePlot.pdf", new JFreeChart[]{chart, chart1}, file); + charts = new JFreeChart[]{chart, chart1}; + createSVG("/DamagePlot_three_prime.svg", chart1); } else { - createPdf("/DamagePlot.pdf", new JFreeChart[]{chart}, file); + charts = new JFreeChart[]{chart}; } + + createPdf("/DamagePlot.pdf", charts, file); + createSVG("/DamagePlot_five_prime.svg", chart); + } @@ -913,6 +928,18 @@ private double[] getSubArray(double[] array, int n){ } + public void createSVG(String filename, JFreeChart chart) throws IOException { + + int height = (int)(PageSize.A4.getWidth() * (float)0.8); + int width = (int)(PageSize.A4.getHeight() / 2); + + SVGGraphics2D g2 = new SVGGraphics2D(width, height); + Rectangle r = new Rectangle(0, 0, width, height); + chart.draw(g2, r); + File f = new File(outpath + "/" + filename); + SVGUtils.writeToSVG(f, g2.getSVGElement()); + + } /** * Creates a PDF document. * @@ -941,11 +968,22 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws String read_per; if(!ssLibProtocolUsed){ - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie; + if(this.specie == null){ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads)"; + } else{ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie; + } + } else { - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie + " | ssLib protocol"; + if(this.specie == null){ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | ssLib protocol"; + } else { + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Specie: " + this.specie + " | ssLib protocol"; + } } From ec3102789bc66eb3ace101e3d8633842ffd0c2ab Mon Sep 17 00:00:00 2001 From: JudithNeukamm Date: Fri, 27 Mar 2020 14:08:12 +0100 Subject: [PATCH 10/22] add help page to GUI, improve options parser --- build.gradle | 2 + src/main/java/GUI/DamageProfilerMainGUI.java | 13 +- .../AdvancedCalculationOptionsDialogue.java | 4 + .../AdvancedPlottingOptionsDialogue.java | 29 +++ .../GUI/Dialogues/ConfigurationDialogue.java | 28 ++- src/main/java/GUI/Dialogues/HelpDialogue.java | 105 ++++++++++ src/main/java/GUI/Plots/LengthDistPlot.java | 4 +- src/main/java/IO/OutputGenerator.java | 19 +- src/main/java/IO/PDFoutput/Histogram.java | 16 +- src/main/java/IO/UserOptionsParser.java | 181 ++++++++++-------- src/main/java/RunDamageProfiler.java | 2 +- .../java/calculations/DamageProfiler.java | 25 ++- src/main/java/calculations/Functions.java | 49 +++-- .../java/calculations/LengthDistribution.java | 20 +- .../java/calculations/StartCalculations.java | 2 +- .../DamageProfilerMainController.java | 18 +- 16 files changed, 368 insertions(+), 149 deletions(-) create mode 100644 src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java create mode 100644 src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java create mode 100644 src/main/java/GUI/Dialogues/HelpDialogue.java diff --git a/build.gradle b/build.gradle index 75c86c7..aad3973 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,8 @@ dependencies { compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' compile 'org.jfxtras:jmetro:8.6.5' compile group: 'org.jfree', name: 'jfreesvg', version: '2.0' + compile group: 'org.apache.commons', name: 'commons-text', version: '1.+' + } diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java index 419fb01..2c62954 100644 --- a/src/main/java/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/GUI/DamageProfilerMainGUI.java @@ -23,6 +23,7 @@ public class DamageProfilerMainGUI { private Button btn_leftpane_info; private Button btn_leftpane_damageProfile; private Button btn_leftpane_lengthDist; + private Button btn_help; public DamageProfilerMainGUI(String version, ProgressBarController progressBarController) { @@ -46,7 +47,7 @@ public void init(Stage primaryStage){ //jMetro.setScene(new Scene(root, 750, 500)); //this.primaryStage.setScene(jMetro.getScene()); - this.primaryStage.setScene(new Scene(root, 900, 600)); + this.primaryStage.setScene(new Scene(root, 950, 700)); this.primaryStage.setResizable(true); this.primaryStage.show(); @@ -56,6 +57,7 @@ private VBox generateLeftPane() { VBox leftPanel = new VBox(); btn_leftpane_damageProfile = new Button("Damage Plot"); btn_leftpane_info = new Button("Run Configuration"); + btn_help = new Button("Show help"); btn_leftpane_lengthDist = new Button("Length Distribution"); btn_leftpane_identityDist = new Button("Identity Distribution"); @@ -63,6 +65,9 @@ private VBox generateLeftPane() { btn_leftpane_info.setPrefHeight(30); btn_leftpane_info.setPrefWidth(200); + btn_help.setPrefHeight(30); + btn_help.setPrefWidth(200); + btn_leftpane_damageProfile.setPrefHeight(30); btn_leftpane_damageProfile.setPrefWidth(200); btn_leftpane_damageProfile.setDisable(true); @@ -75,7 +80,7 @@ private VBox generateLeftPane() { btn_leftpane_identityDist.setPrefWidth(200); btn_leftpane_identityDist.setDisable(true); - leftPanel.getChildren().addAll(btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist); + leftPanel.getChildren().addAll(btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist, btn_help); leftPanel.setPadding(new Insets(10,10,10,10)); return leftPanel; @@ -107,6 +112,10 @@ public Button getBtn_leftpane_lengthDist() { return btn_leftpane_lengthDist; } + public Button getBtn_help() { + return btn_help; + } + public ConfigurationDialogue getConfig_dialogue() { return config_dialogue; } diff --git a/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java b/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java new file mode 100644 index 0000000..6540b46 --- /dev/null +++ b/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java @@ -0,0 +1,4 @@ +package GUI.Dialogues; + +public class AdvancedCalculationOptionsDialogue { +} diff --git a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java b/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java new file mode 100644 index 0000000..85a6a4b --- /dev/null +++ b/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java @@ -0,0 +1,29 @@ +package GUI.Dialogues; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.layout.GridPane; + +public class AdvancedPlottingOptionsDialogue { + private GridPane plotting_config_gridpane; + + public AdvancedPlottingOptionsDialogue(){ + plotting_config_gridpane = new GridPane(); + plotting_config_gridpane.setAlignment(Pos.CENTER); + plotting_config_gridpane.setHgap(10); + plotting_config_gridpane.setVgap(10); + plotting_config_gridpane.setPadding(new Insets(15,15,15,15)); + + fill(); + } + + private void fill() { + + } + + + public Node getGridPane() { + return plotting_config_gridpane; + } +} diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java index 0cc7b67..9b07cfd 100644 --- a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java @@ -4,6 +4,8 @@ import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; @@ -87,6 +89,21 @@ private void addComponents() { textfield_threshold.setText("25"); textfield_y_axis_height.setText("0.4"); + TitledPane pane_advanced_plotting_options = new TitledPane(); + pane_advanced_plotting_options.setText("Advanced options (Plotting)"); + AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue = new AdvancedPlottingOptionsDialogue(); + pane_advanced_plotting_options.setContent(advancedPlottingOptionsDialogue.getGridPane()); + pane_advanced_plotting_options.setExpanded(false); + + TitledPane pane_advanced_calculation_options = new TitledPane(); + pane_advanced_calculation_options.setText("Advanced options (Calculation)"); + HBox hbox_length_calc = new HBox(); + hbox_length_calc.setPadding(new Insets(10,10,10,10)); + hbox_length_calc.getChildren().addAll(label_length, textfield_length); + pane_advanced_calculation_options.setContent(hbox_length_calc); + pane_advanced_calculation_options.setExpanded(false); + + // add components to grid int row = 0; @@ -111,17 +128,18 @@ private void addComponents() { config_gridpane.add(textfield_y_axis_height, 1, row, 2,1); config_gridpane.add(label_threshold, 0, ++row, 1,1); config_gridpane.add(textfield_threshold, 1, row, 2,1); - config_gridpane.add(label_specie, 0, ++row, 1,1); - config_gridpane.add(textfield_specie, 1, row, 2,1); - config_gridpane.add(btn_specieList, 3, row, 1,1); + config_gridpane.add(pane_advanced_plotting_options, 0,++row, 3,1); config_gridpane.add(new Separator(), 0, ++row,3,1); // CALCULATIONS config_gridpane.add(label_calculations, 0, ++row, 1,1); config_gridpane.add(checkbox_use_merged_reads, 0, ++row,1,1); config_gridpane.add(checkbox_ssLibs_protocol, 0, ++row, 1,1); - config_gridpane.add(label_length, 0, ++row, 1,1); - config_gridpane.add(textfield_length, 1, row, 2,1); + config_gridpane.add(label_specie, 0, ++row, 1,1); + config_gridpane.add(textfield_specie, 1, row, 2,1); + config_gridpane.add(btn_specieList, 3, row, 1,1); + config_gridpane.add(pane_advanced_calculation_options, 0,++row, 3,1); + config_gridpane.add(new Separator(), 0, ++row,3,1); config_gridpane.add(btn_estimate_runtime, 0, ++row,1,1); config_gridpane.add(btn_run, 1, row,1,1); diff --git a/src/main/java/GUI/Dialogues/HelpDialogue.java b/src/main/java/GUI/Dialogues/HelpDialogue.java new file mode 100644 index 0000000..1212876 --- /dev/null +++ b/src/main/java/GUI/Dialogues/HelpDialogue.java @@ -0,0 +1,105 @@ +package GUI.Dialogues; + + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; + +import java.awt.*; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +public class HelpDialogue { + + private final GridPane gridPane; + private Hyperlink link; + + public HelpDialogue(){ + + gridPane = new GridPane(); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(10); + gridPane.setVgap(10); + gridPane.setPadding(new Insets(15,15,15,15)); + + fill(); + } + + /** + * Fill dialogue with help content + */ + private void fill() { + Label label_title = new Label("Welcome to damageProfiler help page"); + label_title.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); + + Label label_usage = new Label("Usage:\n"); + label_usage.setFont(Font.font("Verdana", FontWeight.BOLD, 12)); + + Label label_help = new Label(); + label_help.setText("DamageProfiler [-h] [-version] [-i ] [-r ] [-o ] [-t ]\n[-s ] [-sf ] " + + "[-l ] [-title ] [-yaxis_dp_max <MAX_VALUE>]\n[-xaxis_id_min <MIN_VALUE>] [-xaxis_id_max <MAX_VALUE>] [-xaxis_length_min <MIN_VALUE>]\n" + + "[-xaxis_length_max <MAX_VALUE>] [-only_merged] [-ssLib]" + + "\n\n" ); + + Label label_details = new Label("Detailed description:\n"); + label_details.setFont(Font.font("Verdana", FontWeight.BOLD, 12)); + + link = new Hyperlink(); + link.setText("Documentation"); + link.setOnAction(event -> new Thread(() -> { + try { + Desktop.getDesktop().browse(new URI("http://damageprofiler.readthedocs.io/en/latest/")); + } catch (IOException | URISyntaxException e1) { + e1.printStackTrace(); + } + }).start()); + + Label label_helppage = new Label(" -h\t\t\t\t\t\t\tShows this help page.\n" + + " -version\t\t\t\t\t\tShows the version of DamageProfiler.\n" + + " -i <INPUT>\t\t\t\t\tREQUIRED: The input sam/bam/cram file.\n" + + " -r <REFERENCE>\t\t\t\tThe reference file (fasta format).\n" + + " -o <OUTPUT>\t\t\t\t\tREQUIRED: The output folder.\n" + + " -t <THRESHOLD>\t\t\t\tDamagePlot: Number of bases which are considered for plotting\n\t\t\t\t\t\t\tnucleotide misincorporations. Default: 25\n" + + " -s <SPECIES>\t\t\t\t\tReference sequence name (RNAME flag of SAM record).\n\t\t\t\t\t\t\tFor more details see Documentation.\n" + + " -sf <SPECIES LIST>\t\t\t\tList with species for which damage profile has to be calculated.\n\t\t\t\t\t\t\tFor more details see Documentation.\n" + + " -l <LENGTH>\t\t\t\t\tNumber of bases which are considered for frequency\n\t\t\t\t\t\t\tcomputations. Default: 100.\n" + + " -title <TITLE>\t\t\t\t\tTitle used for all plots. Default: input filename.\n" + + " -yaxis_dp_max <MAX_VALUE>\tDamagePlot: Maximal y-axis value.\n" + + " -xaxis_id_min <MIN_VALUE>\t\tIdentity Distribution: Minimal value x-axis.\n" + + " -xaxis_id_max <MAX_VALUE>\tIdentity Distribution: Maximal value x-axis.\n" + + " -xaxis_length_min <MIN_VALUE>\tLength Distribution: Minimal value x-axis.\n" + + " -xaxis_length_max <MAX_VALUE>\tLength Distribution: Maximal value x-axis.\n" + + " -only_merged\t\t\t\t\tUse only mapped and merged reads to calculate damage plot\n\t\t\t\t\t\t\tinstead of using all mapped reads.\n\t\t\t\t\t\t\tThe SAM/BAM entry must start with 'M_', otherwise it will\n\t\t\t\t\t\t\tbe skipped. Default: false\n" + + " -ssLib\t\t\t\t\t\tSingle-stranded library protocol was used. Default: false"); + + int row=0; + + gridPane.add(label_title,0,row,2,1); + gridPane.add(new Label("If you need more information, please check the documentation or contact the developers."),0, ++row,2,1); + gridPane.add(link,0, ++row,2,1); + gridPane.add(new Separator(),0, ++row,2,1); + + gridPane.add(label_usage,0, ++row,2,1); + gridPane.add(label_help,0, ++row,2,1); + gridPane.add(label_details,0, ++row,2,1); + gridPane.add(label_helppage, 0,++row, 2,1); + + + + + } + + + + // Getter + + public GridPane getGridPane() { + return this.gridPane; + } +} diff --git a/src/main/java/GUI/Plots/LengthDistPlot.java b/src/main/java/GUI/Plots/LengthDistPlot.java index 05b1ae2..1105d3c 100644 --- a/src/main/java/GUI/Plots/LengthDistPlot.java +++ b/src/main/java/GUI/Plots/LengthDistPlot.java @@ -78,7 +78,7 @@ private void generate_split_data(HashMap<Integer, Integer> length_distribution_m } - private void generate_alldata(List<Double> length_all) { + private void generate_alldata(List<Integer> length_all) { Double[] data_all = prepareData(length_all); HashMap<Double, Integer> length_map_all = groupData(data_all); @@ -130,7 +130,7 @@ private HashMap<Double, Integer> groupData(Double[] data_all) { return idents_count; } - private Double[] prepareData(List<Double> length_data_all) { + private Double[] prepareData(List<Integer> length_data_all) { Double[] data_all = new Double[length_data_all.size()]; diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index 81361a4..6728fb7 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -1,7 +1,5 @@ package IO; -import GUI.Plots.IdentityHistPlot; -import GUI.Plots.LengthDistPlot; import IO.PDFoutput.Histogram; import IO.PDFoutput.LinePlot; import calculations.DamageProfiler; @@ -444,14 +442,14 @@ public void writeFrequenciesReference(Frequencies frequencies) throws IOExceptio * @throws IOException * @throws DocumentException */ - public void plotLengthHistogram(List<Double> length_all, List<Double> length_forward, List<Double> length_reverse, + public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_forward, List<Integer> length_reverse, String file) throws IOException, DocumentException { Histogram hist_all = new Histogram(LOG); hist_all.addData(length_all); HistogramDataset dataset_all = hist_all.createDataset(new String[]{"all reads"}, max_length); - JFreeChart chart_all = hist_all.createChart(dataset_all, "Read length distribution", "Read length", - "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo); + JFreeChart chart_all = hist_all.createChart(dataset_all, "", "Read length", + "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo, false); Histogram hist_separated = new Histogram(LOG); if(length_forward.size()>0){ @@ -461,8 +459,8 @@ public void plotLengthHistogram(List<Double> length_all, List<Double> length_for hist_separated.addData(length_reverse); } HistogramDataset dataset_separated = hist_separated.createDataset(new String[]{"+ strand", "- strand"}, max_length); - JFreeChart chart_separated = hist_separated.createChart(dataset_separated, "Read length distribution", - "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo); + JFreeChart chart_separated = hist_separated.createChart(dataset_separated, "", + "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo, true); createPdf("/Length_plot.pdf", new JFreeChart[]{chart_all, chart_separated}, file); createSVG("/Length_plot_combined_data.svg", chart_all); @@ -480,12 +478,13 @@ public void plotLengthHistogram(List<Double> length_all, List<Double> length_for * @throws DocumentException * @throws IOException */ - public void plotIdentitiyHistogram(ArrayList distances, String title, String file) throws DocumentException, IOException{ + public void plotIdentitiyHistogram(List<Integer> distances, String title, String file) throws DocumentException, IOException{ Histogram hist_all = new Histogram(LOG); hist_all.addData(distances); + HistogramDataset dataset = hist_all.createDataset(new String[]{title}, 100); - JFreeChart chart_all = hist_all.createChart(dataset, "Read identity distribution", "Identity", "Occurrences", - x_axis_min_id_histo, x_axis_max_id_histo); + JFreeChart chart_all = hist_all.createChart(dataset, "", "Edit distance", "Occurrences", + x_axis_min_id_histo, x_axis_max_id_histo, false); createPdf("/identity_histogram.pdf", new JFreeChart[]{chart_all}, file); createSVG("/identity_histogram.svg", chart_all); diff --git a/src/main/java/IO/PDFoutput/Histogram.java b/src/main/java/IO/PDFoutput/Histogram.java index 5a12dc8..8a33e31 100755 --- a/src/main/java/IO/PDFoutput/Histogram.java +++ b/src/main/java/IO/PDFoutput/Histogram.java @@ -4,10 +4,13 @@ import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.xy.StandardXYBarPainter; import org.jfree.chart.renderer.xy.XYBarRenderer; +import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.statistics.HistogramType; @@ -31,7 +34,7 @@ public Histogram(Logger LOG){ data_collected = new ArrayList<>(); } - public void addData(List<Double> data){ + public void addData(List<Integer> data){ double[] d = new double[data.size()]; for(int i = 0; i < data.size(); i++){ d[i] = data.get(i); @@ -58,7 +61,7 @@ public HistogramDataset createDataset(String[] title, int max){ public JFreeChart createChart(HistogramDataset dataset, String title, String xlab, String ylab, - double xmin, double xmax){ + double xmin, double xmax, boolean legend){ JFreeChart chart = ChartFactory.createHistogram( title,//"Histogram read length", @@ -66,18 +69,19 @@ public JFreeChart createChart(HistogramDataset dataset, String title, String xla ylab, // "Occurrences", dataset, PlotOrientation.VERTICAL, - true, + legend, false, false ); - chart.setBackgroundPaint(new Color(230,230,230)); +// chart.setBackgroundPaint(new Color(230,230,230)); XYPlot xyplot = (XYPlot)chart.getPlot(); xyplot.setForegroundAlpha(0.7F); xyplot.setBackgroundPaint(Color.WHITE); xyplot.setDomainGridlinePaint(new Color(150,150,150)); xyplot.setRangeGridlinePaint(new Color(150,150,150)); + if(xmin > -1){ ValueAxis axis = xyplot.getDomainAxis(); axis.setLowerBound(xmin); @@ -90,8 +94,8 @@ public JFreeChart createChart(HistogramDataset dataset, String title, String xla XYBarRenderer xybarrenderer = (XYBarRenderer)xyplot.getRenderer(); xybarrenderer.setShadowVisible(false); - xybarrenderer.setBarPainter(new StandardXYBarPainter()); - xybarrenderer.setMargin(0.2); +// xybarrenderer.setBarPainter(new StandardXYBarPainter()); +// xybarrenderer.setMargin(0.2); return chart; diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index 9af04a8..c119f7d 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -26,122 +26,135 @@ private void parse() { // create command line parameters Options helpOptions = new Options(); helpOptions.addOption("h", "help", false, "show this help page"); + Options options = new Options(); - options.addOption("h", "help", false, "show this help page"); - Option version = new Option("version", "version", false, - "Show version of DamageProfiler"); - options.addOption(version); + options.addOption("h", false, "Shows this help page."); + + options.addOption(new Option("version", false, + "Shows the version of DamageProfiler.")); - options.addOption(OptionBuilder.withLongOpt("input") - .withArgName("INPUT") - .withDescription("The input sam/bam file") + options.addOption(Option.builder("i") + .argName("INPUT") + .desc("The input sam/bam/cram file.") .hasArg() - .create("i")); - options.addOption(OptionBuilder.withLongOpt("reference") - .withArgName("REFERENCE") - .withDescription("The reference file") + .build()); + + options.addOption(Option.builder("r") + .argName("REFERENCE") + .desc("The reference file (fasta format).") .hasArg() - .create("r")); - options.addOption(OptionBuilder.withLongOpt("output") - .withArgName("OUTPUT") - .withDescription("The output folder") + .build()); + + options.addOption(Option.builder("o") + .argName("OUTPUT") + .desc("The output folder.") .hasArg() - .create("o")); - options.addOption(OptionBuilder.withLongOpt("threshold") - .withArgName("THRESHOLD") - .withDescription("Number of bases which are considered for plotting nucleotide misincorporations") + .build()); + + options.addOption(Option.builder("t") + .argName("THRESHOLD") + .desc("DamagePlot: Number of bases which are considered for plotting nucleotide misincorporations. Default: 25") .hasArg() - .create("t")); - options.addOption(OptionBuilder.withLongOpt("specie") - .withArgName("SPECIE") - .withDescription("RNAME flag SAM record (Reference sequence name)") + .build()); + + options.addOption(Option.builder("s") + .argName("SPECIES") + .desc("Reference sequence name (RNAME flag of SAM record). For more details see Documentation.") .hasArg() - .create("s")); - options.addOption(OptionBuilder.withLongOpt("specieslist file") - .withArgName("SPECIES LIST") - .withDescription("List with species for which damage profile has to be calculated.") + .build()); + + options.addOption(Option.builder("sf") + .argName("SPECIES LIST") + .desc("List with species for which damage profile has to be calculated. For more details see Documentation.") .hasArg() - .create("sf")); - options.addOption(OptionBuilder.withLongOpt("length") - .withArgName("LENGTH") - .withDescription("Number of bases which are considered for frequency computations.") + .build()); + + options.addOption(Option.builder("l") + .argName("LENGTH") + .desc("Number of bases which are considered for frequency computations. Default: 100.") .hasArg() - .create("l")); + .build()); + + + /* + plotting options + */ - options.addOption(OptionBuilder.withLongOpt("title") - .withArgName("TITLE") - .withDescription("Title used for all plots. Default: filepath of input SAM/BAM file.") + options.addOption(Option.builder("title") + .argName("TITLE") + .desc("Title used for all plots. Default: input filename.") .hasArg() - .create("title")); + .build()); - options.addOption(OptionBuilder.withLongOpt("yaxis_damageplot") - .withArgName("YAXIS_DAMAGEPLOT") - .withDescription("Maximal value on y axis of damage plot.") + // damage plot + + options.addOption(Option.builder("yaxis_dp_max") + .argName("MAX_VALUE") + .desc("DamagePlot: Maximal y-axis value.") .hasArg() - .create("yaxis_damageplot")); + .build()); + + // Identity plot - options.addOption(OptionBuilder.withLongOpt("xaxis_histo_id_min") - .withArgName("XAXIS_HISTO_ID_MIN") - .withDescription("Minimal value x-axis of identity histogram.") + options.addOption(Option.builder("xaxis_id_min") + .argName("MIN_VALUE") + .desc("Identity Distribution: Minimal value x-axis.") .hasArg() - .create("xaxis_histo_id_min")); + .build()); - options.addOption(OptionBuilder.withLongOpt("xaxis_histo_id_max") - .withArgName("XAXIS_HISTO_ID_MAX") - .withDescription("Maximal value x-axis of identity histogram.") + options.addOption(Option.builder("xaxis_id_max") + .argName("MAX_VALUE") + .desc("Identity Distribution: Maximal value x-axis.") .hasArg() - .create("xaxis_histo_id_max")); + .build()); + + // Length plot - options.addOption(OptionBuilder.withLongOpt("xaxis_histo_length_min") - .withArgName("XAXIS_HISTO_LENGTH_MIN") - .withDescription("Minimal value x-axis of length histogram.") + options.addOption(Option.builder("xaxis_length_min") + .argName("MIN_VALUE") + .desc("Length Distribution: Minimal value x-axis.") .hasArg() - .create("xaxis_histo_length_min")); + .build()); - options.addOption(OptionBuilder.withLongOpt("xaxis_histo_length_max") - .withArgName("XAXIS_HISTO_LENGTH_MAX") - .withDescription("Maximal value x-axis of length histogram.") + options.addOption(Option.builder("xaxis_length_max") + .argName("MAX_VALUE") + .desc("Length Distribution: Maximal value x-axis.") .hasArg() - .create("xaxis_histo_length_max")); + .build()); - Option mapped_and_merged = new Option("merged", "all_mapped_and_merged_reads", false, - "Use all mapped and merged reads to calculate damage plot instead of using all mapped reads. The SAM/BAM entry must start with 'M_', otherwise " + - " it will be skipped. Default: false "); - options.addOption(mapped_and_merged); - Option use_all_reads = new Option("useall", "use_all_reads", false, - "Use all reads (mapped and unmapped) to calculate damage plot. Default: false "); - options.addOption(use_all_reads); + // others - Option ssLib_used = new Option("sslib", "sslib", false, - "Single-stranded library protocol was used. Default: false "); - options.addOption(ssLib_used); + options.addOption(Option.builder("only_merged") + .desc("Use only mapped and merged reads to calculate damage plot instead of using all mapped reads. The SAM/BAM entry must start with 'M_', otherwise " + + " it will be skipped. Default: false ") + .build()); + options.addOption(Option.builder("ssLib") + .desc("Single-stranded library protocol was used. Default: false") + .build()); - HelpFormatter helpformatter = new HelpFormatter(); + String header = "\nDetailed description:\n\n"; + + HelpFormatter formatter = new HelpFormatter(); + formatter.setOptionComparator(null); + formatter.setWidth(130); CommandLineParser parser = new BasicParser(); - if (args[0].equals("-version") || args[0].equals("--version")){ - System.out.println("DamageProfiler v" + this.version); - System.exit(0); - } else if (args.length < 2) { - helpformatter.printHelp(CLASS_NAME, options); - System.exit(0); - } - try { - CommandLine cmd = parser.parse(helpOptions, args); - if (cmd.hasOption('h')) { - helpformatter.printHelp(CLASS_NAME, options); - System.exit(0); - } - } catch (ParseException e1) { - } + +// --------------------------------------------------------------------------------------- try { + CommandLine cmd = parser.parse(options, args); + if (cmd.hasOption('h')) { + formatter.printHelp("DamageProfiler", header, options, null, true); + System.exit(0); + } + if(cmd.hasOption("version")) { System.out.print("DamageProfiler v" + this.version + "\n"); System.exit(0); @@ -217,9 +230,9 @@ private void parse() { } catch (ParseException e) { - helpformatter.printHelp(CLASS_NAME, options); + formatter.printHelp(CLASS_NAME, options); System.err.println(e.getMessage()); - System.exit(0); + System.exit(1); } } diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index a57a0dc..988d685 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -22,12 +22,12 @@ public static void main(String[] args) throws Exception { */ - System.setProperty("java.awt.headless", "true"); if(args.length==0){ new Thread(() -> Application.launch(StarterGUI.class)).start(); } else { + System.setProperty("java.awt.headless", "true"); StarterCLI starterCLI = new StarterCLI(VERSION, args); } diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index 81372ba..d7f81af 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -3,8 +3,6 @@ import IO.FastACacher; import htsjdk.samtools.*; -import htsjdk.samtools.cram.ref.CRAMReferenceSource; -import htsjdk.samtools.cram.ref.ReferenceSource; import htsjdk.samtools.reference.IndexedFastaSequenceFile; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; @@ -35,6 +33,7 @@ public class DamageProfiler { private SpecieHandler specieHandler; private long actualRuntime=0; private long runtime_ms; + private List<Integer> editDistances; /** * constructor @@ -90,6 +89,7 @@ public void init(File input, File reference, int threshold, int length, String s this.lengthDistribution = new LengthDistribution(this.LOG); this.lengthDistribution.init(); this.identity = new ArrayList(); + this.editDistances = new ArrayList(); this.specie = specie; useful_functions = new Functions(this.LOG); @@ -242,7 +242,7 @@ private void processRecord(SAMRecord record) throws Exception{ System.exit(1); } readReferenceInCache(); - SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, false); + SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, true); } byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); @@ -253,12 +253,21 @@ private void processRecord(SAMRecord record) throws Exception{ // report length distribution this.lengthDistribution.fillDistributionTable(record,record_aligned); + + // calculate distance between record and reference int hamming = useful_functions.getHammingDistance(record_aligned, reference_aligned); + + // todo: so far unused, could be added as user-choice + int levenshtein = useful_functions.getLevenshteinDistance(record_aligned, reference_aligned); + double id = (double)(record_aligned.length()-hamming) / (double)record_aligned.length(); this.identity.add(id); + this.editDistances.add(hamming); // calculate frequencies frequencies.count(record, record_aligned, reference_aligned); + + // calculate base misincorporations frequencies.calculateMisincorporations(record, record_aligned, reference_aligned); } @@ -291,13 +300,13 @@ public Frequencies getFrequencies() { } public HashMap<Integer, Integer> getLength_distribution_map_forward() {return lengthDistribution.getLength_distribution_map_forward(); } public HashMap<Integer, Integer> getLength_distribution_map_reverse() {return lengthDistribution.getLength_distribution_map_reverse(); } - public List<Double> getLength_forward() { + public List<Integer> getLength_forward() { return lengthDistribution.getLength_forward(); } - public List<Double> getLength_all() { + public List<Integer> getLength_all() { return lengthDistribution.getLength_all(); } - public List<Double> getLength_reverse() { return lengthDistribution.getLength_reverse(); } + public List<Integer> getLength_reverse() { return lengthDistribution.getLength_reverse(); } public int getNumberOfUsedReads() { return numberOfUsedReads; } @@ -324,4 +333,8 @@ public String getSpeciesname(File file, String ref) { public int getNumberOfRecords() { return numberOfRecords; } + + public List<Integer> getEditDistances() { + return editDistances; + } } diff --git a/src/main/java/calculations/Functions.java b/src/main/java/calculations/Functions.java index c84d185..d884a89 100755 --- a/src/main/java/calculations/Functions.java +++ b/src/main/java/calculations/Functions.java @@ -1,5 +1,7 @@ package calculations; +import org.apache.commons.text.similarity.HammingDistance; +import org.apache.commons.text.similarity.LevenshteinDistance; import org.apache.log4j.Logger; /** @@ -21,27 +23,34 @@ public Functions(Logger LOG){ * @param sequence2 - the second sequence * @return the hamming distance */ - public static int getHammingDistance(String sequence1, String sequence2){ - int distance =0; - if(sequence1 == null || sequence2==null) - System.exit(1); + public int getHammingDistance(String sequence1, String sequence2){ + HammingDistance hammingDistance = new HammingDistance(); + return hammingDistance.apply(sequence1, sequence2); +// int distance =0; +// if(sequence1 == null || sequence2==null) +// System.exit(1); +// +// sequence1 = sequence1.toUpperCase(); +// sequence2 = sequence2.toUpperCase(); +// +// if(sequence1.length() != sequence2.length()) +// { +// System.out.println("Functions:getHammingDistance(): Different length, please enter the strings with equal length."); +// } +// +// for(int i=0;i < sequence1.length();i++) +// { +// if(sequence1.charAt(i)!=sequence2.charAt(i)) +// distance++; +// } +// +// //System.out.println("Hamming Distance: " + distance); +// return distance; - sequence1 = sequence1.toUpperCase(); - sequence2 = sequence2.toUpperCase(); - - if(sequence1.length() != sequence2.length()) - { - System.out.println("Functions:getHammingDistance(): Different length, please enter the strings with equal length."); - } - - for(int i=0;i < sequence1.length();i++) - { - if(sequence1.charAt(i)!=sequence2.charAt(i)) - distance++; - } - - //System.out.println("Hamming Distance: " + distance); - return distance; + } + public int getLevenshteinDistance(String sequence1, String sequence2){ + LevenshteinDistance levenshteinDistance = new LevenshteinDistance(); + return levenshteinDistance.apply(sequence1, sequence2); } } diff --git a/src/main/java/calculations/LengthDistribution.java b/src/main/java/calculations/LengthDistribution.java index b63eeec..d11450c 100755 --- a/src/main/java/calculations/LengthDistribution.java +++ b/src/main/java/calculations/LengthDistribution.java @@ -16,9 +16,9 @@ public class LengthDistribution { private HashMap<Integer, Integer> length_distribution_map_forward; private HashMap<Integer, Integer> length_distribution_map_reverse; private HashMap<Double, Double> length_distribution_map; - private List<Double> length_forward; - private List<Double> length_reverse; - private List<Double> length_all; + private List<Integer> length_forward; + private List<Integer> length_reverse; + private List<Integer> length_all; public LengthDistribution(Logger LOG){ @@ -48,7 +48,7 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ // int record_length = record.getReadLength(); int record_length = record_aligned.length(); - length_all.add((double)record_length); + length_all.add(record_length); // check if record is on forward or reverse strand if(record.getReadNegativeStrandFlag()){ @@ -58,7 +58,7 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ int count = length_distribution_map_reverse.get(record_length); length_distribution_map_reverse.put(record_length, count + 1); } - length_reverse.add((double)record_length); + length_reverse.add(record_length); @@ -69,7 +69,7 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ int count = length_distribution_map_forward.get(record_length); length_distribution_map_forward.put(record_length, count + 1); } - length_forward.add((double)record_length); + length_forward.add(record_length); } @@ -91,7 +91,7 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ public HashMap<Integer, Integer> getSeqLen(LengthDistribution lengthDistribution) { - List<Double> length_all = lengthDistribution.getLength_all(); + List<Integer> length_all = lengthDistribution.getLength_all(); HashMap<Integer, Integer> map_length_occurrences_all = new HashMap<>(); for(double d : length_all){ @@ -114,15 +114,15 @@ public HashMap<Integer, Integer> getLength_distribution_map_reverse() { return length_distribution_map_reverse; } - public List<Double> getLength_forward() { + public List<Integer> getLength_forward() { return length_forward; } - public List<Double> getLength_reverse() { + public List<Integer> getLength_reverse() { return length_reverse; } - public List<Double> getLength_all() { + public List<Integer> getLength_all() { return length_all; } diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index 59c4439..3dff530 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -369,7 +369,7 @@ private void generateOutput( inputfileNameWithOutExtension ); outputGenerator.plotIdentitiyHistogram( - damageProfiler.getIdentity(), + damageProfiler.getEditDistances(), // damageProfiler.getIdentity(), "Identity distribution", inputfileNameWithOutExtension ); diff --git a/src/main/java/controller/DamageProfilerMainController.java b/src/main/java/controller/DamageProfilerMainController.java index 12e751e..3a0b1a0 100644 --- a/src/main/java/controller/DamageProfilerMainController.java +++ b/src/main/java/controller/DamageProfilerMainController.java @@ -1,6 +1,7 @@ package controller; import GUI.*; +import GUI.Dialogues.HelpDialogue; import GUI.Dialogues.RunInfoDialogue; import GUI.Dialogues.RuntimeEstimatorDialogue; import GUI.Plots.DamagePlot; @@ -17,8 +18,11 @@ import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.text.Font; import javafx.util.Duration; +import javax.swing.*; import java.lang.reflect.Field; public class DamageProfilerMainController { @@ -29,6 +33,8 @@ public class DamageProfilerMainController { private final Button btn_leftpane_lengthDist; private final ProgressBarController progressBarController; private final Button btn_estimate_runtime; + private final Button btn_help; + private final HelpDialogue help_dialogue; private RunInfoDialogue runInfoDialogue; private Communicator communicator; private Button btn_inputfile; @@ -46,15 +52,19 @@ public class DamageProfilerMainController { private StartCalculations starter = new StartCalculations(); private DamageProfilerMainGUI mainGUI; private RuntimeEstimatorDialogue runtimeInfoDialogue; - private long numberOfRecords; - + /** + * Constructor + * @param damageProfilerMainGUI + * @param progressBarController + */ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, ProgressBarController progressBarController){ this.mainGUI = damageProfilerMainGUI; this.progressBarController = progressBarController; this.communicator = mainGUI.getCommunicator(); runInfoDialogue = new RunInfoDialogue("Run configuration", communicator); starter.setVERSION(damageProfilerMainGUI.getVersion()); + this.help_dialogue = new HelpDialogue(); this.btn_inputfile = mainGUI.getConfig_dialogue().getBtn_inputfile(); this.btn_reference = mainGUI.getConfig_dialogue().getBtn_reference(); @@ -64,6 +74,7 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.btn_specieList = mainGUI.getConfig_dialogue().getBtn_specieList(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); + this.btn_help = mainGUI.getBtn_help(); this.btn_leftpane_damageProfile = mainGUI.getBtn_leftpane_damageProfile(); this.btn_leftpane_lengthDist = mainGUI.getBtn_leftpane_lengthDist(); @@ -104,6 +115,9 @@ private void addListener() { }); + btn_help.setOnAction(e -> { + mainGUI.getRoot().setCenter(new ScrollPane(this.help_dialogue.getGridPane())); + }); btn_reference.setOnAction(e -> { From 7c7579e9a2f55cd9882bc3b2223fd28399c47ef9 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <afW91L:C> Date: Thu, 2 Apr 2020 14:14:03 +0200 Subject: [PATCH 11/22] GUI and CLI plots are identical now (made with same library), working on GUI --- build.gradle | 5 +- src/main/java/GUI/DamageProfilerMainGUI.java | 43 ++--- .../AdvancedPlottingOptionsDialogue.java | 63 +++++-- .../java/GUI/Dialogues/ColorPickerPane.java | 18 ++ .../GUI/Dialogues/ConfigurationDialogue.java | 11 +- src/main/java/GUI/Dialogues/HelpDialogue.java | 7 +- .../TabAdvancedSettingsDamagePlot.java | 92 +++++++++++ .../TabAdvancedSettingsEditdistance.java | 22 +++ ...TabAdvancedSettingsLengthDistribution.java | 22 +++ src/main/java/GUI/Plots/DamagePlot.java | 111 ------------- src/main/java/GUI/Plots/IdentityHistPlot.java | 79 --------- src/main/java/GUI/Plots/LengthDistPlot.java | 156 ------------------ src/main/java/IO/Communicator.java | 50 +++++- src/main/java/IO/OutputGenerator.java | 51 ++++-- src/main/java/RunDamageProfiler.java | 2 - src/main/java/StarterGUI.java | 4 +- .../java/calculations/DamageProfiler.java | 18 +- .../java/calculations/StartCalculations.java | 116 ++++++------- .../DamageProfilerMainController.java | 96 ++++++++--- .../TabPaneAdvPlottingController.java | 4 + 20 files changed, 467 insertions(+), 503 deletions(-) create mode 100644 src/main/java/GUI/Dialogues/ColorPickerPane.java create mode 100644 src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java create mode 100644 src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java create mode 100644 src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java delete mode 100644 src/main/java/GUI/Plots/DamagePlot.java delete mode 100644 src/main/java/GUI/Plots/IdentityHistPlot.java delete mode 100644 src/main/java/GUI/Plots/LengthDistPlot.java create mode 100644 src/main/java/controller/TabPaneAdvPlottingController.java diff --git a/build.gradle b/build.gradle index aad3973..ef1da61 100644 --- a/build.gradle +++ b/build.gradle @@ -40,19 +40,18 @@ sourceSets { } + dependencies { compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' compile group: 'commons-cli', name: 'commons-cli', version: '1.3.+' compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.+' - compile group: 'org.jfree', name: 'jcommon', version: '1.0.+' - compile group: 'jfree', name: 'jfreechart', version: '1.0.13' compile group: 'com.github.samtools', name: 'htsjdk', version: '2.+' compile group: 'com.intellij', name: 'forms_rt', version: '6.0.+' compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' - compile 'org.jfxtras:jmetro:8.6.5' compile group: 'org.jfree', name: 'jfreesvg', version: '2.0' compile group: 'org.apache.commons', name: 'commons-text', version: '1.+' + compile 'org.jfree:jfreechart-fx:1.+' } diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java index 2c62954..6c7fb9a 100644 --- a/src/main/java/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/GUI/DamageProfilerMainGUI.java @@ -6,9 +6,12 @@ import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; +import java.io.InputStream; public class DamageProfilerMainGUI { @@ -31,9 +34,7 @@ public DamageProfilerMainGUI(String version, ProgressBarController progressBarCo this.progressBarController = progressBarController; } - public void init(Stage primaryStage){ - - //JMetro jMetro = new JMetro(Style.LIGHT); + public void init(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setTitle("DamageProfiler v" + version); @@ -42,11 +43,12 @@ public void init(Stage primaryStage){ config_dialogue = new ConfigurationDialogue(progressBarController.getProgressBar()); - root.setCenter(config_dialogue.getConfig_gridpane()); + ScrollPane scrollPane_adv_config = new ScrollPane(); + scrollPane_adv_config.setPadding(new Insets(10,10,10,10)); + scrollPane_adv_config.setContent(config_dialogue.getConfig_gridpane()); + root.setCenter(scrollPane_adv_config); root.setLeft(generateLeftPane()); - //jMetro.setScene(new Scene(root, 750, 500)); - //this.primaryStage.setScene(jMetro.getScene()); this.primaryStage.setScene(new Scene(root, 950, 700)); this.primaryStage.setResizable(true); this.primaryStage.show(); @@ -54,6 +56,17 @@ public void init(Stage primaryStage){ } private VBox generateLeftPane() { + + // Image Source + InputStream input= getClass().getClassLoader().getResourceAsStream("logo.png"); + Image image = new Image(input); + ImageView imageView = new ImageView(image); + + // Create a Label with label and Icon + Label label = new Label("", imageView); + + + VBox leftPanel = new VBox(); btn_leftpane_damageProfile = new Button("Damage Plot"); btn_leftpane_info = new Button("Run Configuration"); @@ -80,7 +93,7 @@ private VBox generateLeftPane() { btn_leftpane_identityDist.setPrefWidth(200); btn_leftpane_identityDist.setDisable(true); - leftPanel.getChildren().addAll(btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist, btn_help); + leftPanel.getChildren().addAll(label, btn_leftpane_info, btn_leftpane_damageProfile, btn_leftpane_lengthDist, btn_leftpane_identityDist, btn_help); leftPanel.setPadding(new Insets(10,10,10,10)); return leftPanel; @@ -100,9 +113,7 @@ public Button getBtn_leftpane_identityDist() { return btn_leftpane_identityDist; } - public Button getBtn_leftpane_info() { - return btn_leftpane_info; - } + public Button getBtn_leftpane_info() { return btn_leftpane_info; } public Button getBtn_leftpane_damageProfile() { return btn_leftpane_damageProfile; @@ -112,15 +123,9 @@ public Button getBtn_leftpane_lengthDist() { return btn_leftpane_lengthDist; } - public Button getBtn_help() { - return btn_help; - } + public Button getBtn_help() { return btn_help; } - public ConfigurationDialogue getConfig_dialogue() { - return config_dialogue; - } + public ConfigurationDialogue getConfig_dialogue() { return config_dialogue; } - public String getVersion() { - return version; - } + public String getVersion() { return version; } } diff --git a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java b/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java index 85a6a4b..086dc8b 100644 --- a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java +++ b/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java @@ -1,29 +1,68 @@ package GUI.Dialogues; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.Node; -import javafx.scene.layout.GridPane; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; + public class AdvancedPlottingOptionsDialogue { - private GridPane plotting_config_gridpane; + + private TabPane tabPane; + private Tab tab_Length_Dist; + private Tab tab_Edit_Dist; + private Tab tab_DP; + private TabAdvancedSettingsLengthDistribution tabAdvancedSettingsLengthDistribution; + private TabAdvancedSettingsDamagePlot tabAdvancedSettingsDamagePlot; + private TabAdvancedSettingsEditdistance tabAdvancedSettingsEditdistance; public AdvancedPlottingOptionsDialogue(){ - plotting_config_gridpane = new GridPane(); - plotting_config_gridpane.setAlignment(Pos.CENTER); - plotting_config_gridpane.setHgap(10); - plotting_config_gridpane.setVgap(10); - plotting_config_gridpane.setPadding(new Insets(15,15,15,15)); fill(); } private void fill() { + tabAdvancedSettingsDamagePlot = new TabAdvancedSettingsDamagePlot("Damage Profile"); + tab_DP = tabAdvancedSettingsDamagePlot.getTab(); + + tabAdvancedSettingsEditdistance = new TabAdvancedSettingsEditdistance("Edit Distance"); + tab_Edit_Dist = tabAdvancedSettingsEditdistance.getTab(); + + tabAdvancedSettingsLengthDistribution = new TabAdvancedSettingsLengthDistribution("Length Distribution"); + tab_Length_Dist = tabAdvancedSettingsLengthDistribution.getTab(); + + tabPane = new TabPane(); + tabPane.getTabs().addAll(tab_DP,tab_Edit_Dist, tab_Length_Dist); + + } + + + + + public TabPane getGridPane() { + return tabPane; + } + + public Tab getTab_Length_Dist() { + return tab_Length_Dist; + } + + public Tab getTab_Edit_Dist() { + return tab_Edit_Dist; } + public Tab getTab_DP() { + return tab_DP; + } + + public TabAdvancedSettingsDamagePlot getTabAdvancedSettingsDamagePlot() { + return tabAdvancedSettingsDamagePlot; + } + + public TabAdvancedSettingsLengthDistribution getTabAdvancedSettingsLengthDistribution() { + return tabAdvancedSettingsLengthDistribution; + } - public Node getGridPane() { - return plotting_config_gridpane; + public TabAdvancedSettingsEditdistance getTabAdvancedSettingsEditdistance() { + return tabAdvancedSettingsEditdistance; } } diff --git a/src/main/java/GUI/Dialogues/ColorPickerPane.java b/src/main/java/GUI/Dialogues/ColorPickerPane.java new file mode 100644 index 0000000..38b8eb2 --- /dev/null +++ b/src/main/java/GUI/Dialogues/ColorPickerPane.java @@ -0,0 +1,18 @@ +package GUI.Dialogues; + +import javafx.scene.Node; +import javafx.scene.control.ColorPicker; +import javafx.scene.paint.Color; + +public class ColorPickerPane { + private ColorPicker colorPicker; + + public ColorPickerPane(Color color){ + colorPicker = new ColorPicker(); + colorPicker.setValue(color); + } + + public ColorPicker getPicker() { + return colorPicker; + } +} diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java index 9b07cfd..ce8dfe6 100644 --- a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java @@ -5,7 +5,6 @@ import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; @@ -27,10 +26,10 @@ public class ConfigurationDialogue { private CheckBox checkbox_use_merged_reads; private CheckBox checkbox_ssLibs_protocol; private TextField textfield_title; - //private CheckBox checkbox_dynamic_y_axis_height; private TextField textfield_y_axis_height; private ProgressBar progressBar; + private AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue; public ConfigurationDialogue(ProgressBar progressBar){ @@ -81,7 +80,6 @@ private void addComponents() { checkbox_use_merged_reads = new CheckBox("Only merged reads"); checkbox_ssLibs_protocol = new CheckBox("Single-stranded library protocol"); - //checkbox_dynamic_y_axis_height = new CheckBox("Dynamic"); btn_run.setDisable(true); btn_estimate_runtime.setDisable(true); @@ -91,7 +89,8 @@ private void addComponents() { TitledPane pane_advanced_plotting_options = new TitledPane(); pane_advanced_plotting_options.setText("Advanced options (Plotting)"); - AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue = new AdvancedPlottingOptionsDialogue(); + + advancedPlottingOptionsDialogue = new AdvancedPlottingOptionsDialogue(); pane_advanced_plotting_options.setContent(advancedPlottingOptionsDialogue.getGridPane()); pane_advanced_plotting_options.setExpanded(false); @@ -202,4 +201,8 @@ public TextField getTextfield_y_axis_height() { public Button getBtn_estimate_runtime() { return btn_estimate_runtime; } + + public AdvancedPlottingOptionsDialogue getAdvancedPlottingOptionsDialogue() { + return advancedPlottingOptionsDialogue; + } } diff --git a/src/main/java/GUI/Dialogues/HelpDialogue.java b/src/main/java/GUI/Dialogues/HelpDialogue.java index 1212876..c28eaad 100644 --- a/src/main/java/GUI/Dialogues/HelpDialogue.java +++ b/src/main/java/GUI/Dialogues/HelpDialogue.java @@ -35,7 +35,7 @@ public HelpDialogue(){ * Fill dialogue with help content */ private void fill() { - Label label_title = new Label("Welcome to damageProfiler help page"); + Label label_title = new Label("Welcome to DamageProfiler help page"); label_title.setFont(Font.font("Verdana", FontWeight.BOLD, 14)); Label label_usage = new Label("Usage:\n"); @@ -60,6 +60,7 @@ private void fill() { } }).start()); + // todo: one could make it a bit nicer Label label_helppage = new Label(" -h\t\t\t\t\t\t\tShows this help page.\n" + " -version\t\t\t\t\t\tShows the version of DamageProfiler.\n" + " -i <INPUT>\t\t\t\t\tREQUIRED: The input sam/bam/cram file.\n" + @@ -90,13 +91,9 @@ private void fill() { gridPane.add(label_details,0, ++row,2,1); gridPane.add(label_helppage, 0,++row, 2,1); - - - } - // Getter public GridPane getGridPane() { diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java new file mode 100644 index 0000000..2c29175 --- /dev/null +++ b/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java @@ -0,0 +1,92 @@ +package GUI.Dialogues; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.ColorPicker; +import javafx.scene.control.Label; +import javafx.scene.control.Tab; +import javafx.scene.layout.GridPane; +import javafx.scene.paint.Color; + +public class TabAdvancedSettingsDamagePlot { + + private final Tab tab; + private ColorPicker colorPicker_C_to_T; + private ColorPicker colorPicker_G_to_A; + private ColorPicker colorPicker_insertions; + private ColorPicker colorPicker_deletions; + private ColorPicker colorPicker_others; + + public TabAdvancedSettingsDamagePlot(String title){ + + this.tab = new Tab(title); + fill(); + + } + + private void fill() { + GridPane gridpane = new GridPane(); + gridpane.setAlignment(Pos.BOTTOM_LEFT); + gridpane.setHgap(7); + gridpane.setVgap(7); + gridpane.setPadding(new Insets(10,10,10,10)); + + Button btn_reset = new Button("Reset"); + colorPicker_C_to_T = generateColorPicker(Color.RED); + colorPicker_G_to_A = generateColorPicker(Color.BLUE); + colorPicker_insertions = generateColorPicker(Color.valueOf("FF00FF")); + colorPicker_deletions = generateColorPicker(Color.GREEN); + colorPicker_others = generateColorPicker(Color.GREY); + + gridpane.add(new Label("C->T"), 0,0,1,1); + gridpane.add(colorPicker_C_to_T, 0,1,1,1); + + gridpane.add(new Label("G->A"), 1,0,1,1); + gridpane.add(colorPicker_G_to_A, 1,1,1,1); + + gridpane.add(new Label("Insertions"), 0,2,1,1); + gridpane.add(colorPicker_insertions, 0,3,1,1); + + gridpane.add(new Label("Deletions"), 1,2,1,1); + gridpane.add(colorPicker_deletions, 1,3,1,1); + + gridpane.add(new Label("Others"), 0,4,1,1); + gridpane.add(colorPicker_others, 0,5,1,1); + + gridpane.add(btn_reset, 2,5,1,1); + + tab.setContent(gridpane); + } + + + private ColorPicker generateColorPicker(Color color) { + ColorPickerPane colorPickerPane = new ColorPickerPane(color); + return colorPickerPane.getPicker(); + + } + + public Tab getTab() { + return tab; + } + + public ColorPicker getColorPicker_C_to_T() { + return colorPicker_C_to_T; + } + + public ColorPicker getColorPicker_G_to_A() { + return colorPicker_G_to_A; + } + + public ColorPicker getColorPicker_insertions() { + return colorPicker_insertions; + } + + public ColorPicker getColorPicker_deletions() { + return colorPicker_deletions; + } + + public ColorPicker getColorPicker_others() { + return colorPicker_others; + } +} diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java new file mode 100644 index 0000000..a860808 --- /dev/null +++ b/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java @@ -0,0 +1,22 @@ +package GUI.Dialogues; + +import javafx.scene.control.Tab; + +public class TabAdvancedSettingsEditdistance { + + private final Tab tab; + + public TabAdvancedSettingsEditdistance(String title){ + this.tab = new Tab(title); + fill(); + } + + private void fill() { + + } + + public Tab getTab() { + + return tab; + } +} diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java new file mode 100644 index 0000000..f5548ae --- /dev/null +++ b/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java @@ -0,0 +1,22 @@ +package GUI.Dialogues; + +import javafx.scene.control.Tab; + +public class TabAdvancedSettingsLengthDistribution { + + private final Tab tab; + + public TabAdvancedSettingsLengthDistribution(String title){ + this.tab = new Tab(title); + fill(); + } + + private void fill() { + + } + + public Tab getTab() { + + return tab; + } +} diff --git a/src/main/java/GUI/Plots/DamagePlot.java b/src/main/java/GUI/Plots/DamagePlot.java deleted file mode 100644 index a80e63c..0000000 --- a/src/main/java/GUI/Plots/DamagePlot.java +++ /dev/null @@ -1,111 +0,0 @@ -package GUI.Plots; - - -import IO.OutputGenerator; -import calculations.StartCalculations; -import javafx.scene.chart.CategoryAxis; -import javafx.scene.chart.LineChart; -import javafx.scene.chart.NumberAxis; -import javafx.scene.chart.XYChart; -import javafx.scene.layout.HBox; - -public class DamagePlot { - - - private final StartCalculations starter; - private OutputGenerator outputGenerator; - private LineChart<String, Number> lineChart3prime; - private LineChart<String, Number> lineChart5prime; - - public DamagePlot(OutputGenerator outputGenerator, StartCalculations starter) { - - this.outputGenerator = outputGenerator; - this.starter = starter; - - CategoryAxis xAxis_5 = new CategoryAxis(); - NumberAxis yAxis_5 = new NumberAxis(0.0, outputGenerator.getMaxYdamapePlot(), 0.05); - - CategoryAxis xAxis_3 = new CategoryAxis(); - NumberAxis yAxis_3 = new NumberAxis(0.0, outputGenerator.getMaxYdamapePlot(), 0.05); - - lineChart5prime = new LineChart<String,Number>(xAxis_5,yAxis_5); - lineChart5prime.setCreateSymbols(false); - - lineChart3prime = new LineChart<String,Number>(xAxis_3,yAxis_3); - lineChart3prime.setCreateSymbols(false); - - createFivePrimePlot(); - createThreePrimePlot(); - - } - - - private void createFivePrimePlot() { - - lineChart5prime.setTitle("5' end"); - - // C -> T misincorporations 5' - XYChart.Series series1 = new XYChart.Series(); - series1.setName("C -> T"); - - double[] data_C_T_5 = starter.getDamageProfiler().getFrequencies().getCount_C_T_5_norm(); - for(int i = 0; i < outputGenerator.getThreshold(); i++){ - series1.getData().add(new XYChart.Data(String.valueOf(i+1), data_C_T_5[i])); - } - - // G -> A misincorporations 5' - XYChart.Series series2 = new XYChart.Series(); - series2.setName("G -> A"); - - double[] data_G_A_5 = starter.getDamageProfiler().getFrequencies().getCount_G_A_5_norm(); - for(int i = 0; i < outputGenerator.getThreshold(); i++){ - series2.getData().add(new XYChart.Data(String.valueOf(i+1), data_G_A_5[i])); - } - - lineChart5prime.getData().addAll(series1, series2); - - } - - private void createThreePrimePlot() { - - lineChart3prime.setTitle("3' end"); - - // C -> T misincorporations 3' - - XYChart.Series series1 = new XYChart.Series(); - series1.setName("C -> T"); - double[] data_C_T_3 = this.outputGenerator.getThree_C_to_T_reverse(); - - for(int i = 0; i < outputGenerator.getThreshold(); i++){ - series1.getData().add(new XYChart.Data(String.valueOf(i+1), data_C_T_3[i])); - } - - - - // G -> A misincorporations 3' - - XYChart.Series series2 = new XYChart.Series(); - series2.setName("G -> A"); - double[] data_G_A_3 = this.outputGenerator.getThree_G_to_A_reverse(); - - for(int i = 0; i < outputGenerator.getThreshold(); i++){ - series2.getData().add(new XYChart.Data(String.valueOf(i+1), data_G_A_3[i])); - } - - lineChart3prime.getData().addAll(series1, series2); - - } - - public HBox getDamageProfile() { - HBox plots_combined = new HBox(); - - lineChart5prime.prefHeightProperty().bind(plots_combined.heightProperty()); - lineChart5prime.prefWidthProperty().bind(plots_combined.widthProperty()); - - lineChart3prime.prefHeightProperty().bind(plots_combined.heightProperty()); - lineChart3prime.prefWidthProperty().bind(plots_combined.widthProperty()); - - plots_combined.getChildren().addAll(lineChart5prime, lineChart3prime); - return plots_combined; - } -} diff --git a/src/main/java/GUI/Plots/IdentityHistPlot.java b/src/main/java/GUI/Plots/IdentityHistPlot.java deleted file mode 100644 index 11176e6..0000000 --- a/src/main/java/GUI/Plots/IdentityHistPlot.java +++ /dev/null @@ -1,79 +0,0 @@ -package GUI.Plots; - -import javafx.scene.chart.*; -import java.util.*; - - -public class IdentityHistPlot { - - private BarChart<String, Number> barChart; - - private Double[] data; - private HashMap<Double, Integer> idents_count; - - - public IdentityHistPlot(ArrayList<Double> identity_data) { - - prepareData(identity_data); - groupData(); - - final CategoryAxis xAxis = new CategoryAxis(); - final NumberAxis yAxis = new NumberAxis(); - barChart = new BarChart<>(xAxis,yAxis); - - barChart.setCategoryGap(0); - barChart.setBarGap(1); - barChart.setTitle("Read identity"); - - yAxis.setLabel("Number of reads"); - xAxis.setLabel("Read identity"); - - XYChart.Series series1 = new XYChart.Series(); - - List<Double> targetList = new ArrayList<>(idents_count.keySet()); - Collections.sort(targetList); - - for(double d : targetList){ - if (idents_count.containsKey(d)){ - series1.getData().add(new XYChart.Data(String.valueOf(d), idents_count.get(d))); - } else { - series1.getData().add(new XYChart.Data(String.valueOf(d), 0)); - } - - } - - barChart.getData().addAll(series1); - - } - - - - //prepare data - private void prepareData(ArrayList<Double> identity_data){ - data = new Double[identity_data.size()]; - for(int i=0; i < identity_data.size(); i++){ - data[i] = Math.round(identity_data.get(i) * 1000.0) / 1000.0; - } - } - - //count data identities in groups - private void groupData(){ - - idents_count = new HashMap<Double, Integer>(); - - for (double ident : data) { - if (!idents_count.containsKey(ident)) { - idents_count.put(ident, 1); - } else { - int count_tmp = idents_count.get(ident); - count_tmp=count_tmp+1; - idents_count.put(ident, count_tmp); - } - } - - } - - public BarChart<String, Number> getBarChart() { - return barChart; - } -} diff --git a/src/main/java/GUI/Plots/LengthDistPlot.java b/src/main/java/GUI/Plots/LengthDistPlot.java deleted file mode 100644 index 1105d3c..0000000 --- a/src/main/java/GUI/Plots/LengthDistPlot.java +++ /dev/null @@ -1,156 +0,0 @@ -package GUI.Plots; - -import calculations.DamageProfiler; -import javafx.scene.chart.BarChart; -import javafx.scene.chart.CategoryAxis; -import javafx.scene.chart.NumberAxis; -import javafx.scene.chart.XYChart; -import javafx.scene.layout.HBox; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -public class LengthDistPlot { - - private BarChart<String, Number> bc_data_all; - private BarChart<String, Number> bc_data_split; - - public LengthDistPlot(DamageProfiler damageProfiler){ - - generate_alldata(damageProfiler.getLength_all()); - generate_split_data(damageProfiler.getLength_distribution_map_forward(), - damageProfiler.getLength_distribution_map_reverse()); - - - } - - private void generate_split_data(HashMap<Integer, Integer> length_distribution_map_forward, HashMap<Integer, Integer> length_distribution_map_reverse) { - - //Double[] data_forward = prepareData((List<Double>) length_distribution_map_forward); - //Double[] data_reverse = prepareData((List<Double>) length_distribution_map_reverse); - - HashMap<Integer, Integer> length_map_forward = length_distribution_map_forward; - HashMap<Integer, Integer> length_map_reverse = length_distribution_map_reverse; - - final CategoryAxis xAxis = new CategoryAxis(); - final NumberAxis yAxis = new NumberAxis(); - bc_data_split = new BarChart<>(xAxis,yAxis); - - bc_data_split.setCategoryGap(0); - bc_data_split.setBarGap(1); - bc_data_split.setTitle("Read length distribution"); - - yAxis.setLabel("Number of reads"); - xAxis.setLabel("Read length"); - - XYChart.Series series_forward = new XYChart.Series(); - - List<Integer> targetList_forward = new ArrayList<>(length_map_forward.keySet()); - Collections.sort(targetList_forward); - - for(int d : targetList_forward){ - if (length_map_forward.containsKey(d)){ - series_forward.getData().add(new XYChart.Data(String.valueOf(d), length_map_forward.get(d))); - } else { - series_forward.getData().add(new XYChart.Data(String.valueOf(d), 0)); - } - - } - - - XYChart.Series series_reverse = new XYChart.Series(); - - List<Integer> targetList_reverse = new ArrayList<>(length_map_reverse.keySet()); - Collections.sort(targetList_reverse); - - for(double d : targetList_reverse){ - if (length_map_reverse.containsKey(d)){ - series_reverse.getData().add(new XYChart.Data(String.valueOf(d), length_map_reverse.get(d))); - } else { - series_reverse.getData().add(new XYChart.Data(String.valueOf(d), 0)); - } - - } - bc_data_split.getData().addAll(series_forward, series_reverse); - - - } - - private void generate_alldata(List<Integer> length_all) { - - Double[] data_all = prepareData(length_all); - HashMap<Double, Integer> length_map_all = groupData(data_all); - - - final CategoryAxis xAxis = new CategoryAxis(); - final NumberAxis yAxis = new NumberAxis(); - bc_data_all = new BarChart<>(xAxis,yAxis); - - bc_data_all.setCategoryGap(0); - bc_data_all.setBarGap(1); - bc_data_all.setTitle("Read length distribution"); - - yAxis.setLabel("Number of reads"); - xAxis.setLabel("Read length"); - - XYChart.Series series1 = new XYChart.Series(); - - List<Double> targetList = new ArrayList<>(length_map_all.keySet()); - Collections.sort(targetList); - - for(double d : targetList){ - if (length_map_all.containsKey(d)){ - series1.getData().add(new XYChart.Data(String.valueOf(d), length_map_all.get(d))); - } else { - series1.getData().add(new XYChart.Data(String.valueOf(d), 0)); - } - - } - - bc_data_all.getData().addAll(series1); - - } - - private HashMap<Double, Integer> groupData(Double[] data_all) { - - HashMap<Double, Integer> idents_count = new HashMap<Double, Integer>(); - - for (double ident : data_all) { - if (!idents_count.containsKey(ident)) { - idents_count.put(ident, 1); - } else { - int count_tmp = idents_count.get(ident); - count_tmp=count_tmp+1; - idents_count.put(ident, count_tmp); - } - } - - return idents_count; - } - - private Double[] prepareData(List<Integer> length_data_all) { - - - Double[] data_all = new Double[length_data_all.size()]; - for(int i=0; i < length_data_all.size(); i++){ - data_all[i] = Math.round(length_data_all.get(i) * 1000.0) / 1000.0; - } - - return data_all; - } - - public HBox getBc() { - HBox plots_combined = new HBox(); - - bc_data_all.prefHeightProperty().bind(plots_combined.heightProperty()); - bc_data_all.prefWidthProperty().bind(plots_combined.widthProperty()); - - bc_data_split.prefHeightProperty().bind(plots_combined.heightProperty()); - bc_data_split.prefWidthProperty().bind(plots_combined.widthProperty()); - - plots_combined.getChildren().addAll(bc_data_all, bc_data_split); - return plots_combined; - } -} diff --git a/src/main/java/IO/Communicator.java b/src/main/java/IO/Communicator.java index 14656fb..a04fbd0 100755 --- a/src/main/java/IO/Communicator.java +++ b/src/main/java/IO/Communicator.java @@ -1,5 +1,7 @@ package IO; +import javafx.scene.paint.Color; + /** * Created by neukamm on 11.11.2016. */ @@ -29,7 +31,11 @@ public class Communicator { // plot settings private String title_plots; - + private Color color_DP_C_to_T; + private Color color_DP_G_to_A; + private Color color_DP_insertions; + private Color color_DP_deletions; + private Color color_DP_other; public String getInput() { @@ -160,4 +166,46 @@ public double getXaxis_histo_length_max() { public void setXaxis_histo_length_max(double xaxis_histo_length_max) { this.xaxis_histo_length_max = xaxis_histo_length_max; } + + public void setColor_DP_C_to_T(Color color_c_to_t) { + this.color_DP_C_to_T = color_c_to_t; + + } + + public void setColor_DP_G_to_A(Color color_g_to_a) { + this.color_DP_G_to_A = color_g_to_a; + } + + public void setColor_DP_insertions(Color color_insertions) { + this.color_DP_insertions = color_insertions; + } + + public void setColor_DP_deletions(Color color_deletions) { + this.color_DP_deletions = color_deletions; + } + + public void setColor_DP_other(Color color_other) { + this.color_DP_other = color_other; + + } + + public Color getColor_DP_C_to_T() { + return color_DP_C_to_T; + } + + public Color getColor_DP_G_to_A() { + return color_DP_G_to_A; + } + + public Color getColor_DP_insertions() { + return color_DP_insertions; + } + + public Color getColor_DP_deletions() { + return color_DP_deletions; + } + + public Color getColor_DP_other() { + return color_DP_other; + } } diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index 6728fb7..fd43813 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -12,7 +12,6 @@ import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.PdfWriter; -import javafx.scene.chart.BarChart; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.log4j.Logger; import org.jfree.chart.JFreeChart; @@ -59,6 +58,11 @@ public class OutputGenerator { private HashMap<String,Object> json_map = new HashMap<>(); private double[] three_C_to_T_reverse; private double[] three_G_to_A_reverse; + private JFreeChart chart_DP_5prime; + private JFreeChart chart_DP_3prime; + private JFreeChart length_chart_all; + private JFreeChart length_chart_separated; + private JFreeChart editDist_chart; public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, @@ -448,7 +452,7 @@ public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_f Histogram hist_all = new Histogram(LOG); hist_all.addData(length_all); HistogramDataset dataset_all = hist_all.createDataset(new String[]{"all reads"}, max_length); - JFreeChart chart_all = hist_all.createChart(dataset_all, "", "Read length", + length_chart_all = hist_all.createChart(dataset_all, "", "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo, false); Histogram hist_separated = new Histogram(LOG); @@ -459,12 +463,12 @@ public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_f hist_separated.addData(length_reverse); } HistogramDataset dataset_separated = hist_separated.createDataset(new String[]{"+ strand", "- strand"}, max_length); - JFreeChart chart_separated = hist_separated.createChart(dataset_separated, "", + length_chart_separated = hist_separated.createChart(dataset_separated, "", "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo, true); - createPdf("/Length_plot.pdf", new JFreeChart[]{chart_all, chart_separated}, file); - createSVG("/Length_plot_combined_data.svg", chart_all); - createSVG("/Length_plot_forward_reverse_separated.svg", chart_separated); + createPdf("/Length_plot.pdf", new JFreeChart[]{length_chart_all, length_chart_separated}, file); + createSVG("/Length_plot_combined_data.svg", length_chart_all); + createSVG("/Length_plot_forward_reverse_separated.svg", length_chart_separated); } @@ -483,10 +487,10 @@ public void plotIdentitiyHistogram(List<Integer> distances, String title, Strin hist_all.addData(distances); HistogramDataset dataset = hist_all.createDataset(new String[]{title}, 100); - JFreeChart chart_all = hist_all.createChart(dataset, "", "Edit distance", "Occurrences", + editDist_chart = hist_all.createChart(dataset, "", "Edit distance", "Occurrences", x_axis_min_id_histo, x_axis_max_id_histo, false); - createPdf("/identity_histogram.pdf", new JFreeChart[]{chart_all}, file); - createSVG("/identity_histogram.svg", chart_all); + createPdf("/identity_histogram.pdf", new JFreeChart[]{editDist_chart}, file); + createSVG("/identity_histogram.svg", editDist_chart); } @@ -854,19 +858,19 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep JFreeChart[] charts; // create damage plot five prime - JFreeChart chart = damagePlot_five.createChart(dataset_five, ymax, threshold); + chart_DP_5prime = damagePlot_five.createChart(dataset_five, ymax, threshold); if(!ssLibProtocolUsed){ XYDataset dataset_three = damagePlot_three.createDataset(); // create damage plot three prime - JFreeChart chart1 = damagePlot_three.createChart(dataset_three, ymax, threshold); - charts = new JFreeChart[]{chart, chart1}; - createSVG("/DamagePlot_three_prime.svg", chart1); + chart_DP_3prime = damagePlot_three.createChart(dataset_three, ymax, threshold); + charts = new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; + createSVG("/DamagePlot_three_prime.svg", chart_DP_3prime); } else { - charts = new JFreeChart[]{chart}; + charts = new JFreeChart[]{chart_DP_5prime}; } createPdf("/DamagePlot.pdf", charts, file); - createSVG("/DamagePlot_five_prime.svg", chart); + createSVG("/DamagePlot_five_prime.svg", chart_DP_5prime); } @@ -1035,4 +1039,21 @@ public double[] getThree_G_to_A_reverse() { public double getMaxYdamapePlot() { return height; } + + public JFreeChart[] getDP_chart() { + if(chart_DP_3prime!=null){ + return new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; + } else { + return new JFreeChart[]{chart_DP_5prime}; + } + } + + public JFreeChart[] getLengthDistPlots() { + return new JFreeChart[]{length_chart_all, length_chart_separated}; + + } + + public JFreeChart getEditDist_chart() { + return editDist_chart; + } } diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index 988d685..b0160ba 100644 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -7,8 +7,6 @@ public class RunDamageProfiler { private static final String VERSION = "0.4.9"; - - @SuppressWarnings("static-access") public static void main(String[] args) throws Exception { /* diff --git a/src/main/java/StarterGUI.java b/src/main/java/StarterGUI.java index fb8db4c..84ed041 100755 --- a/src/main/java/StarterGUI.java +++ b/src/main/java/StarterGUI.java @@ -1,12 +1,12 @@ import controller.DamageProfilerMainController; import GUI.DamageProfilerMainGUI; import controller.ProgressBarController; +import controller.TabPaneAdvPlottingController; import javafx.application.Application; import javafx.stage.Stage; - public class StarterGUI extends Application { private static final String VERSION = "0.4.9"; @@ -23,8 +23,6 @@ public void start(Stage primaryStage) { DamageProfilerMainController damageProfilerMainController = new DamageProfilerMainController(damageProfilerMainGUI, progressBarController); - - } diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index d7f81af..a6f865f 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -126,6 +126,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea long startTime = System.currentTimeMillis(); for(SAMRecord record : inputSam) { + numberOfRecords++; if (this.specie == null) { @@ -150,16 +151,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } } - if((numberOfUsedReads % 100000) == 0){ - - long currtime_post_execution = System.currentTimeMillis(); - long diff = currtime_post_execution - startTime; - - runtime_ms = diff; - long runtime_s = diff / 1000; - actualRuntime += runtime_s; - startTime = System.currentTimeMillis(); - } } frequencies.normalizeValues(); @@ -168,13 +159,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea LOG.info("# reads used for damage calculation: " + (numberOfUsedReads )); } - if(actualRuntime > 60) { - long minutes = actualRuntime / 60; - long seconds = actualRuntime % 60; - System.out.println("Runtime for processing all records: " + minutes + " minutes, and " + seconds + " seconds."); - } else { - System.out.println("Runtime for processing all records: " + actualRuntime + " seconds and " + runtime_ms%60 + " milliseconds"); - } } diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index 3dff530..e289dfb 100644 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -8,6 +8,7 @@ import java.util.List; import com.itextpdf.text.DocumentException; +import javafx.scene.paint.Color; import org.apache.log4j.*; @@ -42,6 +43,18 @@ public class StartCalculations { private boolean ssLibProtocolUsed; private DamageProfiler damageProfiler; private OutputGenerator outputGenerator; + private String inputfileNameWithOutExtension; + private Communicator communicator; + + + // plot settings + private Color color_DP_C_to_T; + private Color color_DP_G_to_A; + private Color color_DP_insertions; + private Color color_DP_deletions; + private Color color_DP_other; + private String output_folder; + private String speciesname = null; public StartCalculations(){ @@ -72,12 +85,22 @@ public void start(Communicator c) throws Exception { speciesListParser=null; species_name_list=null; + color_DP_C_to_T = c.getColor_DP_C_to_T(); + color_DP_G_to_A = c.getColor_DP_G_to_A(); + color_DP_insertions = c.getColor_DP_insertions(); + color_DP_deletions = c.getColor_DP_deletions(); + color_DP_other = c.getColor_DP_other(); + + + this.inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); + this.communicator = c; SpeciesListParser speciesListParser = new SpeciesListParser( specieslist_filepath, LOG ); + if(specieslist_filepath != null){ /* @@ -94,28 +117,19 @@ parse species references (-sf) and run DP for each reference in the file // start DamageProfiler - File file = new File(input); damageProfiler = new DamageProfiler(specieHandler); String ref = specie_input_string.split("\\|")[0].trim(); - String speciesname = damageProfiler.getSpeciesname(file, ref); + speciesname = damageProfiler.getSpeciesname(new File(input), ref); - String inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - String output_folder = createOutputFolder( + + createOutputFolder( outfolder, inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1] + File.separator + ref + "_" + speciesname); - - - if (c.getTitle_plots() == null) { - inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - } else { - inputfileNameWithOutExtension = c.getTitle_plots(); - } - - + initPlot(); // init Logger initLogger(output_folder + "/DamageProfiler_" + ref + "_" + speciesname +".log", @@ -129,7 +143,7 @@ parse species references (-sf) and run DP for each reference in the file // create new output folder // log settings - LOG.info("Analysis of file (-i):" + file + "\n" + LOG.info("\nAnalysis of file (-i):" + input + "\n" + "Output folder (-o):" + output_folder + "\n" + "Reference (-r, optional) :" + reference + "\n" + "Specie (-s, optional):" + specie_input_string + "\n" @@ -143,7 +157,7 @@ parse species references (-sf) and run DP for each reference in the file + "x-axis max length histogram (-xaxis_histo_length_max): " + xaxis_max_length_histogram + "\n"); - damageProfiler.init(file, + damageProfiler.init(new File(input), new File(reference), threshold, length, @@ -152,7 +166,6 @@ parse species references (-sf) and run DP for each reference in the file damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); - generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, speciesname, ssLibProtocolUsed); } @@ -169,24 +182,16 @@ parse species reference (-s) and run DP this.specieslist = new ArrayList<>(); specieslist.add(species_ref_identifier); - String speciesname = damageProfiler.getSpeciesname(new File(input), species_ref_identifier); + speciesname = damageProfiler.getSpeciesname(new File(input), species_ref_identifier); String inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - String output_folder = createOutputFolder( + createOutputFolder( outfolder, inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1] + File.separator + species_ref_identifier + "_" + speciesname); - - if (c.getTitle_plots() == null) { - inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - } - else { - inputfileNameWithOutExtension = c.getTitle_plots(); - } - - + initPlot(); // init Logger initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); @@ -197,10 +202,8 @@ parse species reference (-s) and run DP input = unzip.decompress(input); } - // create new output folder - File file = new File(input); // log settings - LOG.info("Analysis of file (-i):" + file + "\n" + LOG.info("Analysis of file (-i):" + input + "\n" + "Output folder (-o):" + output_folder + "\n" + "Reference (-r, optional) :" + reference + "\n" + "Specie (-s, optional):" + specieslist + "\n" @@ -216,7 +219,7 @@ parse species reference (-s) and run DP - damageProfiler.init(file, + damageProfiler.init(new File(input), new File(reference), threshold, length, @@ -224,9 +227,8 @@ parse species reference (-s) and run DP LOG); damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); - speciesListParser.setLOG(LOG); - generateOutput(damageProfiler,output_folder, inputfileNameWithOutExtension, null, ssLibProtocolUsed); + } else { /* @@ -234,15 +236,11 @@ parse species reference (-s) and run DP */ String inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - String output_folder = createOutputFolder( + createOutputFolder( outfolder, inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1]); - if (c.getTitle_plots() == null) { - inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); - } else { - inputfileNameWithOutExtension = c.getTitle_plots(); - } + initPlot(); // init Logger initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); @@ -254,9 +252,9 @@ parse species reference (-s) and run DP } // create new output folder - File file = new File(input); + // log settings - LOG.info("Analysis of file (-i):" + file + "\n" + LOG.info("Analysis of file (-i):" + input + "\n" + "Output folder (-o):" + output_folder + "\n" + "Reference (-r, optional) :" + reference + "\n" + "Specie (-s, optional):" + specieslist + "\n" @@ -274,7 +272,7 @@ parse species reference (-s) and run DP // start DamageProfiler damageProfiler = new DamageProfiler(specieHandler); - damageProfiler.init(file, + damageProfiler.init(new File(input), new File(reference), threshold, length, @@ -282,10 +280,13 @@ parse species reference (-s) and run DP LOG); damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); speciesListParser.setLOG(LOG); - generateOutput(damageProfiler, output_folder, inputfileNameWithOutExtension, null, ssLibProtocolUsed); + + } + generateOutput(); + // print runtime long currtime_post_execution = System.currentTimeMillis(); @@ -303,6 +304,15 @@ parse species reference (-s) and run DP } + private void initPlot() { + if (communicator.getTitle_plots() == null) { + inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); + } else { + inputfileNameWithOutExtension = communicator.getTitle_plots(); + } + + } + private void initLogger(String outfolder, String log) { logClass = new LogClass(); @@ -311,24 +321,18 @@ private void initLogger(String outfolder, String log) { LOG = logClass.getLogger(this.getClass()); System.out.println("DamageProfiler v" + VERSION); - LOG.info("DamageProfiler v" + VERSION); LOG.info(log); } - private void generateOutput( - DamageProfiler damageProfiler, - String output_folder, - String inputfileNameWithOutExtension, - String spe, - boolean ssLibProtocolUsed) throws IOException, DocumentException { + private void generateOutput() throws IOException, DocumentException { if (damageProfiler.getNumberOfUsedReads() != 0) { outputGenerator = new OutputGenerator( output_folder, damageProfiler, - spe, + speciesname, threshold, length, height_damageplot, @@ -381,6 +385,8 @@ private void generateOutput( } } + + /** * create output folder. * Save all files in subfolder, which has the same name as the input file @@ -389,7 +395,7 @@ private void generateOutput( * @param path * @throws IOException */ - private static String createOutputFolder(String path, String inputfileNameWithOutExtension) { + private void createOutputFolder(String path, String inputfileNameWithOutExtension) { // use Pattern.quote(File.separator) to split file path File f = new File(path + File.separator + inputfileNameWithOutExtension); @@ -399,7 +405,7 @@ private static String createOutputFolder(String path, String inputfileNameWithOu f.mkdirs(); } - return f.getAbsolutePath(); + this.output_folder = f.getAbsolutePath(); } @@ -411,10 +417,6 @@ public void setCalculationsDone(boolean calculationsDone) { this.calculationsDone = calculationsDone; } - public DamageProfiler getDamageProfiler(){ - return damageProfiler; - } - public OutputGenerator getOutputGenerator() { return outputGenerator; } diff --git a/src/main/java/controller/DamageProfilerMainController.java b/src/main/java/controller/DamageProfilerMainController.java index 3a0b1a0..c667a98 100644 --- a/src/main/java/controller/DamageProfilerMainController.java +++ b/src/main/java/controller/DamageProfilerMainController.java @@ -1,12 +1,10 @@ package controller; import GUI.*; +import GUI.Dialogues.AdvancedPlottingOptionsDialogue; import GUI.Dialogues.HelpDialogue; import GUI.Dialogues.RunInfoDialogue; import GUI.Dialogues.RuntimeEstimatorDialogue; -import GUI.Plots.DamagePlot; -import GUI.Plots.IdentityHistPlot; -import GUI.Plots.LengthDistPlot; import IO.Communicator; import calculations.RuntimeEstimator; import calculations.StartCalculations; @@ -16,13 +14,11 @@ import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.control.*; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.text.Font; +import javafx.scene.paint.Color; import javafx.util.Duration; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.fx.ChartViewer; -import javax.swing.*; import java.lang.reflect.Field; public class DamageProfilerMainController { @@ -35,6 +31,7 @@ public class DamageProfilerMainController { private final Button btn_estimate_runtime; private final Button btn_help; private final HelpDialogue help_dialogue; + private final AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue; private RunInfoDialogue runInfoDialogue; private Communicator communicator; private Button btn_inputfile; @@ -52,13 +49,13 @@ public class DamageProfilerMainController { private StartCalculations starter = new StartCalculations(); private DamageProfilerMainGUI mainGUI; private RuntimeEstimatorDialogue runtimeInfoDialogue; - /** * Constructor * @param damageProfilerMainGUI * @param progressBarController */ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, ProgressBarController progressBarController){ + this.mainGUI = damageProfilerMainGUI; this.progressBarController = progressBarController; this.communicator = mainGUI.getCommunicator(); @@ -86,7 +83,11 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.checkbox_use_merged_reads = mainGUI.getConfig_dialogue().getCheckbox_use_merged_reads(); this.checkbox_ssLibs_protocol = mainGUI.getConfig_dialogue().getCheckbox_ssLibs_protocol(); - //this.checkbox_dynamic_y_axis_height = mainGUI.getConfig_dialogue().get??; + + + // attributes of advanced plotting settings + this.advancedPlottingOptionsDialogue = this.mainGUI.getConfig_dialogue().getAdvancedPlottingOptionsDialogue(); + runtimeInfoDialogue = new RuntimeEstimatorDialogue("Runtime information", "This gives you an estimate of the runtime. For large files with a long runtime,\n" + @@ -94,6 +95,24 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, addListener(); + addListenerAdvPlotting(); + } + + private void addListenerAdvPlotting() { + + Color color_c_to_t = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_C_to_T().getValue(); + Color color_g_to_a = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_G_to_A().getValue(); + Color color_insertions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_insertions().getValue(); + Color color_deletions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue(); + Color color_other = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue(); + + // set colors in communicator + communicator.setColor_DP_C_to_T(color_c_to_t); + communicator.setColor_DP_G_to_A(color_g_to_a); + communicator.setColor_DP_insertions(color_insertions); + communicator.setColor_DP_deletions(color_deletions); + communicator.setColor_DP_other(color_other); + } private void addListener() { @@ -319,23 +338,62 @@ protected Object call() throws Exception { */ private void generateLengthDist() { - LengthDistPlot lengthDistPlot = new LengthDistPlot(starter.getDamageProfiler()); - mainGUI.getRoot().setCenter(lengthDistPlot.getBc()); + + JFreeChart[] lengthCharts = starter.getOutputGenerator().getLengthDistPlots(); + + TabPane tabPane_lengthDist = new TabPane(); + Tab allData = new Tab("All data"); + Tab splitData = new Tab("Forward vs. Reverse"); + + ChartViewer viewerLengthAll = new ChartViewer(lengthCharts[0]); + ChartViewer viewerLengthSep = new ChartViewer(lengthCharts[1]); + + // disable zoom on x-axis + viewerLengthAll.getCanvas().setDomainZoomable(false); + viewerLengthAll.getCanvas().setDomainZoomable(false); + + allData.setContent(viewerLengthAll); + splitData.setContent(viewerLengthSep); + + tabPane_lengthDist.getTabs().addAll(allData, splitData); + + mainGUI.getRoot().setCenter(tabPane_lengthDist); } private void generateIdentityDist() { - IdentityHistPlot identityHistPlot = new IdentityHistPlot(starter.getDamageProfiler().getIdentity()); - mainGUI.getRoot().setCenter(identityHistPlot.getBarChart()); + ChartViewer viewerEditDistance = new ChartViewer(starter.getOutputGenerator().getEditDist_chart()); + mainGUI.getRoot().setCenter(viewerEditDistance); } private void generateDamageProfile() { - DamagePlot damagePlot = new DamagePlot(starter.getOutputGenerator(), starter); - HBox dp_plots = damagePlot.getDamageProfile(); - dp_plots.prefHeightProperty().bind(mainGUI.getRoot().heightProperty()); - dp_plots.prefWidthProperty().bind(mainGUI.getRoot().widthProperty()); - mainGUI.getRoot().setCenter(dp_plots); + + JFreeChart[] dpCharts = starter.getOutputGenerator().getDP_chart(); + if(dpCharts.length==1){ + ChartViewer viewer5prime = new ChartViewer(dpCharts[0]); + viewer5prime.getCanvas().setDomainZoomable(false); + mainGUI.getRoot().setCenter(viewer5prime); + } else if(dpCharts.length == 2){ + + TabPane tabPane_damagePlot = new TabPane(); + Tab fivePrime = new Tab("5'end"); + Tab threePrime = new Tab("3'end"); + + ChartViewer viewer5prime = new ChartViewer(dpCharts[0]); + ChartViewer viewer3prime = new ChartViewer(dpCharts[1]); + + // disable zoom on x-axis + viewer5prime.getCanvas().setDomainZoomable(false); + viewer3prime.getCanvas().setDomainZoomable(false); + + fivePrime.setContent(viewer5prime); + threePrime.setContent(viewer3prime); + + tabPane_damagePlot.getTabs().addAll(fivePrime, threePrime); + + mainGUI.getRoot().setCenter(tabPane_damagePlot); + } } diff --git a/src/main/java/controller/TabPaneAdvPlottingController.java b/src/main/java/controller/TabPaneAdvPlottingController.java new file mode 100644 index 0000000..763a62e --- /dev/null +++ b/src/main/java/controller/TabPaneAdvPlottingController.java @@ -0,0 +1,4 @@ +package controller; + +public class TabPaneAdvPlottingController { +} From ed429ee1782e7b3d5297419ed3e91cbd4c964193 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Wed, 6 May 2020 14:01:05 +0200 Subject: [PATCH 12/22] User can choose color for plots --- build.gradle | 0 src/main/java/GUI/DamageProfilerMainGUI.java | 0 .../GUI/Dialogues/AbstractApplication.java | 0 .../java/GUI/Dialogues/AbstractDialogue.java | 0 .../AdvancedCalculationOptionsDialogue.java | 0 .../AdvancedPlottingOptionsDialogue.java | 0 .../java/GUI/Dialogues/ColorPickerPane.java | 1 - .../GUI/Dialogues/ConfigurationDialogue.java | 0 src/main/java/GUI/Dialogues/HelpDialogue.java | 0 .../java/GUI/Dialogues/RunInfoDialogue.java | 0 .../Dialogues/RuntimeEstimatorDialogue.java | 0 .../TabAdvancedSettingsDamagePlot.java | 40 +++++-- .../TabAdvancedSettingsEditdistance.java | 0 ...TabAdvancedSettingsLengthDistribution.java | 0 src/main/java/IO/FastACacher.java | 2 +- src/main/java/IO/OutputGenerator.java | 27 ++++- src/main/java/IO/PDFoutput/LinePlot.java | 54 +++++++--- src/main/java/IO/UserOptionsParser.java | 5 +- src/main/java/RunDamageProfiler.java | 0 src/main/java/StarterCLI.java | 0 .../java/calculations/DamageProfiler.java | 98 +++++++++++------- .../java/calculations/RuntimeEstimator.java | 19 +++- .../java/calculations/StartCalculations.java | 31 +++++- .../DamageProfilerMainController.java | 19 ++-- .../controller/ProgressBarController.java | 0 .../TabPaneAdvPlottingController.java | 0 src/main/resources/logo.png | Bin 27 files changed, 213 insertions(+), 83 deletions(-) mode change 100644 => 100755 build.gradle mode change 100644 => 100755 src/main/java/GUI/DamageProfilerMainGUI.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/AbstractApplication.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/AbstractDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/ColorPickerPane.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/ConfigurationDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/HelpDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/RunInfoDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java mode change 100644 => 100755 src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java mode change 100644 => 100755 src/main/java/RunDamageProfiler.java mode change 100644 => 100755 src/main/java/StarterCLI.java mode change 100644 => 100755 src/main/java/calculations/RuntimeEstimator.java mode change 100644 => 100755 src/main/java/calculations/StartCalculations.java mode change 100644 => 100755 src/main/java/controller/DamageProfilerMainController.java mode change 100644 => 100755 src/main/java/controller/ProgressBarController.java mode change 100644 => 100755 src/main/java/controller/TabPaneAdvPlottingController.java mode change 100644 => 100755 src/main/resources/logo.png diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/GUI/DamageProfilerMainGUI.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/AbstractApplication.java b/src/main/java/GUI/Dialogues/AbstractApplication.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/AbstractDialogue.java b/src/main/java/GUI/Dialogues/AbstractDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java b/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java b/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/ColorPickerPane.java b/src/main/java/GUI/Dialogues/ColorPickerPane.java old mode 100644 new mode 100755 index 38b8eb2..fb117dc --- a/src/main/java/GUI/Dialogues/ColorPickerPane.java +++ b/src/main/java/GUI/Dialogues/ColorPickerPane.java @@ -1,6 +1,5 @@ package GUI.Dialogues; -import javafx.scene.Node; import javafx.scene.control.ColorPicker; import javafx.scene.paint.Color; diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/HelpDialogue.java b/src/main/java/GUI/Dialogues/HelpDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/RunInfoDialogue.java b/src/main/java/GUI/Dialogues/RunInfoDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java b/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java old mode 100644 new mode 100755 index 2c29175..16d8388 --- a/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java +++ b/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java @@ -17,27 +17,47 @@ public class TabAdvancedSettingsDamagePlot { private ColorPicker colorPicker_insertions; private ColorPicker colorPicker_deletions; private ColorPicker colorPicker_others; + private Button btn_reset; + private GridPane gridpane; public TabAdvancedSettingsDamagePlot(String title){ this.tab = new Tab(title); - fill(); + btn_reset = new Button("Reset"); + fill( generateColorPicker(Color.RED), + generateColorPicker(Color.BLUE), + generateColorPicker(Color.valueOf("FF00FF")), + generateColorPicker(Color.GREEN), + generateColorPicker(Color.GREY)); + + addListener(); + } + + private void addListener() { + this.btn_reset.setOnAction(e ->{ + gridpane.getChildren().clear(); + fill( generateColorPicker(Color.RED), + generateColorPicker(Color.BLUE), + generateColorPicker(Color.valueOf("FF00FF")), + generateColorPicker(Color.GREEN), + generateColorPicker(Color.GREY)); + }); } - private void fill() { - GridPane gridpane = new GridPane(); + private void fill(ColorPicker c_t, ColorPicker g_a, ColorPicker insertions, ColorPicker deletions, ColorPicker others) { + gridpane = new GridPane(); gridpane.setAlignment(Pos.BOTTOM_LEFT); gridpane.setHgap(7); gridpane.setVgap(7); gridpane.setPadding(new Insets(10,10,10,10)); - Button btn_reset = new Button("Reset"); - colorPicker_C_to_T = generateColorPicker(Color.RED); - colorPicker_G_to_A = generateColorPicker(Color.BLUE); - colorPicker_insertions = generateColorPicker(Color.valueOf("FF00FF")); - colorPicker_deletions = generateColorPicker(Color.GREEN); - colorPicker_others = generateColorPicker(Color.GREY); + + colorPicker_C_to_T = c_t; + colorPicker_G_to_A = g_a; + colorPicker_insertions = insertions; + colorPicker_deletions = deletions; + colorPicker_others = others; gridpane.add(new Label("C->T"), 0,0,1,1); gridpane.add(colorPicker_C_to_T, 0,1,1,1); @@ -63,7 +83,6 @@ private void fill() { private ColorPicker generateColorPicker(Color color) { ColorPickerPane colorPickerPane = new ColorPickerPane(color); return colorPickerPane.getPicker(); - } public Tab getTab() { @@ -89,4 +108,5 @@ public ColorPicker getColorPicker_deletions() { public ColorPicker getColorPicker_others() { return colorPicker_others; } + } diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java old mode 100644 new mode 100755 diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java b/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java old mode 100644 new mode 100755 diff --git a/src/main/java/IO/FastACacher.java b/src/main/java/IO/FastACacher.java index 99c8929..d6304c9 100755 --- a/src/main/java/IO/FastACacher.java +++ b/src/main/java/IO/FastACacher.java @@ -14,7 +14,7 @@ public class FastACacher { private final Logger LOG; private HashMap<String,byte[]> data = new HashMap<>(); - public FastACacher(File f, Logger LOG) throws FileNotFoundException { + public FastACacher(File f, Logger LOG) { ReferenceSequenceFile refSeq = ReferenceSequenceFileFactory.getReferenceSequenceFile(f); this.LOG = LOG; diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index fd43813..a04d3d5 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -12,6 +12,7 @@ import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.PdfWriter; +import javafx.scene.paint.Color; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.log4j.Logger; import org.jfree.chart.JFreeChart; @@ -64,11 +65,19 @@ public class OutputGenerator { private JFreeChart length_chart_separated; private JFreeChart editDist_chart; + private Color color_DP_C_to_T; + private Color color_DP_G_to_A; + private Color color_DP_insertions; + private Color color_DP_deletions; + private Color color_DP_other; + public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, - int numberOfRecords, boolean ssLibProtocolUsed) { + int numberOfRecords, boolean ssLibProtocolUsed, Color color_DP_C_to_T, + Color color_DP_deletions, Color color_DP_G_to_A, Color color_DP_insertions, + Color color_DP_other) { this.outpath = outputFolder; this.frequencies = damageProfiler.getFrequencies(); @@ -86,6 +95,14 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.numberOfRecords = numberOfRecords; this.ssLibProtocolUsed = ssLibProtocolUsed; + this.color_DP_C_to_T = color_DP_C_to_T; + this.color_DP_deletions = color_DP_deletions; + this.color_DP_G_to_A = color_DP_G_to_A; + this.color_DP_other = color_DP_other; + this.color_DP_insertions = color_DP_insertions; + + + // set tax id if specified by user if(specie != null && !specie.equals("")){ this.specie = specie; @@ -766,7 +783,8 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep // create plots if(!ssLibProtocolUsed){ - damagePlot_three = new LinePlot("3' end", threshold, height, LOG); + damagePlot_three = new LinePlot("3' end", threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, + color_DP_insertions, color_DP_deletions, color_DP_other); // three prime end // red @@ -800,7 +818,8 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep } - LinePlot damagePlot_five = new LinePlot("5' end", threshold, height, LOG); + LinePlot damagePlot_five = new LinePlot("5' end", threshold, height, LOG, color_DP_C_to_T, + color_DP_G_to_A, color_DP_insertions, color_DP_deletions, color_DP_other); /* add data to plots @@ -961,7 +980,7 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws document.open(); // compute percentage of used reads - double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / numberOfRecords; + double ratio_used_reads = damageProfiler.getNumberOfUsedReads() / (double)numberOfRecords; // draw text String[] splitted = file.split("/"); diff --git a/src/main/java/IO/PDFoutput/LinePlot.java b/src/main/java/IO/PDFoutput/LinePlot.java index ee871fa..c2d833f 100755 --- a/src/main/java/IO/PDFoutput/LinePlot.java +++ b/src/main/java/IO/PDFoutput/LinePlot.java @@ -30,14 +30,43 @@ public class LinePlot { private String title; private int threshold; + private Color awtColor_DP_C_to_T; + private Color awtColor_DP_G_to_A; + private Color awtColor_DP_insertions; + private Color awtColor_DP_deletions; + private Color awtColor_DP_other; - public LinePlot(String title, int threshold, double height, Logger LOG) { + + public LinePlot(String title, int threshold, double height, Logger LOG, javafx.scene.paint.Color color_DP_C_to_T, + javafx.scene.paint.Color color_DP_G_to_A, javafx.scene.paint.Color color_DP_insertions, + javafx.scene.paint.Color color_DP_deletions, javafx.scene.paint.Color color_DP_other) { this.LOG = LOG; all_data = new ArrayList<>(); this.title = title; this.threshold = threshold; this.height = height; + awtColor_DP_C_to_T = new java.awt.Color((float) color_DP_C_to_T.getRed(), + (float) color_DP_C_to_T.getGreen(), + (float) color_DP_C_to_T.getBlue(), + (float) color_DP_C_to_T.getOpacity()); + awtColor_DP_G_to_A = new java.awt.Color((float) color_DP_G_to_A.getRed(), + (float) color_DP_G_to_A.getGreen(), + (float) color_DP_G_to_A.getBlue(), + (float) color_DP_G_to_A.getOpacity()); + awtColor_DP_insertions = new java.awt.Color((float) color_DP_insertions.getRed(), + (float) color_DP_insertions.getGreen(), + (float) color_DP_insertions.getBlue(), + (float) color_DP_insertions.getOpacity()); + awtColor_DP_deletions = new java.awt.Color((float) color_DP_deletions.getRed(), + (float) color_DP_deletions.getGreen(), + (float) color_DP_deletions.getBlue(), + (float) color_DP_deletions.getOpacity()); + awtColor_DP_other = new java.awt.Color((float) color_DP_other.getRed(), + (float) color_DP_other.getGreen(), + (float) color_DP_other.getBlue(), + (float) color_DP_other.getOpacity()); + } @@ -127,11 +156,12 @@ public JFreeChart createChart(final XYDataset dataset, double yMax, int threshol legendItemsNew.add(legendItemsOld.get(3)); legendItemsNew.add(legendItemsOld.get(4)); - legendItemsNew.get(0).setLinePaint(Color.RED); - legendItemsNew.get(1).setLinePaint(Color.BLUE); - legendItemsNew.get(2).setLinePaint(new Color(255, 0, 255)); - legendItemsNew.get(3).setLinePaint(Color.GREEN); - legendItemsNew.get(4).setLinePaint(Color.GRAY); + //legendItemsNew.get(0).setLinePaint(Color.RED); + legendItemsNew.get(0).setLinePaint(this.awtColor_DP_C_to_T); + legendItemsNew.get(1).setLinePaint(this.awtColor_DP_G_to_A); + legendItemsNew.get(2).setLinePaint(this.awtColor_DP_insertions); + legendItemsNew.get(3).setLinePaint(this.awtColor_DP_deletions); + legendItemsNew.get(4).setLinePaint(this.awtColor_DP_other); renderer.setSeriesStroke(0, new BasicStroke(3.0f)); renderer.setSeriesStroke(1, new BasicStroke(3.0f)); @@ -140,13 +170,13 @@ public JFreeChart createChart(final XYDataset dataset, double yMax, int threshol plot.setFixedLegendItems(legendItemsNew); // set colour of line - renderer.setSeriesPaint(0, Color.RED); - renderer.setSeriesPaint(1, Color.BLUE); - renderer.setSeriesPaint(2, new Color(255, 0, 255)); - renderer.setSeriesPaint(3, Color.GREEN); - renderer.setSeriesPaint(4, Color.GRAY); + renderer.setSeriesPaint(0, this.awtColor_DP_C_to_T); + renderer.setSeriesPaint(1, this.awtColor_DP_G_to_A); + renderer.setSeriesPaint(2, this.awtColor_DP_insertions); + renderer.setSeriesPaint(3, this.awtColor_DP_deletions); + renderer.setSeriesPaint(4, this.awtColor_DP_other); for(int i=5; i < all_data.size(); i++){ - renderer.setSeriesPaint(i, Color.GRAY); + renderer.setSeriesPaint(i, this.awtColor_DP_other); } plot.setRenderer(renderer); diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index c119f7d..baf7fd8 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -127,8 +127,9 @@ private void parse() { // others options.addOption(Option.builder("only_merged") - .desc("Use only mapped and merged reads to calculate damage plot instead of using all mapped reads. The SAM/BAM entry must start with 'M_', otherwise " + - " it will be skipped. Default: false ") + .desc("Use only mapped and merged (in case of paired-end sequencing) reads to calculate damage plot " + + "instead of using all mapped reads. The SAM/BAM entry must start with 'M_', otherwise " + + "it will be skipped. Default: false ") .build()); options.addOption(Option.builder("ssLib") diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java old mode 100644 new mode 100755 diff --git a/src/main/java/StarterCLI.java b/src/main/java/StarterCLI.java old mode 100644 new mode 100755 diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index a6f865f..e1d25ea 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -3,7 +3,6 @@ import IO.FastACacher; import htsjdk.samtools.*; -import htsjdk.samtools.reference.IndexedFastaSequenceFile; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; @@ -16,31 +15,30 @@ */ public class DamageProfiler { + private final FastACacher cache; private SamReader inputSam=null; private Functions useful_functions=null; private String specie=null; private Logger LOG=null; - private IndexedFastaSequenceFile fastaSequenceFile; private int numberOfUsedReads; private int numberOfRecords; private int threshold; private int length; private Frequencies frequencies; private File reference; - private FastACacher cache; LengthDistribution lengthDistribution; private ArrayList<Double> identity; private SpecieHandler specieHandler; - private long actualRuntime=0; - private long runtime_ms; private List<Integer> editDistances; /** * constructor * @param specieHandler + * @param cache */ - public DamageProfiler(SpecieHandler specieHandler) { + public DamageProfiler(SpecieHandler specieHandler, FastACacher cache) { this.specieHandler = specieHandler; + this.cache = cache; } @@ -68,7 +66,6 @@ public void init(File input, File reference, int threshold, int length, String s validationStringency(ValidationStringency.LENIENT).open(input); } else if(input.getAbsolutePath().endsWith(".cram")){ - System.out.println(reference.getName()); if(!reference.isFile()){ System.err.println("Reference file is needed to reads CRAM files."); System.exit(1); @@ -93,6 +90,20 @@ public void init(File input, File reference, int threshold, int length, String s this.specie = specie; useful_functions = new Functions(this.LOG); + // number of records in file: + //numberOfRecords = inputSam.iterator().toList().size(); + // estimate number of records in file: + double bytes = input.length(); + double kilobytes = (bytes / 1024); + double megabytes = (kilobytes / 1024); + double gigabytes = (megabytes / 1024); + + double sizeSamRecordInBytes = 50; + + double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; + System.out.println("Estimated number of records to process: " + Math.round(estimatedNumberOfRecords)); + + } catch (Exception e){ System.err.println("Invalid SAM/BAM file. Please check your file."); @@ -122,9 +133,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } else { - // measure runtime - long startTime = System.currentTimeMillis(); - for(SAMRecord record : inputSam) { numberOfRecords++; @@ -133,21 +141,11 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea handleRecord(use_only_merged_reads, use_all_reads, record); - // print number of processed reads - if (numberOfUsedReads % 100 == 0) { - LOG.info(numberOfUsedReads + " Reads processed."); - } - } else { if (record.getReferenceName().contains(this.specie)) { handleRecord(use_only_merged_reads, use_all_reads, record); - - // print number of processed reads - if (numberOfUsedReads % 100 == 0) { - LOG.info(numberOfUsedReads + " Reads processed."); - } } } @@ -157,6 +155,8 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea LOG.info("-------------------"); LOG.info("# reads used for damage calculation: " + (numberOfUsedReads )); + System.out.println(numberOfRecords + " Reads in total"); + //System.out.println(numberOfUsedReads + " Reads used for calculations"); } } @@ -198,9 +198,15 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, * @throws IOException */ - private void processRecord(SAMRecord record) throws Exception{ + private void processRecord(SAMRecord record) { numberOfUsedReads++; + // print number of processed reads + //if (numberOfUsedReads % 10000 == 0) { + //LOG.info(numberOfUsedReads + " Reads used."); + //System.out.println(numberOfUsedReads + " Reads used."); + //} + /* If MD value is set, use it to reconstruct reference Otherwise reconstruct it based on reference. @@ -221,20 +227,49 @@ private void processRecord(SAMRecord record) throws Exception{ // MD tag needs to be calculated --> REF needs to be specified if (record.getStringAttribute(SAMTag.MD.name()) == null){ + if(!reference.isFile()){ System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag calculations."); System.exit(1); } - readReferenceInCache(); SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, true); + } - byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); - reference_aligned = new String(ref_seq, "UTF-8"); - record_aligned = record.getReadString(); + try{ + + byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); + reference_aligned = new String(ref_seq, "UTF-8"); + record_aligned = record.getReadString(); + proceed(record, record_aligned, reference_aligned); + + } catch (Exception e){ + + System.err.println(record.getReadName() + "\nMD and NM value will be re-calculated. Error: \n" + e); + if(!reference.isFile()){ + System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag calculations."); + System.exit(1); + } + + try{ + SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, true); + byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); + reference_aligned = new String(ref_seq, "UTF-8"); + record_aligned = record.getReadString(); + proceed(record, record_aligned, reference_aligned); + System.err.println("Re-calculation was successful!\n"); + + } catch (Exception e1){ + System.err.println("Re-calculation failed. Record " + record.getReadName() + " will be skipped.\n"); + } + + } } + } + + private void proceed(SAMRecord record, String record_aligned, String reference_aligned) throws Exception { // report length distribution this.lengthDistribution.fillDistributionTable(record,record_aligned); @@ -257,20 +292,7 @@ private void processRecord(SAMRecord record) throws Exception{ } - /** - * index reference file and put it in cache to get faster - * access - * - * @throws FileNotFoundException - */ - - private void readReferenceInCache() throws FileNotFoundException{ - // read reference file as indexed reference - fastaSequenceFile = new IndexedFastaSequenceFile(reference); - // store reference in cache to get faster access - cache = new FastACacher(reference, LOG); - } diff --git a/src/main/java/calculations/RuntimeEstimator.java b/src/main/java/calculations/RuntimeEstimator.java old mode 100644 new mode 100755 index 36e76fd..a213a1e --- a/src/main/java/calculations/RuntimeEstimator.java +++ b/src/main/java/calculations/RuntimeEstimator.java @@ -17,7 +17,7 @@ public RuntimeEstimator(String inputfile){ input = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). validationStringency(ValidationStringency.LENIENT).open(new File(inputfile)); - estimate(); + estimate(inputfile); } @@ -25,10 +25,23 @@ public RuntimeEstimator(String inputfile){ * Estimate runtime based on the time needed in previous runs and the number of reads in the * current input file. * + * @param inputfile */ - public void estimate() { + public void estimate(String inputfile) { // estimate runtime: - numberOfRecords = input.iterator().toList().size(); + + double bytes = new File (inputfile).length(); + double kilobytes = (bytes / 1024); + double megabytes = (kilobytes / 1024); + double gigabytes = (megabytes / 1024); + + double sizeSamRecordInBytes = 50; + + double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; + System.out.println("Estimated number of records to process: " + estimatedNumberOfRecords); + +// numberOfRecords = input.iterator().toList().size(); + numberOfRecords = (long)estimatedNumberOfRecords; System.out.println("Number of records to process: " + numberOfRecords); estimatedRuntimeInSeconds = (long) (numberOfRecords/100000 * timePer100000RecordsInSeconds); diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java old mode 100644 new mode 100755 index e289dfb..bb19e95 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -3,11 +3,13 @@ import IO.*; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.itextpdf.text.DocumentException; +import htsjdk.samtools.reference.IndexedFastaSequenceFile; import javafx.scene.paint.Color; import org.apache.log4j.*; @@ -45,6 +47,9 @@ public class StartCalculations { private OutputGenerator outputGenerator; private String inputfileNameWithOutExtension; private Communicator communicator; + private IndexedFastaSequenceFile fastaSequenceFile; + private FastACacher cache; + // plot settings @@ -101,6 +106,9 @@ public void start(Communicator c) throws Exception { ); + if(!this.reference.equals("")) + readReferenceInCache(); + if(specieslist_filepath != null){ /* @@ -117,7 +125,7 @@ parse species references (-sf) and run DP for each reference in the file // start DamageProfiler - damageProfiler = new DamageProfiler(specieHandler); + damageProfiler = new DamageProfiler(specieHandler, cache); String ref = specie_input_string.split("\\|")[0].trim(); @@ -174,7 +182,7 @@ parse species references (-sf) and run DP for each reference in the file // start DamageProfiler damageProfiler = new DamageProfiler( - specieHandler); + specieHandler, cache); /* parse species reference (-s) and run DP @@ -270,7 +278,7 @@ parse species reference (-s) and run DP // start DamageProfiler - damageProfiler = new DamageProfiler(specieHandler); + damageProfiler = new DamageProfiler(specieHandler, cache); damageProfiler.init(new File(input), new File(reference), @@ -343,7 +351,8 @@ private void generateOutput() throws IOException, DocumentException { input, LOG, damageProfiler.getNumberOfRecords(), - ssLibProtocolUsed + ssLibProtocolUsed, + color_DP_C_to_T, color_DP_deletions, color_DP_G_to_A, color_DP_insertions, color_DP_other ); outputGenerator.writeLengthDistribution(); @@ -408,6 +417,20 @@ private void createOutputFolder(String path, String inputfileNameWithOutExtensio this.output_folder = f.getAbsolutePath(); } + /** + * index reference file and put it in cache to get faster + * access + * + * @throws FileNotFoundException + */ + + private void readReferenceInCache() throws FileNotFoundException{ + // read reference file as indexed reference + fastaSequenceFile = new IndexedFastaSequenceFile(new File(this.reference)); + // store reference in cache to get faster access + cache = new FastACacher(new File(reference), LOG); + + } public boolean isCalculationsDone() { return calculationsDone; diff --git a/src/main/java/controller/DamageProfilerMainController.java b/src/main/java/controller/DamageProfilerMainController.java old mode 100644 new mode 100755 index c667a98..317899d --- a/src/main/java/controller/DamageProfilerMainController.java +++ b/src/main/java/controller/DamageProfilerMainController.java @@ -93,12 +93,12 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, "This gives you an estimate of the runtime. For large files with a long runtime,\n" + "it's recommended to use the command line version of DamageProfiler."); + setColorsPlotting(); addListener(); - addListenerAdvPlotting(); } - private void addListenerAdvPlotting() { + private void setColorsPlotting() { Color color_c_to_t = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_C_to_T().getValue(); Color color_g_to_a = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_G_to_A().getValue(); @@ -106,16 +106,11 @@ private void addListenerAdvPlotting() { Color color_deletions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue(); Color color_other = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue(); - // set colors in communicator - communicator.setColor_DP_C_to_T(color_c_to_t); - communicator.setColor_DP_G_to_A(color_g_to_a); - communicator.setColor_DP_insertions(color_insertions); - communicator.setColor_DP_deletions(color_deletions); - communicator.setColor_DP_other(color_other); } private void addListener() { + btn_inputfile.setOnAction(e -> { BamFileChooser fqfc = new BamFileChooser(communicator); @@ -292,6 +287,14 @@ private void runDamageProfiler() { communicator.setyAxis_damageplot(Double.parseDouble(textfield_y_axis_height.getText())); communicator.setTitle_plots(textfield_title.getText()); + // set colors + communicator.setColor_DP_C_to_T(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_C_to_T().getValue()); + communicator.setColor_DP_G_to_A(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_G_to_A().getValue()); + communicator.setColor_DP_insertions(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_insertions().getValue()); + communicator.setColor_DP_deletions(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue()); + communicator.setColor_DP_other(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue()); + + if(textfield_specie.getText().equals("")) communicator.setSpecies_ref_identifier(null); else diff --git a/src/main/java/controller/ProgressBarController.java b/src/main/java/controller/ProgressBarController.java old mode 100644 new mode 100755 diff --git a/src/main/java/controller/TabPaneAdvPlottingController.java b/src/main/java/controller/TabPaneAdvPlottingController.java old mode 100644 new mode 100755 diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png old mode 100644 new mode 100755 From 13f36cfcd6122dee092e7f91d3db474054e273db Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Wed, 6 May 2020 14:07:25 +0200 Subject: [PATCH 13/22] add colot option to CLI option parser --- src/main/java/IO/UserOptionsParser.java | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index baf7fd8..2313d86 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -95,6 +95,36 @@ private void parse() { .hasArg() .build()); + options.addOption(Option.builder("color_c_t") + .argName("COLOR_C_T") + .desc("DamagePlot: Color for C to T misincoporation frequency.") + .hasArg() + .build()); + + options.addOption(Option.builder("color_g_a") + .argName("COLOR_G_A") + .desc("DamagePlot: Color for G to A misincoporation frequency.") + .hasArg() + .build()); + + options.addOption(Option.builder("color_instertions") + .argName("COLOR_C_T") + .desc("DamagePlot: Color for base insertions.") + .hasArg() + .build()); + + options.addOption(Option.builder("color_deletions") + .argName("COLOR_DELETIONS") + .desc("DamagePlot: Color for base deletions.") + .hasArg() + .build()); + + options.addOption(Option.builder("color_other") + .argName("COLOR_OTHER") + .desc("DamagePlot: Color for other bases different to reference.") + .hasArg() + .build()); + // Identity plot options.addOption(Option.builder("xaxis_id_min") From c987f3db0052691792df2e2e62fad39c603c2756 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Fri, 8 May 2020 13:36:09 +0200 Subject: [PATCH 14/22] bug fixes --- build.gradle | 2 +- src/main/java/IO/Communicator.java | 10 +++++----- src/main/java/IO/UserOptionsParser.java | 4 ++-- src/main/java/RunDamageProfiler.java | 2 +- .../java/calculations/DamageProfiler.java | 20 ++++++++++--------- .../java/calculations/StartCalculations.java | 3 ++- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/build.gradle b/build.gradle index ef1da61..b0f0aa5 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group 'com.uni-tuebingen.de.it.eager.damageprofiler' -version '0.4.9' +version '0.5.0' buildscript { repositories { diff --git a/src/main/java/IO/Communicator.java b/src/main/java/IO/Communicator.java index a04fbd0..0cb7fdb 100755 --- a/src/main/java/IO/Communicator.java +++ b/src/main/java/IO/Communicator.java @@ -31,11 +31,11 @@ public class Communicator { // plot settings private String title_plots; - private Color color_DP_C_to_T; - private Color color_DP_G_to_A; - private Color color_DP_insertions; - private Color color_DP_deletions; - private Color color_DP_other; + private Color color_DP_C_to_T = Color.RED; + private Color color_DP_G_to_A = Color.BLUE; + private Color color_DP_insertions = Color.valueOf("FF00FF"); + private Color color_DP_deletions = Color.GREEN; + private Color color_DP_other = Color.GREY; public String getInput() { diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/IO/UserOptionsParser.java index 2313d86..ca80203 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/IO/UserOptionsParser.java @@ -232,8 +232,8 @@ private void parse() { communicator.setTitle_plots(cmd.getOptionValue("title")); } - if(cmd.hasOption("yaxis_damageplot")) { - communicator.setyAxis_damageplot(Double.parseDouble(cmd.getOptionValue("yaxis_damageplot"))); + if(cmd.hasOption("yaxis_dp_max")) { + communicator.setyAxis_damageplot(Double.parseDouble(cmd.getOptionValue("yaxis_dp_max"))); } if(cmd.hasOption("xaxis_histo_id_min")) { diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java index b0160ba..9da581b 100755 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -5,7 +5,7 @@ */ public class RunDamageProfiler { - private static final String VERSION = "0.4.9"; + private static final String VERSION = "0.5.0"; public static void main(String[] args) throws Exception { diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/calculations/DamageProfiler.java index e1d25ea..1f97243 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/calculations/DamageProfiler.java @@ -93,15 +93,15 @@ public void init(File input, File reference, int threshold, int length, String s // number of records in file: //numberOfRecords = inputSam.iterator().toList().size(); // estimate number of records in file: - double bytes = input.length(); - double kilobytes = (bytes / 1024); - double megabytes = (kilobytes / 1024); - double gigabytes = (megabytes / 1024); - - double sizeSamRecordInBytes = 50; - - double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; - System.out.println("Estimated number of records to process: " + Math.round(estimatedNumberOfRecords)); +// double bytes = input.length(); +// double kilobytes = (bytes / 1024); +// double megabytes = (kilobytes / 1024); +// double gigabytes = (megabytes / 1024); +// +// double sizeSamRecordInBytes = 50; +// +// double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; +// System.out.println("Estimated number of records to process: " + Math.round(estimatedNumberOfRecords)); @@ -135,6 +135,8 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea for(SAMRecord record : inputSam) { + List<SAMSequenceRecord> refs = inputSam.getFileHeader().getSequenceDictionary().getSequences(); + numberOfRecords++; if (this.specie == null) { diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/calculations/StartCalculations.java index bb19e95..5d18fb6 100755 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/calculations/StartCalculations.java @@ -36,7 +36,7 @@ public class StartCalculations { private String reference; private String outfolder; private String input; - private SpecieHandler specieHandler; + private SpecieHandler specieHandler = new SpecieHandler(); private boolean use_all_reads; private double xaxis_min_id_histogram; private double xaxis_max_id_histogram; @@ -111,6 +111,7 @@ public void start(Communicator c) throws Exception { if(specieslist_filepath != null){ + specieHandler = new SpecieHandler(); /* parse species references (-sf) and run DP for each reference in the file */ From 9665612bc02c1a2eca3389977f413e18690a74df Mon Sep 17 00:00:00 2001 From: jfy133 <jfy133@gmail.com> Date: Mon, 18 May 2020 09:29:43 +0200 Subject: [PATCH 15/22] Fix user display specie -> species --- src/main/java/GUI/Dialogues/ConfigurationDialogue.java | 2 +- src/main/java/IO/OutputGenerator.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java index ce8dfe6..80227c0 100755 --- a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/GUI/Dialogues/ConfigurationDialogue.java @@ -57,7 +57,7 @@ private void addComponents() { Label label_threshold = new Label("Number of bases (x-axis)"); Label label_yaxis = new Label("Height y-axis"); Label label_length = new Label("Set number of bases (calculations)"); - Label label_specie = new Label("Filter for specie"); + Label label_specie = new Label("Filter for species"); Label label_title = new Label("Set title"); Label label_plot = new Label("Plot"); diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/IO/OutputGenerator.java index a04d3d5..3954298 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/IO/OutputGenerator.java @@ -995,7 +995,7 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads)"; } else{ read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Specie: " + this.specie; + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Species: " + this.specie; } } else { @@ -1004,7 +1004,7 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | ssLib protocol"; } else { read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Specie: " + this.specie + " | ssLib protocol"; + (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Species: " + this.specie + " | ssLib protocol"; } } From fe799b722f6dffb3348aa523b5bf8d2f5fffff11 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Fri, 19 Jun 2020 18:54:22 +0200 Subject: [PATCH 16/22] can now be compiled with Java11 --- LICENSE | 2 +- README.md | 2 +- build.gradle | 108 +++--------------- docs/contents/generalUsage.rst | 2 +- .../damageprofiler}/GUI/BamFileChooser.java | 4 +- .../GUI/DamageProfilerMainGUI.java | 9 +- .../GUI/Dialogues/AbstractApplication.java | 2 +- .../GUI/Dialogues/AbstractDialogue.java | 2 +- .../AdvancedCalculationOptionsDialogue.java | 2 +- .../AdvancedPlottingOptionsDialogue.java | 2 +- .../GUI/Dialogues/ColorPickerPane.java | 2 +- .../GUI/Dialogues/ConfigurationDialogue.java | 17 ++- .../GUI/Dialogues/HelpDialogue.java | 2 +- .../GUI/Dialogues/RunInfoDialogue.java | 4 +- .../Dialogues/RuntimeEstimatorDialogue.java | 2 +- .../TabAdvancedSettingsDamagePlot.java | 2 +- .../TabAdvancedSettingsEditdistance.java | 2 +- ...TabAdvancedSettingsLengthDistribution.java | 2 +- .../damageprofiler}/GUI/OutputDirChooser.java | 4 +- .../GUI/ReferenceFileChooser.java | 4 +- .../GUI/SpeciesListFileChooser.java | 4 +- .../damageprofiler}/IO/Communicator.java | 2 +- .../damageprofiler}/IO/DOMParser.java | 2 +- .../damageprofiler}/IO/FastACacher.java | 3 +- .../{ => org/damageprofiler}/IO/LogClass.java | 2 +- .../damageprofiler}/IO/OutputGenerator.java | 47 +++++--- .../IO/PDFoutput/Histogram.java | 6 +- .../IO/PDFoutput/LinePlot.java | 2 +- .../{ => org/damageprofiler}/IO/Unzip.java | 2 +- .../damageprofiler}/IO/UserOptionsParser.java | 2 +- .../damageprofiler}/RunDamageProfiler.java | 4 +- .../{ => org/damageprofiler}/StarterCLI.java | 8 +- .../{ => org/damageprofiler}/StarterGUI.java | 11 +- .../calculations/DamageProfiler.java | 30 ++--- .../calculations/Frequencies.java | 2 +- .../calculations/Functions.java | 2 +- .../calculations/LengthDistribution.java | 2 +- .../calculations/RuntimeEstimator.java | 2 +- .../calculations/SpecieHandler.java | 4 +- .../calculations/SpeciesListParser.java | 2 +- .../calculations/StartCalculations.java | 8 +- .../DamageProfilerMainController.java | 42 ++++--- .../controller/ProgressBarController.java | 2 +- .../TabPaneAdvPlottingController.java | 2 +- 44 files changed, 164 insertions(+), 205 deletions(-) rename src/main/java/{ => org/damageprofiler}/GUI/BamFileChooser.java (92%) rename src/main/java/{ => org/damageprofiler}/GUI/DamageProfilerMainGUI.java (95%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/AbstractApplication.java (96%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/AbstractDialogue.java (95%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java (55%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java (97%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/ColorPickerPane.java (89%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/ConfigurationDialogue.java (92%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/HelpDialogue.java (99%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/RunInfoDialogue.java (95%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/RuntimeEstimatorDialogue.java (96%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java (98%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/TabAdvancedSettingsEditdistance.java (88%) rename src/main/java/{ => org/damageprofiler}/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java (88%) rename src/main/java/{ => org/damageprofiler}/GUI/OutputDirChooser.java (85%) rename src/main/java/{ => org/damageprofiler}/GUI/ReferenceFileChooser.java (87%) rename src/main/java/{ => org/damageprofiler}/GUI/SpeciesListFileChooser.java (83%) rename src/main/java/{ => org/damageprofiler}/IO/Communicator.java (99%) rename src/main/java/{ => org/damageprofiler}/IO/DOMParser.java (98%) rename src/main/java/{ => org/damageprofiler}/IO/FastACacher.java (95%) rename src/main/java/{ => org/damageprofiler}/IO/LogClass.java (96%) rename src/main/java/{ => org/damageprofiler}/IO/OutputGenerator.java (95%) rename src/main/java/{ => org/damageprofiler}/IO/PDFoutput/Histogram.java (92%) rename src/main/java/{ => org/damageprofiler}/IO/PDFoutput/LinePlot.java (99%) rename src/main/java/{ => org/damageprofiler}/IO/Unzip.java (96%) rename src/main/java/{ => org/damageprofiler}/IO/UserOptionsParser.java (99%) rename src/main/java/{ => org/damageprofiler}/RunDamageProfiler.java (92%) rename src/main/java/{ => org/damageprofiler}/StarterCLI.java (66%) rename src/main/java/{ => org/damageprofiler}/StarterGUI.java (76%) rename src/main/java/{ => org/damageprofiler}/calculations/DamageProfiler.java (93%) rename src/main/java/{ => org/damageprofiler}/calculations/Frequencies.java (99%) rename src/main/java/{ => org/damageprofiler}/calculations/Functions.java (97%) rename src/main/java/{ => org/damageprofiler}/calculations/LengthDistribution.java (98%) rename src/main/java/{ => org/damageprofiler}/calculations/RuntimeEstimator.java (98%) rename src/main/java/{ => org/damageprofiler}/calculations/SpecieHandler.java (97%) rename src/main/java/{ => org/damageprofiler}/calculations/SpeciesListParser.java (97%) rename src/main/java/{ => org/damageprofiler}/calculations/StartCalculations.java (98%) rename src/main/java/{ => org/damageprofiler}/controller/DamageProfilerMainController.java (93%) rename src/main/java/{ => org/damageprofiler}/controller/ProgressBarController.java (95%) rename src/main/java/{ => org/damageprofiler}/controller/TabPaneAdvPlottingController.java (54%) diff --git a/LICENSE b/LICENSE index 9cecc1d..7c057bf 100755 --- a/LICENSE +++ b/LICENSE @@ -659,7 +659,7 @@ notice like this when it starts in an interactive mode: The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". +might be different; for a org.damageprofiler.GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. diff --git a/README.md b/README.md index f2a87e7..7e114c5 100755 --- a/README.md +++ b/README.md @@ -85,6 +85,6 @@ Maximal value on y axis (Default: flexible, adapts to the calculated damage). -Running the jar file without any parameter starts a GUI to configure the run. +Running the jar file without any parameter starts a org.damageprofiler.GUI to configure the run. Stay tuned, a more detailed description, manual and tutorial of DamageProfiler is coming soon. \ No newline at end of file diff --git a/build.gradle b/build.gradle index b0f0aa5..c5f845f 100755 --- a/build.gradle +++ b/build.gradle @@ -1,113 +1,41 @@ -group 'com.uni-tuebingen.de.it.eager.damageprofiler' -version '0.5.0' - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8+' - } +plugins { + id 'application' + id 'org.openjfx.javafxplugin' version '0.0.8' + id 'org.beryx.jlink' version '2.12.0' } -allprojects { - repositories { - jcenter() - } - apply plugin: 'maven' - apply plugin: 'maven-publish' - apply plugin: 'java' - apply plugin: 'idea' - apply plugin: 'com.jfrog.bintray' - apply plugin: 'jacoco' +repositories { + mavenCentral() } -sourceCompatibility = 1.8 - - -sourceSets { - main { - java { - srcDir 'src' - } - - resources { - srcDirs "src/main/resources" - } - } -} - - - dependencies { + runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" + compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' compile group: 'commons-cli', name: 'commons-cli', version: '1.3.+' compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.+' compile group: 'com.github.samtools', name: 'htsjdk', version: '2.+' - compile group: 'com.intellij', name: 'forms_rt', version: '6.0.+' - compile group: 'log4j', name: 'log4j', version: '1.+' + compile group: 'com.intellij', name: 'forms_rt', version: '5.+' compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' compile group: 'org.jfree', name: 'jfreesvg', version: '2.0' compile group: 'org.apache.commons', name: 'commons-text', version: '1.+' compile 'org.jfree:jfreechart-fx:1.+' - - } +javafx { + version = "14" + modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics' ] +} +mainClassName = "org.damageprofiler.RunDamageProfiler" jar { manifest { - attributes("Implementation-Title": "DamageProfiler", - "Implementation-Version": version, "main-Class": "RunDamageProfiler") + attributes 'Main-Class': 'org.damageprofiler.RunDamageProfiler' } - doFirst { - from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } -} - - - - - -publishing { - publications { - MyPublication(MavenPublication) { - from components.java - groupId 'com.uni-tuebingen.de.it.eager' - artifactId 'DamageProfiler' - } - } -} - - -jacocoTestReport { - reports { - xml.enabled true - } -} - - -bintray { - user = System.getenv('BINTRAY_USER') - key = System.getenv('BINTRAY_API_KEY') - publications = ['MyPublication'] - publish = true - override = true - pkg { - repo = 'EAGER' - name = 'DamageProfiler' - licenses = ['GPL-3.0'] - vcsUrl = "https://github.com/apeltzer/DamageProfiler" - version { - name = project.version - desc = 'Damage calculations for mapped reads.' - released = new Date() - vcsTag = project.version - attributes = ['gradle-plugin': 'com.use.less:com.use.less.gradle:gradle-useless-plugin'] - } - - } -} +} \ No newline at end of file diff --git a/docs/contents/generalUsage.rst b/docs/contents/generalUsage.rst index 015c723..a65769d 100755 --- a/docs/contents/generalUsage.rst +++ b/docs/contents/generalUsage.rst @@ -40,7 +40,7 @@ Options: DamageProfiler can be used in offline mode. -Running the jar file without any parameter starts a GUI to configure the run. +Running the jar file without any parameter starts a org.damageprofiler.GUI to configure the run. Log file diff --git a/src/main/java/GUI/BamFileChooser.java b/src/main/java/org/damageprofiler/GUI/BamFileChooser.java similarity index 92% rename from src/main/java/GUI/BamFileChooser.java rename to src/main/java/org/damageprofiler/GUI/BamFileChooser.java index d66d58f..81fbd0c 100755 --- a/src/main/java/GUI/BamFileChooser.java +++ b/src/main/java/org/damageprofiler/GUI/BamFileChooser.java @@ -1,6 +1,6 @@ -package GUI; +package org.damageprofiler.GUI; -import IO.Communicator; +import org.damageprofiler.IO.Communicator; import javafx.stage.FileChooser; import javafx.stage.Stage; diff --git a/src/main/java/GUI/DamageProfilerMainGUI.java b/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java similarity index 95% rename from src/main/java/GUI/DamageProfilerMainGUI.java rename to src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java index 6c7fb9a..47b4e81 100755 --- a/src/main/java/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java @@ -1,8 +1,8 @@ -package GUI; +package org.damageprofiler.GUI; -import GUI.Dialogues.ConfigurationDialogue; -import IO.Communicator; -import controller.ProgressBarController; +import org.damageprofiler.GUI.Dialogues.ConfigurationDialogue; +import org.damageprofiler.IO.Communicator; +import org.damageprofiler.controller.ProgressBarController; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; @@ -11,6 +11,7 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; + import java.io.InputStream; public class DamageProfilerMainGUI { diff --git a/src/main/java/GUI/Dialogues/AbstractApplication.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AbstractApplication.java similarity index 96% rename from src/main/java/GUI/Dialogues/AbstractApplication.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/AbstractApplication.java index 21604d6..117d430 100755 --- a/src/main/java/GUI/Dialogues/AbstractApplication.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/AbstractApplication.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.geometry.Pos; import javafx.scene.Scene; diff --git a/src/main/java/GUI/Dialogues/AbstractDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AbstractDialogue.java similarity index 95% rename from src/main/java/GUI/Dialogues/AbstractDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/AbstractDialogue.java index 9f6df78..535f52b 100755 --- a/src/main/java/GUI/Dialogues/AbstractDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/AbstractDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.geometry.Insets; import javafx.geometry.Pos; diff --git a/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java similarity index 55% rename from src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java index 6540b46..62f87fc 100755 --- a/src/main/java/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; public class AdvancedCalculationOptionsDialogue { } diff --git a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java similarity index 97% rename from src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java index 086dc8b..8ed2f65 100755 --- a/src/main/java/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; diff --git a/src/main/java/GUI/Dialogues/ColorPickerPane.java b/src/main/java/org/damageprofiler/GUI/Dialogues/ColorPickerPane.java similarity index 89% rename from src/main/java/GUI/Dialogues/ColorPickerPane.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/ColorPickerPane.java index fb117dc..c71d232 100755 --- a/src/main/java/GUI/Dialogues/ColorPickerPane.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/ColorPickerPane.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.scene.control.ColorPicker; import javafx.scene.paint.Color; diff --git a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java similarity index 92% rename from src/main/java/GUI/Dialogues/ConfigurationDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java index ce8dfe6..8617398 100755 --- a/src/main/java/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -30,6 +30,7 @@ public class ConfigurationDialogue { private ProgressBar progressBar; private AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue; + private Button btn_loadSpecies; public ConfigurationDialogue(ProgressBar progressBar){ @@ -50,14 +51,15 @@ private void addComponents() { btn_inputfile = new Button("Select input file"); btn_reference = new Button("Select reference"); btn_output = new Button("Select output"); - btn_specieList = new Button("Set list"); + btn_specieList = new Button("Set species file"); + btn_loadSpecies = new Button("Load Species"); btn_run = new Button("Run"); btn_estimate_runtime = new Button("Estimate Runtime"); Label label_threshold = new Label("Number of bases (x-axis)"); Label label_yaxis = new Label("Height y-axis"); - Label label_length = new Label("Set number of bases (calculations)"); - Label label_specie = new Label("Filter for specie"); + Label label_length = new Label("Set number of bases (org.damageprofiler.calculations)"); + Label label_specie = new Label("Enter RefSeq ID "); Label label_title = new Label("Set title"); Label label_plot = new Label("Plot"); @@ -136,7 +138,8 @@ private void addComponents() { config_gridpane.add(checkbox_ssLibs_protocol, 0, ++row, 1,1); config_gridpane.add(label_specie, 0, ++row, 1,1); config_gridpane.add(textfield_specie, 1, row, 2,1); - config_gridpane.add(btn_specieList, 3, row, 1,1); + config_gridpane.add(btn_specieList, 1, ++row, 1,1); + //config_gridpane.add(btn_loadSpecies, 3, row, 1,1); config_gridpane.add(pane_advanced_calculation_options, 0,++row, 3,1); config_gridpane.add(new Separator(), 0, ++row,3,1); @@ -205,4 +208,8 @@ public Button getBtn_estimate_runtime() { public AdvancedPlottingOptionsDialogue getAdvancedPlottingOptionsDialogue() { return advancedPlottingOptionsDialogue; } + + public Button getBtn_loadSpecies() { + return btn_loadSpecies; + } } diff --git a/src/main/java/GUI/Dialogues/HelpDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java similarity index 99% rename from src/main/java/GUI/Dialogues/HelpDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java index c28eaad..a3ee889 100755 --- a/src/main/java/GUI/Dialogues/HelpDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.geometry.Insets; diff --git a/src/main/java/GUI/Dialogues/RunInfoDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/RunInfoDialogue.java similarity index 95% rename from src/main/java/GUI/Dialogues/RunInfoDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/RunInfoDialogue.java index 53ca676..9821f0f 100755 --- a/src/main/java/GUI/Dialogues/RunInfoDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/RunInfoDialogue.java @@ -1,6 +1,6 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; -import IO.Communicator; +import org.damageprofiler.IO.Communicator; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; diff --git a/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/RuntimeEstimatorDialogue.java similarity index 96% rename from src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/RuntimeEstimatorDialogue.java index 09f94d6..10b9e0e 100755 --- a/src/main/java/GUI/Dialogues/RuntimeEstimatorDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/RuntimeEstimatorDialogue.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.scene.control.Button; import javafx.scene.control.Label; diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java similarity index 98% rename from src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java index 16d8388..4f5bf8c 100755 --- a/src/main/java/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.geometry.Insets; import javafx.geometry.Pos; diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java similarity index 88% rename from src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java index a860808..4642b14 100755 --- a/src/main/java/GUI/Dialogues/TabAdvancedSettingsEditdistance.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.scene.control.Tab; diff --git a/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java similarity index 88% rename from src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java rename to src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java index f5548ae..e6a8daa 100755 --- a/src/main/java/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java @@ -1,4 +1,4 @@ -package GUI.Dialogues; +package org.damageprofiler.GUI.Dialogues; import javafx.scene.control.Tab; diff --git a/src/main/java/GUI/OutputDirChooser.java b/src/main/java/org/damageprofiler/GUI/OutputDirChooser.java similarity index 85% rename from src/main/java/GUI/OutputDirChooser.java rename to src/main/java/org/damageprofiler/GUI/OutputDirChooser.java index e6493c8..b9ab610 100755 --- a/src/main/java/GUI/OutputDirChooser.java +++ b/src/main/java/org/damageprofiler/GUI/OutputDirChooser.java @@ -1,6 +1,6 @@ -package GUI; +package org.damageprofiler.GUI; -import IO.Communicator; +import org.damageprofiler.IO.Communicator; import javafx.stage.DirectoryChooser; import javafx.stage.Stage; diff --git a/src/main/java/GUI/ReferenceFileChooser.java b/src/main/java/org/damageprofiler/GUI/ReferenceFileChooser.java similarity index 87% rename from src/main/java/GUI/ReferenceFileChooser.java rename to src/main/java/org/damageprofiler/GUI/ReferenceFileChooser.java index 77f6389..384df7b 100755 --- a/src/main/java/GUI/ReferenceFileChooser.java +++ b/src/main/java/org/damageprofiler/GUI/ReferenceFileChooser.java @@ -1,6 +1,6 @@ -package GUI; +package org.damageprofiler.GUI; -import IO.Communicator; +import org.damageprofiler.IO.Communicator; import javafx.stage.FileChooser; import javafx.stage.Stage; diff --git a/src/main/java/GUI/SpeciesListFileChooser.java b/src/main/java/org/damageprofiler/GUI/SpeciesListFileChooser.java similarity index 83% rename from src/main/java/GUI/SpeciesListFileChooser.java rename to src/main/java/org/damageprofiler/GUI/SpeciesListFileChooser.java index afd65c8..c33feb9 100755 --- a/src/main/java/GUI/SpeciesListFileChooser.java +++ b/src/main/java/org/damageprofiler/GUI/SpeciesListFileChooser.java @@ -1,6 +1,6 @@ -package GUI; +package org.damageprofiler.GUI; -import IO.Communicator; +import org.damageprofiler.IO.Communicator; import javafx.stage.FileChooser; import javafx.stage.Stage; diff --git a/src/main/java/IO/Communicator.java b/src/main/java/org/damageprofiler/IO/Communicator.java similarity index 99% rename from src/main/java/IO/Communicator.java rename to src/main/java/org/damageprofiler/IO/Communicator.java index 0cb7fdb..ad81a72 100755 --- a/src/main/java/IO/Communicator.java +++ b/src/main/java/org/damageprofiler/IO/Communicator.java @@ -1,4 +1,4 @@ -package IO; +package org.damageprofiler.IO; import javafx.scene.paint.Color; diff --git a/src/main/java/IO/DOMParser.java b/src/main/java/org/damageprofiler/IO/DOMParser.java similarity index 98% rename from src/main/java/IO/DOMParser.java rename to src/main/java/org/damageprofiler/IO/DOMParser.java index 71dd54b..6040e96 100755 --- a/src/main/java/IO/DOMParser.java +++ b/src/main/java/org/damageprofiler/IO/DOMParser.java @@ -1,4 +1,4 @@ -package IO; +package org.damageprofiler.IO; import org.apache.log4j.Logger; import org.w3c.dom.Document; diff --git a/src/main/java/IO/FastACacher.java b/src/main/java/org/damageprofiler/IO/FastACacher.java similarity index 95% rename from src/main/java/IO/FastACacher.java rename to src/main/java/org/damageprofiler/IO/FastACacher.java index d6304c9..8b1ddfb 100755 --- a/src/main/java/IO/FastACacher.java +++ b/src/main/java/org/damageprofiler/IO/FastACacher.java @@ -1,10 +1,9 @@ -package IO; +package org.damageprofiler.IO; import htsjdk.samtools.reference.*; import org.apache.log4j.Logger; import java.io.File; -import java.io.FileNotFoundException; import java.util.HashMap; /** diff --git a/src/main/java/IO/LogClass.java b/src/main/java/org/damageprofiler/IO/LogClass.java similarity index 96% rename from src/main/java/IO/LogClass.java rename to src/main/java/org/damageprofiler/IO/LogClass.java index b657234..458dc74 100755 --- a/src/main/java/IO/LogClass.java +++ b/src/main/java/org/damageprofiler/IO/LogClass.java @@ -1,4 +1,4 @@ -package IO; +package org.damageprofiler.IO; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; diff --git a/src/main/java/IO/OutputGenerator.java b/src/main/java/org/damageprofiler/IO/OutputGenerator.java similarity index 95% rename from src/main/java/IO/OutputGenerator.java rename to src/main/java/org/damageprofiler/IO/OutputGenerator.java index a04d3d5..76c559e 100755 --- a/src/main/java/IO/OutputGenerator.java +++ b/src/main/java/org/damageprofiler/IO/OutputGenerator.java @@ -1,9 +1,9 @@ -package IO; +package org.damageprofiler.IO; -import IO.PDFoutput.Histogram; -import IO.PDFoutput.LinePlot; -import calculations.DamageProfiler; -import calculations.Frequencies; +import org.damageprofiler.IO.PDFoutput.Histogram; +import org.damageprofiler.IO.PDFoutput.LinePlot; +import org.damageprofiler.calculations.DamageProfiler; +import org.damageprofiler.calculations.Frequencies; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.itextpdf.awt.PdfGraphics2D; @@ -152,7 +152,7 @@ public void writeLengthDistribution() throws IOException{ HashMap<Integer, Integer> map_forward = damageProfiler.getLength_distribution_map_forward(); HashMap<Integer, Integer> map_reverse = damageProfiler.getLength_distribution_map_reverse(); - lgdist.write("# table produced by calculations.DamageProfiler\n"); + lgdist.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); lgdist.write("# using mapped file " + input + "\n"); lgdist.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); lgdist.write("# Std: strand of reads\n"); @@ -208,7 +208,7 @@ public void writeDNAcomp_genome(Frequencies frequencies) throws IOException{ BufferedWriter file_dna_comp = new BufferedWriter(new FileWriter(outpath + File.separator + "DNA_comp_genome.txt")); - file_dna_comp.write("# table produced by calculations.DamageProfiler\n"); + file_dna_comp.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); file_dna_comp.write("# using mapped file " + input + "\n"); file_dna_comp.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); file_dna_comp.write("DNA base frequencies Sample\n"); @@ -256,7 +256,7 @@ public void writeDNAComp(Frequencies frequencies) throws IOException{ */ - freq_file_sample.write("# table produced by calculations.DamageProfiler\n"); + freq_file_sample.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); freq_file_sample.write("# using mapped file " + input + "\n"); freq_file_sample.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); @@ -319,7 +319,7 @@ public void writeFrequenciesReference(Frequencies frequencies) throws IOExceptio BufferedWriter freq_file_ref = new BufferedWriter(new FileWriter(outpath + File.separator + "misincorporation.txt")); - freq_file_ref.write("# table produced by calculations.DamageProfiler\n"); + freq_file_ref.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); freq_file_ref.write("# using mapped file " + input + "\n"); freq_file_ref.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); @@ -499,7 +499,7 @@ public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_f * @throws DocumentException * @throws IOException */ - public void plotIdentitiyHistogram(List<Integer> distances, String title, String file) throws DocumentException, IOException{ + public void plotEditDistanceHistogram(List<Integer> distances, String title, String file) throws DocumentException, IOException{ Histogram hist_all = new Histogram(LOG); hist_all.addData(distances); @@ -535,14 +535,14 @@ public void writeDamageFiles(double[] gToA_reverse, double[] cToT) throws IOExce if(!ssLibProtocolUsed){ writer3Prime = new BufferedWriter(new FileWriter(this.outpath + "/3pGtoA_freq.txt")); - writer3Prime.write("# table produced by calculations.DamageProfiler\n"); + writer3Prime.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); writer3Prime.write("# using mapped file " + input + "\n"); writer3Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); writeDamagePattern("pos\t3pG>A\n", getSubArray(gToA_reverse, this.threshold), writer3Prime); writer3Prime.close(); } - writer5Prime.write("# table produced by calculations.DamageProfiler\n"); + writer5Prime.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); writer5Prime.write("# using mapped file " + input + "\n"); writer5Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); writeDamagePattern("pos\t5pC>T\n", getSubArray(cToT, this.threshold), writer5Prime); @@ -608,7 +608,7 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw BufferedWriter writer5PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/5p_freq_misincorporations.txt")); - writer5PrimeAll.write("# table produced by calculations.DamageProfiler\n"); + writer5PrimeAll.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); writer5PrimeAll.write("# using mapped file " + input + "\n"); writer5PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); @@ -675,7 +675,7 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw if(!ssLibProtocolUsed){ BufferedWriter writer3PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/3p_freq_misincorporations.txt")); - writer3PrimeAll.write("# table produced by calculations.DamageProfiler\n"); + writer3PrimeAll.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); writer3PrimeAll.write("# using mapped file " + input + "\n"); writer3PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); @@ -736,6 +736,25 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw + public void writeEditDistance(List<Integer> editDistances) throws IOException { + Collections.sort(editDistances); + Set<Integer> distances_sorted = new HashSet<Integer>(editDistances); + HashMap<Integer, Integer> edit_occurrences_map = new HashMap<>(); + for(int dist : distances_sorted){ + int occurrences = Collections.frequency(editDistances, dist); + edit_occurrences_map.put(dist, occurrences); + + } + + BufferedWriter writerEditDistance = new BufferedWriter(new FileWriter(this.outpath + "/editDistance.txt")); + writerEditDistance.write("#Edit distances for file:" + input + "\n"); + writerEditDistance.write("Edit distance\tOccurrences\n"); + + for(int dist : edit_occurrences_map.keySet()) + writerEditDistance.write(dist + "\t" + edit_occurrences_map.get(dist) + "\n"); + + writerEditDistance.close(); + } /** * create damage plot diff --git a/src/main/java/IO/PDFoutput/Histogram.java b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java similarity index 92% rename from src/main/java/IO/PDFoutput/Histogram.java rename to src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java index 8a33e31..8620b5b 100755 --- a/src/main/java/IO/PDFoutput/Histogram.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java @@ -1,16 +1,12 @@ -package IO.PDFoutput; +package org.damageprofiler.IO.PDFoutput; import org.apache.log4j.Logger; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; -import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.category.BarRenderer; -import org.jfree.chart.renderer.xy.StandardXYBarPainter; import org.jfree.chart.renderer.xy.XYBarRenderer; -import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.statistics.HistogramType; diff --git a/src/main/java/IO/PDFoutput/LinePlot.java b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java similarity index 99% rename from src/main/java/IO/PDFoutput/LinePlot.java rename to src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java index c2d833f..3de9d36 100755 --- a/src/main/java/IO/PDFoutput/LinePlot.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java @@ -1,4 +1,4 @@ -package IO.PDFoutput; +package org.damageprofiler.IO.PDFoutput; import org.apache.log4j.Logger; import org.jfree.chart.ChartFactory; diff --git a/src/main/java/IO/Unzip.java b/src/main/java/org/damageprofiler/IO/Unzip.java similarity index 96% rename from src/main/java/IO/Unzip.java rename to src/main/java/org/damageprofiler/IO/Unzip.java index b8a0869..09555b2 100755 --- a/src/main/java/IO/Unzip.java +++ b/src/main/java/org/damageprofiler/IO/Unzip.java @@ -1,4 +1,4 @@ -package IO; +package org.damageprofiler.IO; import org.apache.log4j.Logger; diff --git a/src/main/java/IO/UserOptionsParser.java b/src/main/java/org/damageprofiler/IO/UserOptionsParser.java similarity index 99% rename from src/main/java/IO/UserOptionsParser.java rename to src/main/java/org/damageprofiler/IO/UserOptionsParser.java index ca80203..473abd0 100755 --- a/src/main/java/IO/UserOptionsParser.java +++ b/src/main/java/org/damageprofiler/IO/UserOptionsParser.java @@ -1,4 +1,4 @@ -package IO; +package org.damageprofiler.IO; import org.apache.commons.cli.*; diff --git a/src/main/java/RunDamageProfiler.java b/src/main/java/org/damageprofiler/RunDamageProfiler.java similarity index 92% rename from src/main/java/RunDamageProfiler.java rename to src/main/java/org/damageprofiler/RunDamageProfiler.java index 9da581b..34bda56 100755 --- a/src/main/java/RunDamageProfiler.java +++ b/src/main/java/org/damageprofiler/RunDamageProfiler.java @@ -1,3 +1,5 @@ +package org.damageprofiler; + import javafx.application.Application; /** @@ -13,7 +15,7 @@ public static void main(String[] args) throws Exception { get input parameters - $ damageprofiler : starts GUI + $ damageprofiler : starts org.damageprofiler.GUI $ damageprofiler -i <> -o <> .... : parse command line arguments diff --git a/src/main/java/StarterCLI.java b/src/main/java/org/damageprofiler/StarterCLI.java similarity index 66% rename from src/main/java/StarterCLI.java rename to src/main/java/org/damageprofiler/StarterCLI.java index 74f0b3a..cdc2ac7 100755 --- a/src/main/java/StarterCLI.java +++ b/src/main/java/org/damageprofiler/StarterCLI.java @@ -1,6 +1,8 @@ -import IO.Communicator; -import IO.UserOptionsParser; -import calculations.StartCalculations; +package org.damageprofiler; + +import org.damageprofiler.calculations.StartCalculations; +import org.damageprofiler.IO.Communicator; +import org.damageprofiler.IO.UserOptionsParser; public class StarterCLI { diff --git a/src/main/java/StarterGUI.java b/src/main/java/org/damageprofiler/StarterGUI.java similarity index 76% rename from src/main/java/StarterGUI.java rename to src/main/java/org/damageprofiler/StarterGUI.java index 84ed041..909eb29 100755 --- a/src/main/java/StarterGUI.java +++ b/src/main/java/org/damageprofiler/StarterGUI.java @@ -1,9 +1,9 @@ -import controller.DamageProfilerMainController; -import GUI.DamageProfilerMainGUI; -import controller.ProgressBarController; -import controller.TabPaneAdvPlottingController; -import javafx.application.Application; +package org.damageprofiler; +import org.damageprofiler.controller.DamageProfilerMainController; +import org.damageprofiler.GUI.DamageProfilerMainGUI; +import org.damageprofiler.controller.ProgressBarController; +import javafx.application.Application; import javafx.stage.Stage; @@ -11,7 +11,6 @@ public class StarterGUI extends Application { private static final String VERSION = "0.4.9"; - @Override public void start(Stage primaryStage) { diff --git a/src/main/java/calculations/DamageProfiler.java b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java similarity index 93% rename from src/main/java/calculations/DamageProfiler.java rename to src/main/java/org/damageprofiler/calculations/DamageProfiler.java index 1f97243..e57bc1b 100755 --- a/src/main/java/calculations/DamageProfiler.java +++ b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java @@ -1,7 +1,7 @@ -package calculations; +package org.damageprofiler.calculations; -import IO.FastACacher; +import org.damageprofiler.IO.FastACacher; import htsjdk.samtools.*; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; @@ -117,7 +117,7 @@ public void init(File input, File reference, int threshold, int length, String s /** * get all sam records of input sam/bam file, * distinguish between mapped and mapped/merged and normalize values - * after all calculations + * after all org.damageprofiler.calculations * * * @param use_only_merged_reads @@ -158,7 +158,7 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea LOG.info("-------------------"); LOG.info("# reads used for damage calculation: " + (numberOfUsedReads )); System.out.println(numberOfRecords + " Reads in total"); - //System.out.println(numberOfUsedReads + " Reads used for calculations"); + //System.out.println(numberOfUsedReads + " Reads used for org.damageprofiler.calculations"); } } @@ -204,10 +204,10 @@ private void processRecord(SAMRecord record) { numberOfUsedReads++; // print number of processed reads - //if (numberOfUsedReads % 10000 == 0) { - //LOG.info(numberOfUsedReads + " Reads used."); - //System.out.println(numberOfUsedReads + " Reads used."); - //} + if (numberOfUsedReads % 10000 == 0) { + LOG.info(numberOfUsedReads + " Reads used."); + System.out.println(numberOfUsedReads + " Reads used."); + } /* If MD value is set, use it to reconstruct reference @@ -220,9 +220,9 @@ private void processRecord(SAMRecord record) { // check if record has MD tag and no reference file is specified - if(record.getStringAttribute(SAMTag.MD.name()) == null && this.reference == null){ + if(record.getStringAttribute(SAMTag.MD.name()) == null && (this.reference == null || !reference.isFile())){ - LOG.error("SAM/BAM file has no MD tag. Please specify reference file which is needed for MD tag calculations."); + LOG.error("SAM/BAM file has no MD tag. Please specify reference file which is needed for MD tag org.damageprofiler.calculations."); System.exit(1); } else { @@ -230,10 +230,10 @@ private void processRecord(SAMRecord record) { // MD tag needs to be calculated --> REF needs to be specified if (record.getStringAttribute(SAMTag.MD.name()) == null){ - if(!reference.isFile()){ - System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag calculations."); - System.exit(1); - } +// if(!reference.isFile()){ +// System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag org.damageprofiler.calculations."); +// System.exit(1); +// } SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, true); } @@ -249,7 +249,7 @@ private void processRecord(SAMRecord record) { System.err.println(record.getReadName() + "\nMD and NM value will be re-calculated. Error: \n" + e); if(!reference.isFile()){ - System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag calculations."); + System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag org.damageprofiler.calculations."); System.exit(1); } diff --git a/src/main/java/calculations/Frequencies.java b/src/main/java/org/damageprofiler/calculations/Frequencies.java similarity index 99% rename from src/main/java/calculations/Frequencies.java rename to src/main/java/org/damageprofiler/calculations/Frequencies.java index 2fad807..ba66bdc 100755 --- a/src/main/java/calculations/Frequencies.java +++ b/src/main/java/org/damageprofiler/calculations/Frequencies.java @@ -1,4 +1,4 @@ -package calculations; +package org.damageprofiler.calculations; import htsjdk.samtools.SAMRecord; import htsjdk.samtools.util.SequenceUtil; import org.apache.log4j.Logger; diff --git a/src/main/java/calculations/Functions.java b/src/main/java/org/damageprofiler/calculations/Functions.java similarity index 97% rename from src/main/java/calculations/Functions.java rename to src/main/java/org/damageprofiler/calculations/Functions.java index d884a89..dc0e6e9 100755 --- a/src/main/java/calculations/Functions.java +++ b/src/main/java/org/damageprofiler/calculations/Functions.java @@ -1,4 +1,4 @@ -package calculations; +package org.damageprofiler.calculations; import org.apache.commons.text.similarity.HammingDistance; import org.apache.commons.text.similarity.LevenshteinDistance; diff --git a/src/main/java/calculations/LengthDistribution.java b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java similarity index 98% rename from src/main/java/calculations/LengthDistribution.java rename to src/main/java/org/damageprofiler/calculations/LengthDistribution.java index d11450c..91390db 100755 --- a/src/main/java/calculations/LengthDistribution.java +++ b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java @@ -1,4 +1,4 @@ -package calculations; +package org.damageprofiler.calculations; import htsjdk.samtools.SAMRecord; import org.apache.log4j.Logger; diff --git a/src/main/java/calculations/RuntimeEstimator.java b/src/main/java/org/damageprofiler/calculations/RuntimeEstimator.java similarity index 98% rename from src/main/java/calculations/RuntimeEstimator.java rename to src/main/java/org/damageprofiler/calculations/RuntimeEstimator.java index a213a1e..f5ae95a 100755 --- a/src/main/java/calculations/RuntimeEstimator.java +++ b/src/main/java/org/damageprofiler/calculations/RuntimeEstimator.java @@ -1,4 +1,4 @@ -package calculations; +package org.damageprofiler.calculations; import htsjdk.samtools.SamReader; import htsjdk.samtools.SamReaderFactory; diff --git a/src/main/java/calculations/SpecieHandler.java b/src/main/java/org/damageprofiler/calculations/SpecieHandler.java similarity index 97% rename from src/main/java/calculations/SpecieHandler.java rename to src/main/java/org/damageprofiler/calculations/SpecieHandler.java index 6869d16..a6f4f01 100755 --- a/src/main/java/calculations/SpecieHandler.java +++ b/src/main/java/org/damageprofiler/calculations/SpecieHandler.java @@ -1,9 +1,9 @@ -package calculations; +package org.damageprofiler.calculations; import java.io.*; import java.util.Random; -import IO.DOMParser; +import org.damageprofiler.IO.DOMParser; import org.apache.log4j.Logger; diff --git a/src/main/java/calculations/SpeciesListParser.java b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java similarity index 97% rename from src/main/java/calculations/SpeciesListParser.java rename to src/main/java/org/damageprofiler/calculations/SpeciesListParser.java index d057f45..15960e5 100755 --- a/src/main/java/calculations/SpeciesListParser.java +++ b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java @@ -1,4 +1,4 @@ -package calculations; +package org.damageprofiler.calculations; import org.apache.log4j.Logger; diff --git a/src/main/java/calculations/StartCalculations.java b/src/main/java/org/damageprofiler/calculations/StartCalculations.java similarity index 98% rename from src/main/java/calculations/StartCalculations.java rename to src/main/java/org/damageprofiler/calculations/StartCalculations.java index 5d18fb6..1eb194f 100755 --- a/src/main/java/calculations/StartCalculations.java +++ b/src/main/java/org/damageprofiler/calculations/StartCalculations.java @@ -1,6 +1,4 @@ -package calculations; - -import IO.*; +package org.damageprofiler.calculations; import java.io.File; import java.io.FileNotFoundException; @@ -12,6 +10,7 @@ import htsjdk.samtools.reference.IndexedFastaSequenceFile; import javafx.scene.paint.Color; import org.apache.log4j.*; +import org.damageprofiler.IO.*; /** @@ -382,11 +381,12 @@ private void generateOutput() throws IOException, DocumentException { damageProfiler.getLength_reverse(), inputfileNameWithOutExtension ); - outputGenerator.plotIdentitiyHistogram( + outputGenerator.plotEditDistanceHistogram( damageProfiler.getEditDistances(), // damageProfiler.getIdentity(), "Identity distribution", inputfileNameWithOutExtension ); + outputGenerator.writeEditDistance(damageProfiler.getEditDistances()); LOG.info("Output files generated"); diff --git a/src/main/java/controller/DamageProfilerMainController.java b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java similarity index 93% rename from src/main/java/controller/DamageProfilerMainController.java rename to src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java index 317899d..ebbab9f 100755 --- a/src/main/java/controller/DamageProfilerMainController.java +++ b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java @@ -1,13 +1,13 @@ -package controller; - -import GUI.*; -import GUI.Dialogues.AdvancedPlottingOptionsDialogue; -import GUI.Dialogues.HelpDialogue; -import GUI.Dialogues.RunInfoDialogue; -import GUI.Dialogues.RuntimeEstimatorDialogue; -import IO.Communicator; -import calculations.RuntimeEstimator; -import calculations.StartCalculations; +package org.damageprofiler.controller; + +import org.damageprofiler.GUI.*; +import org.damageprofiler.GUI.Dialogues.AdvancedPlottingOptionsDialogue; +import org.damageprofiler.GUI.Dialogues.HelpDialogue; +import org.damageprofiler.GUI.Dialogues.RunInfoDialogue; +import org.damageprofiler.GUI.Dialogues.RuntimeEstimatorDialogue; +import org.damageprofiler.calculations.RuntimeEstimator; +import org.damageprofiler.calculations.StartCalculations; +import org.damageprofiler.IO.Communicator; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.concurrent.Task; @@ -32,6 +32,7 @@ public class DamageProfilerMainController { private final Button btn_help; private final HelpDialogue help_dialogue; private final AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue; + private final Button btn_loadSpecies; private RunInfoDialogue runInfoDialogue; private Communicator communicator; private Button btn_inputfile; @@ -69,6 +70,7 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.btn_run = mainGUI.getConfig_dialogue().getBtn_run(); this.btn_estimate_runtime = mainGUI.getConfig_dialogue().getBtn_estimate_runtime(); this.btn_specieList = mainGUI.getConfig_dialogue().getBtn_specieList(); + this.btn_loadSpecies = mainGUI.getConfig_dialogue().getBtn_loadSpecies(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); this.btn_help = mainGUI.getBtn_help(); @@ -106,7 +108,6 @@ private void setColorsPlotting() { Color color_deletions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue(); Color color_other = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue(); - } private void addListener() { @@ -115,7 +116,7 @@ private void addListener() { BamFileChooser fqfc = new BamFileChooser(communicator); Tooltip tooltip_input = new Tooltip(communicator.getInput()); - setTooltipDelay(tooltip_input); + //setTooltipDelay(tooltip_input); btn_inputfile.setTooltip(tooltip_input); if (checkIfInputWasSelected()) { @@ -137,7 +138,7 @@ private void addListener() { ReferenceFileChooser rfc = new ReferenceFileChooser(communicator); Tooltip tooltip_ref = new Tooltip(communicator.getReference()); - setTooltipDelay(tooltip_ref); + //setTooltipDelay(tooltip_ref); btn_reference.setTooltip(tooltip_ref); if (checkIfInputWasSelected()) { @@ -156,7 +157,7 @@ private void addListener() { OutputDirChooser rfc = new OutputDirChooser(communicator); Tooltip tooltip_output = new Tooltip(communicator.getOutfolder()); - setTooltipDelay(tooltip_output); + //setTooltipDelay(tooltip_output); btn_output.setTooltip(tooltip_output); if (checkIfInputWasSelected()) { @@ -218,9 +219,14 @@ private void addListener() { btn_specieList.setDisable(true); } - }); +// btn_loadSpecies.setOnAction(e -> { +// LoadSpeciesDialogue loadSpeciesDialogue = new LoadSpeciesDialogue(communicator.getInput()); +// +// +// }); + btn_leftpane_damageProfile.setOnAction(e -> { if(starter.isCalculationsDone()){ @@ -319,7 +325,7 @@ protected Object call() throws Exception { progressBarController.activate(startCalculuations); startCalculuations.setOnSucceeded((EventHandler<Event>) event -> { - // replace config with result GUI + // replace config with result org.damageprofiler.GUI btn_leftpane_lengthDist.setDisable(false); btn_leftpane_identityDist.setDisable(false); btn_leftpane_damageProfile.setDisable(false); @@ -336,7 +342,7 @@ protected Object call() throws Exception { } /** - * The following methods generate the result plots after successful damage profile calculations. + * The following methods generate the result plots after successful damage profile org.damageprofiler.calculations. * todo: if plot already created, just reload */ @@ -421,7 +427,7 @@ private boolean checkIfInputWasSelected() { * * @param tooltip */ - private static void setTooltipDelay(Tooltip tooltip) { + public static void setTooltipDelay(Tooltip tooltip) { try { Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR"); fieldBehavior.setAccessible(true); diff --git a/src/main/java/controller/ProgressBarController.java b/src/main/java/org/damageprofiler/controller/ProgressBarController.java similarity index 95% rename from src/main/java/controller/ProgressBarController.java rename to src/main/java/org/damageprofiler/controller/ProgressBarController.java index b4dd92d..e1d04e4 100755 --- a/src/main/java/controller/ProgressBarController.java +++ b/src/main/java/org/damageprofiler/controller/ProgressBarController.java @@ -1,4 +1,4 @@ -package controller; +package org.damageprofiler.controller; import javafx.concurrent.Task; import javafx.geometry.Insets; diff --git a/src/main/java/controller/TabPaneAdvPlottingController.java b/src/main/java/org/damageprofiler/controller/TabPaneAdvPlottingController.java similarity index 54% rename from src/main/java/controller/TabPaneAdvPlottingController.java rename to src/main/java/org/damageprofiler/controller/TabPaneAdvPlottingController.java index 763a62e..4f85de9 100755 --- a/src/main/java/controller/TabPaneAdvPlottingController.java +++ b/src/main/java/org/damageprofiler/controller/TabPaneAdvPlottingController.java @@ -1,4 +1,4 @@ -package controller; +package org.damageprofiler.controller; public class TabPaneAdvPlottingController { } From 1573c67768b4ee6bd96f731ec277b27236815705 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Sun, 5 Jul 2020 15:00:15 +0200 Subject: [PATCH 17/22] started to add metagenomic summary output --- build.gradle | 91 +++++++++++++++++-- .../RunDamageProfiler.java | 9 -- .../{org/damageprofiler => }/StarterCLI.java | 3 +- .../{org/damageprofiler => }/StarterGUI.java | 4 +- .../GUI/Dialogues/ConfigurationDialogue.java | 2 +- .../org/damageprofiler/IO/FastACacher.java | 12 ++- .../damageprofiler/IO/MetagenomicOutput.java | 82 +++++++++++++++++ .../damageprofiler/IO/OutputGenerator.java | 26 ++++-- .../damageprofiler/IO/PDFoutput/LinePlot.java | 10 +- .../calculations/DamageProfiler.java | 62 +++++++------ .../calculations/Frequencies.java | 7 ++ .../calculations/StartCalculations.java | 57 ++++++------ 12 files changed, 264 insertions(+), 101 deletions(-) rename src/main/java/{org/damageprofiler => }/RunDamageProfiler.java (95%) rename src/main/java/{org/damageprofiler => }/StarterCLI.java (94%) rename src/main/java/{org/damageprofiler => }/StarterGUI.java (90%) create mode 100644 src/main/java/org/damageprofiler/IO/MetagenomicOutput.java diff --git a/build.gradle b/build.gradle index c5f845f..61e08aa 100755 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,30 @@ -plugins { + plugins { id 'application' id 'org.openjfx.javafxplugin' version '0.0.8' id 'org.beryx.jlink' version '2.12.0' -} + } + +//version '0.5.0-java11-linux' +version '0.5.0-java11' repositories { mavenCentral() + jcenter() } + javafx { + version = "14" + modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics', 'javafx.base', 'javafx.media', 'javafx.swing','javafx.web'] + } + + mainClassName = "RunDamageProfiler" + dependencies { - runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" + //runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" + //runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac" + //compile fileTree(dir: 'src/main/resources/javafx-lib/libs', include: '*.jar') compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' compile group: 'commons-cli', name: 'commons-cli', version: '1.3.+' @@ -24,18 +37,76 @@ dependencies { compile 'org.jfree:jfreechart-fx:1.+' } -javafx { - version = "14" - modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics' ] -} -mainClassName = "org.damageprofiler.RunDamageProfiler" jar { manifest { - attributes 'Main-Class': 'org.damageprofiler.RunDamageProfiler' + attributes 'Main-Class': 'RunDamageProfiler' } from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } -} \ No newline at end of file +} + + +//// Uncomment when compiling with java8 +//version '0.5.0-java8' +//buildscript { +// repositories { +// jcenter() +// } +// dependencies { +// classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8+' +// } +//} +// +//allprojects { +// repositories { +// jcenter() +// } +// apply plugin: 'maven' +// apply plugin: 'maven-publish' +// apply plugin: 'java' +// apply plugin: 'idea' +// apply plugin: 'com.jfrog.bintray' +// apply plugin: 'jacoco' +//} +// +//sourceCompatibility = 1.8 +// +//sourceSets { +// main { +// java { +// srcDir 'src' +// } +// +// resources { +// srcDirs "src/main/resources" +// } +// } +//} +// +// +//dependencies { +// compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' +// compile group: 'commons-cli', name: 'commons-cli', version: '1.3.+' +// compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.+' +// compile group: 'com.github.samtools', name: 'htsjdk', version: '2.+' +// compile group: 'com.intellij', name: 'forms_rt', version: '6.0.+' +// compile group: 'log4j', name: 'log4j', version: '1.+' +// compile group: 'com.github.broadinstitute', name: 'picard', version: '2.+' +// compile group: 'org.jfree', name: 'jfreesvg', version: '2.0' +// compile group: 'org.apache.commons', name: 'commons-text', version: '1.+' +// compile 'org.jfree:jfreechart-fx:1.+' +//} +// +// +//jar { +// manifest { +// attributes("Implementation-Title": "DamageProfiler", +// "Implementation-Version": version, "main-Class": "RunDamageProfiler") +// } +// doFirst { +// from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } +// } +//} \ No newline at end of file diff --git a/src/main/java/org/damageprofiler/RunDamageProfiler.java b/src/main/java/RunDamageProfiler.java similarity index 95% rename from src/main/java/org/damageprofiler/RunDamageProfiler.java rename to src/main/java/RunDamageProfiler.java index 34bda56..3315488 100755 --- a/src/main/java/org/damageprofiler/RunDamageProfiler.java +++ b/src/main/java/RunDamageProfiler.java @@ -1,5 +1,3 @@ -package org.damageprofiler; - import javafx.application.Application; /** @@ -12,17 +10,13 @@ public class RunDamageProfiler { public static void main(String[] args) throws Exception { /* - get input parameters $ damageprofiler : starts org.damageprofiler.GUI $ damageprofiler -i <> -o <> .... : parse command line arguments - */ - - if(args.length==0){ new Thread(() -> Application.launch(StarterGUI.class)).start(); @@ -30,8 +24,5 @@ public static void main(String[] args) throws Exception { System.setProperty("java.awt.headless", "true"); StarterCLI starterCLI = new StarterCLI(VERSION, args); } - - } - } diff --git a/src/main/java/org/damageprofiler/StarterCLI.java b/src/main/java/StarterCLI.java similarity index 94% rename from src/main/java/org/damageprofiler/StarterCLI.java rename to src/main/java/StarterCLI.java index cdc2ac7..46caa76 100755 --- a/src/main/java/org/damageprofiler/StarterCLI.java +++ b/src/main/java/StarterCLI.java @@ -1,5 +1,3 @@ -package org.damageprofiler; - import org.damageprofiler.calculations.StartCalculations; import org.damageprofiler.IO.Communicator; import org.damageprofiler.IO.UserOptionsParser; @@ -12,5 +10,6 @@ public StarterCLI(String version, String[] args) throws Exception { starter.setVERSION(version); UserOptionsParser userOptions = new UserOptionsParser(args, c, version); starter.start(c); + System.exit(0); } } diff --git a/src/main/java/org/damageprofiler/StarterGUI.java b/src/main/java/StarterGUI.java similarity index 90% rename from src/main/java/org/damageprofiler/StarterGUI.java rename to src/main/java/StarterGUI.java index 909eb29..bf0862d 100755 --- a/src/main/java/org/damageprofiler/StarterGUI.java +++ b/src/main/java/StarterGUI.java @@ -1,5 +1,3 @@ -package org.damageprofiler; - import org.damageprofiler.controller.DamageProfilerMainController; import org.damageprofiler.GUI.DamageProfilerMainGUI; import org.damageprofiler.controller.ProgressBarController; @@ -9,7 +7,7 @@ public class StarterGUI extends Application { - private static final String VERSION = "0.4.9"; + private static final String VERSION = "0.5.0"; @Override public void start(Stage primaryStage) { diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java index 8617398..5c755a4 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java @@ -58,7 +58,7 @@ private void addComponents() { Label label_threshold = new Label("Number of bases (x-axis)"); Label label_yaxis = new Label("Height y-axis"); - Label label_length = new Label("Set number of bases (org.damageprofiler.calculations)"); + Label label_length = new Label("Set number of bases"); Label label_specie = new Label("Enter RefSeq ID "); Label label_title = new Label("Set title"); diff --git a/src/main/java/org/damageprofiler/IO/FastACacher.java b/src/main/java/org/damageprofiler/IO/FastACacher.java index 8b1ddfb..31dfffe 100755 --- a/src/main/java/org/damageprofiler/IO/FastACacher.java +++ b/src/main/java/org/damageprofiler/IO/FastACacher.java @@ -11,10 +11,11 @@ */ public class FastACacher { private final Logger LOG; + private final ReferenceSequenceFile refSeq; private HashMap<String,byte[]> data = new HashMap<>(); public FastACacher(File f, Logger LOG) { - ReferenceSequenceFile refSeq = ReferenceSequenceFileFactory.getReferenceSequenceFile(f); + refSeq = ReferenceSequenceFileFactory.getReferenceSequenceFile(f); this.LOG = LOG; @@ -23,7 +24,6 @@ public FastACacher(File f, Logger LOG) { if(rs == null){ break; } else { - data.put(getKeyName(rs.getName()), rs.getBases()); } } @@ -33,6 +33,11 @@ public HashMap<String, byte[]> getData() { return data; } + public ReferenceSequence getSubSequence(String chr, int start, int end){ + ReferenceSequence subsequenceAt = refSeq.getSubsequenceAt(chr, start, end); + return subsequenceAt; + } + public String getKeyName(String reference_name){ String name=reference_name; String[] reference_name_splitted = reference_name.split("ref"); @@ -41,10 +46,7 @@ public String getKeyName(String reference_name){ name = reference_name_splitted[1].substring(1, reference_name_splitted[1].length()-1); } - return name; - - } } diff --git a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java new file mode 100644 index 0000000..c55f7a4 --- /dev/null +++ b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java @@ -0,0 +1,82 @@ +package org.damageprofiler.IO; + +import com.itextpdf.awt.PdfGraphics2D; +import com.itextpdf.text.*; +import com.itextpdf.text.Font; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfTemplate; +import com.itextpdf.text.pdf.PdfWriter; +import org.jfree.chart.JFreeChart; + +import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.util.HashMap; +import java.util.List; + +public class MetagenomicOutput { + + public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name) throws FileNotFoundException, DocumentException { + + // step 1 + Document document = new Document(PageSize.A4); + + // step 2 + PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(output_folder + File.separator + "metagenomic_summary.pdf")); + // step 3 + document.open(); + + Font fontbold = FontFactory.getFont("Times-Roman", 18, Font.BOLD); + + Paragraph para = new Paragraph(); + Chunk c_title = new Chunk("Summary of damage patterns for sample " + sample_name, fontbold); + + Phrase p1 = new Phrase(c_title); + para.add(p1); + + document.add(para); + document.addTitle("Summary of damage patterns for sample " + sample_name); + + PdfContentByte cb = writer.getDirectContent(); + float height = PageSize.A4.getHeight() * (float)0.25; + float width = PageSize.A4.getWidth() / 2; + + for(String species : species_output_summary.keySet()){ + int ypos = 20; + Paragraph para2 = new Paragraph(); + Phrase p2 = new Phrase("Results for species: " + species); + p2.setFont(FontFactory.getFont("Times-Roman", 14)); + para2.add(p2); + document.add(para2); + + double xpos = 0; + for(int i = 0; i < species_output_summary.get(species).size(); i++){ + JFreeChart chart = species_output_summary.get(species).get(i); + PdfTemplate plot = cb.createTemplate(width, height); + Graphics2D g2d = new PdfGraphics2D(plot, width, height); + Rectangle2D r2d = new Rectangle2D.Double(0, 0, width, height); + chart.draw(g2d, r2d); + g2d.dispose(); + + + if(i==0){ + cb.addTemplate(plot, xpos, 500); + } else if(i==1){ + cb.addTemplate(plot, width, 500); + } else if(i==2){ + cb.addTemplate(plot, xpos, 500-height); + } else if(i==3){ + cb.addTemplate(plot, width, 500-height); + } + + ypos += height; + + } + document.newPage(); + } + // step 5 + document.close(); + } +} diff --git a/src/main/java/org/damageprofiler/IO/OutputGenerator.java b/src/main/java/org/damageprofiler/IO/OutputGenerator.java index 03481ed..9a19e6b 100755 --- a/src/main/java/org/damageprofiler/IO/OutputGenerator.java +++ b/src/main/java/org/damageprofiler/IO/OutputGenerator.java @@ -72,6 +72,8 @@ public class OutputGenerator { private Color color_DP_other; + + public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, @@ -101,8 +103,6 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.color_DP_other = color_DP_other; this.color_DP_insertions = color_DP_insertions; - - // set tax id if specified by user if(specie != null && !specie.equals("")){ this.specie = specie; @@ -802,7 +802,7 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep // create plots if(!ssLibProtocolUsed){ - damagePlot_three = new LinePlot("3' end", threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, + damagePlot_three = new LinePlot(threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, color_DP_insertions, color_DP_deletions, color_DP_other); // three prime end @@ -837,7 +837,7 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep } - LinePlot damagePlot_five = new LinePlot("5' end", threshold, height, LOG, color_DP_C_to_T, + LinePlot damagePlot_five = new LinePlot(threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, color_DP_insertions, color_DP_deletions, color_DP_other); /* @@ -896,11 +896,11 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep JFreeChart[] charts; // create damage plot five prime - chart_DP_5prime = damagePlot_five.createChart(dataset_five, ymax, threshold); + chart_DP_5prime = damagePlot_five.createChart("5' end", dataset_five, ymax, threshold); if(!ssLibProtocolUsed){ XYDataset dataset_three = damagePlot_three.createDataset(); // create damage plot three prime - chart_DP_3prime = damagePlot_three.createChart(dataset_three, ymax, threshold); + chart_DP_3prime = damagePlot_three.createChart("3' end", dataset_three, ymax, threshold); charts = new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; createSVG("/DamagePlot_three_prime.svg", chart_DP_3prime); } else { @@ -1090,8 +1090,20 @@ public JFreeChart[] getLengthDistPlots() { return new JFreeChart[]{length_chart_all, length_chart_separated}; } - public JFreeChart getEditDist_chart() { return editDist_chart; } + + public JFreeChart getChart_DP_5prime() { + return chart_DP_5prime; + } + + public JFreeChart getChart_DP_3prime() { + return chart_DP_3prime; + } + + public JFreeChart getLength_chart_all() { + return length_chart_all; + } + } diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java index 3de9d36..0949e48 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java @@ -27,7 +27,6 @@ public class LinePlot { private double y_max=0.0; private double y_min=0.0; private ArrayList<XYSeries> all_data; - private String title; private int threshold; private Color awtColor_DP_C_to_T; @@ -37,12 +36,11 @@ public class LinePlot { private Color awtColor_DP_other; - public LinePlot(String title, int threshold, double height, Logger LOG, javafx.scene.paint.Color color_DP_C_to_T, + public LinePlot(int threshold, double height, Logger LOG, javafx.scene.paint.Color color_DP_C_to_T, javafx.scene.paint.Color color_DP_G_to_A, javafx.scene.paint.Color color_DP_insertions, javafx.scene.paint.Color color_DP_deletions, javafx.scene.paint.Color color_DP_other) { this.LOG = LOG; all_data = new ArrayList<>(); - this.title = title; this.threshold = threshold; this.height = height; @@ -119,7 +117,7 @@ public XYDataset createDataset() { * @param dataset the data for the chart. * @return a chart. */ - public JFreeChart createChart(final XYDataset dataset, double yMax, int threshold) { + public JFreeChart createChart(String title, final XYDataset dataset, double yMax, int threshold) { // create the chart... final JFreeChart chart = ChartFactory.createXYLineChart( @@ -202,13 +200,13 @@ public JFreeChart createChart(final XYDataset dataset, double yMax, int threshol } - switch (this.title){ + switch (title){ case ("3' end"): String[] axis_three_prime = new String[threshold]; int position_three_prime=0; for(int i=threshold; i > 0; i--){ - axis_three_prime[position_three_prime] = "-" + String.valueOf(i); + axis_three_prime[position_three_prime] = "-" + i; position_three_prime++; } diff --git a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java index e57bc1b..4da8dce 100755 --- a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java +++ b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java @@ -1,6 +1,7 @@ package org.damageprofiler.calculations; +import htsjdk.samtools.reference.ReferenceSequence; import org.damageprofiler.IO.FastACacher; import htsjdk.samtools.*; import htsjdk.samtools.util.SequenceUtil; @@ -39,7 +40,6 @@ public class DamageProfiler { public DamageProfiler(SpecieHandler specieHandler, FastACacher cache) { this.specieHandler = specieHandler; this.cache = cache; - } /** @@ -59,11 +59,10 @@ public void init(File input, File reference, int threshold, int length, String s System.exit(0); } else { try{ - if(input.getAbsolutePath().endsWith(".sam") || input.getAbsolutePath().endsWith(".bam") ) { inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). - validationStringency(ValidationStringency.LENIENT).open(input); + validationStringency(ValidationStringency.SILENT).open(input); } else if(input.getAbsolutePath().endsWith(".cram")){ if(!reference.isFile()){ @@ -71,7 +70,7 @@ public void init(File input, File reference, int threshold, int length, String s System.exit(1); } else { inputSam = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). - referenceSequence(reference).validationStringency(ValidationStringency.LENIENT).open(input); + referenceSequence(reference).validationStringency(ValidationStringency.SILENT).open(input); } } @@ -103,8 +102,6 @@ public void init(File input, File reference, int threshold, int length, String s // double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; // System.out.println("Estimated number of records to process: " + Math.round(estimatedNumberOfRecords)); - - } catch (Exception e){ System.err.println("Invalid SAM/BAM file. Please check your file."); LOG.error("Invalid SAM/BAM file. Please check your file."); @@ -135,32 +132,24 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea for(SAMRecord record : inputSam) { - List<SAMSequenceRecord> refs = inputSam.getFileHeader().getSequenceDictionary().getSequences(); +// List<SAMSequenceRecord> refs = inputSam.getFileHeader().getSequenceDictionary().getSequences(); numberOfRecords++; if (this.specie == null) { - handleRecord(use_only_merged_reads, use_all_reads, record); - } else { - if (record.getReferenceName().contains(this.specie)) { - handleRecord(use_only_merged_reads, use_all_reads, record); } } - } frequencies.normalizeValues(); LOG.info("-------------------"); LOG.info("# reads used for damage calculation: " + (numberOfUsedReads )); - System.out.println(numberOfRecords + " Reads in total"); - //System.out.println(numberOfUsedReads + " Reads used for org.damageprofiler.calculations"); } - } @@ -184,7 +173,6 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, processRecord(record); } } - } @@ -204,9 +192,9 @@ private void processRecord(SAMRecord record) { numberOfUsedReads++; // print number of processed reads - if (numberOfUsedReads % 10000 == 0) { + if (numberOfUsedReads % 100000 == 0) { LOG.info(numberOfUsedReads + " Reads used."); - System.out.println(numberOfUsedReads + " Reads used."); + //System.out.println(numberOfUsedReads + " Reads used."); } /* @@ -222,7 +210,7 @@ private void processRecord(SAMRecord record) { // check if record has MD tag and no reference file is specified if(record.getStringAttribute(SAMTag.MD.name()) == null && (this.reference == null || !reference.isFile())){ - LOG.error("SAM/BAM file has no MD tag. Please specify reference file which is needed for MD tag org.damageprofiler.calculations."); + LOG.error("SAM/BAM file has no MD tag. Please specify reference file which is needed for MD tag calculations."); System.exit(1); } else { @@ -239,7 +227,6 @@ private void processRecord(SAMRecord record) { } try{ - byte[] ref_seq = SequenceUtil.makeReferenceFromAlignment(record, false); reference_aligned = new String(ref_seq, "UTF-8"); record_aligned = record.getReadString(); @@ -264,8 +251,6 @@ private void processRecord(SAMRecord record) { } catch (Exception e1){ System.err.println("Re-calculation failed. Record " + record.getReadName() + " will be skipped.\n"); } - - } } } @@ -291,18 +276,37 @@ private void proceed(SAMRecord record, String record_aligned, String reference_a // calculate base misincorporations frequencies.calculateMisincorporations(record, record_aligned, reference_aligned); - } - - - + // if reference file provided: calculate fragmentation pattern +/* int algnStart = record.getAlignmentStart(); + int algnEnd = record.getAlignmentEnd(); + if ( this.cache != null ){ + // Correct indexes! + ReferenceSequence ref_chr_left = this.cache.getSubSequence(record.getReferenceName(), algnStart - 10, algnStart-1); + ReferenceSequence ref_chr_right = this.cache.getSubSequence(record.getReferenceName(), algnEnd+1, algnEnd + 10); + char[] ref_chr_left_string; + char[] ref_chr_right_string; + if(record.getReadNegativeStrandFlag()){ + ref_chr_left_string = SequenceUtil.reverseComplement(ref_chr_left.getBaseString()).toCharArray(); + ref_chr_right_string = SequenceUtil.reverseComplement(ref_chr_right.getBaseString()).toCharArray(); + } else { + ref_chr_left_string = ref_chr_left.getBaseString().toCharArray(); + ref_chr_right_string = ref_chr_right.getBaseString().toCharArray(); + } + frequencies.countRecordFlankingRegions(ref_chr_left_string.toString(), ref_chr_right_string.toString()); + String bases_left = ref_chr_left.getBaseString(); + String bases_right = ref_chr_right.getBaseString(); + System.out.println(bases_left + "|" + reference_aligned + "|" + bases_right); + //System.out.println(ref_chr_complete_region.getBaseString()); + } +*/ + } /* * Getter */ - public Frequencies getFrequencies() { return frequencies; } @@ -325,7 +329,7 @@ public ArrayList<Double> getIdentity() { public String getSpeciesname(File file, String ref) { SamReader input = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). - validationStringency(ValidationStringency.LENIENT).open(file); + validationStringency(ValidationStringency.SILENT).open(file); for(SAMRecord record : input) { if(record.getReferenceName().contains(ref)){ @@ -337,11 +341,9 @@ public String getSpeciesname(File file, String ref) { return null; } - public int getNumberOfRecords() { return numberOfRecords; } - public List<Integer> getEditDistances() { return editDistances; } diff --git a/src/main/java/org/damageprofiler/calculations/Frequencies.java b/src/main/java/org/damageprofiler/calculations/Frequencies.java index ba66bdc..3858bb6 100755 --- a/src/main/java/org/damageprofiler/calculations/Frequencies.java +++ b/src/main/java/org/damageprofiler/calculations/Frequencies.java @@ -598,7 +598,14 @@ public void count(SAMRecord record, String record_aligned, String ref_aligned){ countG_ref_forward_3, countT_ref_forward_3, count0_ref_forward_3, null); } + } + /** + * Count purine bases + * @param ref_left bases left of record + * @param ref_right bases right of record + */ + public void countRecordFlankingRegions(String ref_left, String ref_right) { } diff --git a/src/main/java/org/damageprofiler/calculations/StartCalculations.java b/src/main/java/org/damageprofiler/calculations/StartCalculations.java index 1eb194f..491107d 100755 --- a/src/main/java/org/damageprofiler/calculations/StartCalculations.java +++ b/src/main/java/org/damageprofiler/calculations/StartCalculations.java @@ -4,6 +4,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import com.itextpdf.text.DocumentException; @@ -11,6 +12,7 @@ import javafx.scene.paint.Color; import org.apache.log4j.*; import org.damageprofiler.IO.*; +import org.jfree.chart.JFreeChart; /** @@ -48,7 +50,7 @@ public class StartCalculations { private Communicator communicator; private IndexedFastaSequenceFile fastaSequenceFile; private FastACacher cache; - + private HashMap<String, List<JFreeChart>> species_output_summary; // plot settings @@ -68,6 +70,7 @@ public StartCalculations(){ public void setVERSION(String version){ VERSION = version; } + public void start(Communicator c) throws Exception { currtime_prior_execution = System.currentTimeMillis(); @@ -109,6 +112,7 @@ public void start(Communicator c) throws Exception { readReferenceInCache(); if(specieslist_filepath != null){ + species_output_summary = new HashMap<>(); specieHandler = new SpecieHandler(); /* @@ -122,16 +126,12 @@ parse species references (-sf) and run DP for each reference in the file String specie_input_string = specieslist.get(i); //String specie_name = species_real_name_list.get(i); - - - // start DamageProfiler + // start DamageProfiler damageProfiler = new DamageProfiler(specieHandler, cache); - String ref = specie_input_string.split("\\|")[0].trim(); speciesname = damageProfiler.getSpeciesname(new File(input), ref); - createOutputFolder( outfolder, inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1] @@ -164,7 +164,6 @@ parse species references (-sf) and run DP for each reference in the file + "x-axis min length histogram (-xaxis_histo_length_min): " + xaxis_min_length_histogram + "\n" + "x-axis max length histogram (-xaxis_histo_length_max): " + xaxis_max_length_histogram + "\n"); - damageProfiler.init(new File(input), new File(reference), threshold, @@ -173,16 +172,29 @@ parse species references (-sf) and run DP for each reference in the file LOG); damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); - + generateOutput(); + String spec_no_space = specie_input_string.replace(" ","_"); + species_output_summary.put(spec_no_space + " (" + speciesname + ")", + List.of(outputGenerator.getChart_DP_5prime(), + outputGenerator.getChart_DP_3prime(), + outputGenerator.getEditDist_chart(), + outputGenerator.getLength_chart_all()) + ); } + // generate metagenomic output summary + MetagenomicOutput metagenomicOutput = new MetagenomicOutput(); + String[] splitted = input.split("/"); + String filename = splitted[splitted.length-1]; + metagenomicOutput.generate(outfolder + File.separator + + inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1], + species_output_summary, filename); + } else if(species_ref_identifier != null){ // start DamageProfiler - damageProfiler = new DamageProfiler( - - specieHandler, cache); + damageProfiler = new DamageProfiler(specieHandler, cache); /* parse species reference (-s) and run DP @@ -224,9 +236,6 @@ parse species reference (-s) and run DP + "x-axis min length histogram (-xaxis_histo_length_min): " + xaxis_min_length_histogram + "\n" + "x-axis max length histogram (-xaxis_histo_length_max): " + xaxis_max_length_histogram + "\n"); - - - damageProfiler.init(new File(input), new File(reference), threshold, @@ -236,11 +245,12 @@ parse species reference (-s) and run DP damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); speciesListParser.setLOG(LOG); + generateOutput(); } else { /* - No species specified --> use all (mapping) reads + No species specified --> use all mapped reads */ String inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); @@ -275,8 +285,6 @@ parse species reference (-s) and run DP + "x-axis min length histogram (-xaxis_histo_length_min): " + xaxis_min_length_histogram + "\n" + "x-axis max length histogram (-xaxis_histo_length_max): " + xaxis_max_length_histogram + "\n"); - - // start DamageProfiler damageProfiler = new DamageProfiler(specieHandler, cache); @@ -288,13 +296,10 @@ parse species reference (-s) and run DP LOG); damageProfiler.extractSAMRecords(use_only_merged_reads, use_all_reads); speciesListParser.setLOG(LOG); - - - + generateOutput(); } - generateOutput(); - + calculationsDone=true; // print runtime long currtime_post_execution = System.currentTimeMillis(); @@ -303,13 +308,11 @@ parse species reference (-s) and run DP if(runtime_s > 60) { long minutes = runtime_s / 60; long seconds = runtime_s % 60; - LOG.info("Runtime of Module was: " + minutes + " minutes, and " + seconds + " seconds."); + LOG.info("Runtime of Module was: " + minutes + " minutes, and " + seconds + " seconds.\n\n"); } else { - LOG.info("Runtime of Module was: " + runtime_s + " seconds."); + LOG.info("Runtime of Module was: " + runtime_s + " seconds.\n\n"); } - calculationsDone=true; - } private void initPlot() { @@ -318,7 +321,6 @@ private void initPlot() { } else { inputfileNameWithOutExtension = communicator.getTitle_plots(); } - } private void initLogger(String outfolder, String log) { @@ -396,7 +398,6 @@ private void generateOutput() throws IOException, DocumentException { } - /** * create output folder. * Save all files in subfolder, which has the same name as the input file From ea4ae3de5721e4d2eddff2189daa648b6a62f54d Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Mon, 20 Jul 2020 10:55:57 +0200 Subject: [PATCH 18/22] fixes in metagenomic summary output --- .../org/damageprofiler/IO/MetagenomicOutput.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java index c55f7a4..ccd2b66 100644 --- a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java +++ b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java @@ -20,24 +20,31 @@ public class MetagenomicOutput { public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name) throws FileNotFoundException, DocumentException { + // todo: tile page + // step 1 Document document = new Document(PageSize.A4); // step 2 - PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(output_folder + File.separator + "metagenomic_summary.pdf")); + PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(output_folder + File.separator + sample_name +"_summary.pdf")); // step 3 document.open(); - Font fontbold = FontFactory.getFont("Times-Roman", 18, Font.BOLD); + Font fontbold = FontFactory.getFont("Times-Roman", 24, Font.BOLD); Paragraph para = new Paragraph(); - Chunk c_title = new Chunk("Summary of damage patterns for sample " + sample_name, fontbold); + Chunk c_title = new Chunk("\n\n\n\nSummary of damage patterns\n\n" + sample_name, fontbold); Phrase p1 = new Phrase(c_title); para.add(p1); + para.setAlignment(1); document.add(para); - document.addTitle("Summary of damage patterns for sample " + sample_name); + document.addTitle("Summary_damage_patterns"); + + + + document.newPage(); PdfContentByte cb = writer.getDirectContent(); float height = PageSize.A4.getHeight() * (float)0.25; From fff35e8483347078caf1629e97c25ec214ccdbb7 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Mon, 20 Jul 2020 11:00:09 +0200 Subject: [PATCH 19/22] fix typo --- .../GUI/Dialogues/ConfigurationDialogue.java | 20 +++++++++--------- .../damageprofiler/IO/MetagenomicOutput.java | 5 ++--- .../damageprofiler/IO/OutputGenerator.java | 16 +++++++------- .../calculations/DamageProfiler.java | 21 +++++++++---------- ...SpecieHandler.java => SpeciesHandler.java} | 14 ++++++------- .../calculations/SpeciesListParser.java | 12 +++++------ .../calculations/StartCalculations.java | 10 ++++----- .../DamageProfilerMainController.java | 18 ++++++++-------- 8 files changed, 57 insertions(+), 59 deletions(-) rename src/main/java/org/damageprofiler/calculations/{SpecieHandler.java => SpeciesHandler.java} (92%) diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java index 5c755a4..47f6ba1 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java @@ -18,11 +18,11 @@ public class ConfigurationDialogue { private Button btn_output; private Button btn_run; private Button btn_estimate_runtime; - private Button btn_specieList; + private Button btn_speciesList; private TextField textfield_threshold; private TextField textfield_length; - private TextField textfield_specie; + private TextField textfield_species; private CheckBox checkbox_use_merged_reads; private CheckBox checkbox_ssLibs_protocol; private TextField textfield_title; @@ -51,7 +51,7 @@ private void addComponents() { btn_inputfile = new Button("Select input file"); btn_reference = new Button("Select reference"); btn_output = new Button("Select output"); - btn_specieList = new Button("Set species file"); + btn_speciesList = new Button("Set species file"); btn_loadSpecies = new Button("Load Species"); btn_run = new Button("Run"); btn_estimate_runtime = new Button("Estimate Runtime"); @@ -76,7 +76,7 @@ private void addComponents() { textfield_threshold = new TextField(); textfield_length = new TextField(); - textfield_specie = new TextField(); + textfield_species = new TextField(); textfield_title = new TextField(); textfield_y_axis_height = new TextField(); @@ -137,8 +137,8 @@ private void addComponents() { config_gridpane.add(checkbox_use_merged_reads, 0, ++row,1,1); config_gridpane.add(checkbox_ssLibs_protocol, 0, ++row, 1,1); config_gridpane.add(label_specie, 0, ++row, 1,1); - config_gridpane.add(textfield_specie, 1, row, 2,1); - config_gridpane.add(btn_specieList, 1, ++row, 1,1); + config_gridpane.add(textfield_species, 1, row, 2,1); + config_gridpane.add(btn_speciesList, 1, ++row, 1,1); //config_gridpane.add(btn_loadSpecies, 3, row, 1,1); config_gridpane.add(pane_advanced_calculation_options, 0,++row, 3,1); @@ -169,8 +169,8 @@ public Button getBtn_run() { return btn_run; } - public Button getBtn_specieList() { - return btn_specieList; + public Button getBtn_speciesList() { + return btn_speciesList; } public TextField getTextfield_threshold() { @@ -181,8 +181,8 @@ public TextField getTextfield_length() { return textfield_length; } - public TextField getTextfield_specie() { - return textfield_specie; + public TextField getTextfield_species() { + return textfield_species; } public CheckBox getCheckbox_use_merged_reads() { diff --git a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java index ccd2b66..71789da 100644 --- a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java +++ b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java @@ -18,9 +18,8 @@ public class MetagenomicOutput { - public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name) throws FileNotFoundException, DocumentException { - - // todo: tile page + public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name) + throws FileNotFoundException, DocumentException { // step 1 Document document = new Document(PageSize.A4); diff --git a/src/main/java/org/damageprofiler/IO/OutputGenerator.java b/src/main/java/org/damageprofiler/IO/OutputGenerator.java index 9a19e6b..415ae6e 100755 --- a/src/main/java/org/damageprofiler/IO/OutputGenerator.java +++ b/src/main/java/org/damageprofiler/IO/OutputGenerator.java @@ -52,7 +52,7 @@ public class OutputGenerator { private int numberOfRecords; private int max_length; private int min_length; - private String specie; + private String species; private int threshold; private int length; private String input; @@ -74,7 +74,7 @@ public class OutputGenerator { - public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String specie, int threshold, + public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, String species, int threshold, int length, double height, double x_axis_min_id_histo, double x_axis_max_id_histo, double x_axis_min_length_histo, double x_axis_max_length_histo, String input, Logger LOG, int numberOfRecords, boolean ssLibProtocolUsed, Color color_DP_C_to_T, @@ -104,8 +104,8 @@ public OutputGenerator(String outputFolder, DamageProfiler damageProfiler, Strin this.color_DP_insertions = color_DP_insertions; // set tax id if specified by user - if(specie != null && !specie.equals("")){ - this.specie = specie; + if(species != null && !species.equals("")){ + this.species = species; } } @@ -1009,21 +1009,21 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws String read_per; if(!ssLibProtocolUsed){ - if(this.specie == null){ + if(this.species == null){ read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads)"; } else{ read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Species: " + this.specie; + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Species: " + this.species; } } else { - if(this.specie == null){ + if(this.species == null){ read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | ssLib protocol"; } else { read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Species: " + this.specie + " | ssLib protocol"; + (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Species: " + this.species + " | ssLib protocol"; } } diff --git a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java index 4da8dce..47fd09d 100755 --- a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java +++ b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java @@ -1,7 +1,6 @@ package org.damageprofiler.calculations; -import htsjdk.samtools.reference.ReferenceSequence; import org.damageprofiler.IO.FastACacher; import htsjdk.samtools.*; import htsjdk.samtools.util.SequenceUtil; @@ -19,7 +18,7 @@ public class DamageProfiler { private final FastACacher cache; private SamReader inputSam=null; private Functions useful_functions=null; - private String specie=null; + private String species =null; private Logger LOG=null; private int numberOfUsedReads; private int numberOfRecords; @@ -29,16 +28,16 @@ public class DamageProfiler { private File reference; LengthDistribution lengthDistribution; private ArrayList<Double> identity; - private SpecieHandler specieHandler; + private SpeciesHandler speciesHandler; private List<Integer> editDistances; /** * constructor - * @param specieHandler + * @param speciesHandler * @param cache */ - public DamageProfiler(SpecieHandler specieHandler, FastACacher cache) { - this.specieHandler = specieHandler; + public DamageProfiler(SpeciesHandler speciesHandler, FastACacher cache) { + this.speciesHandler = speciesHandler; this.cache = cache; } @@ -86,7 +85,7 @@ public void init(File input, File reference, int threshold, int length, String s this.lengthDistribution.init(); this.identity = new ArrayList(); this.editDistances = new ArrayList(); - this.specie = specie; + this.species = specie; useful_functions = new Functions(this.LOG); // number of records in file: @@ -136,10 +135,10 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea numberOfRecords++; - if (this.specie == null) { + if (this.species == null) { handleRecord(use_only_merged_reads, use_all_reads, record); } else { - if (record.getReferenceName().contains(this.specie)) { + if (record.getReferenceName().contains(this.species)) { handleRecord(use_only_merged_reads, use_all_reads, record); } } @@ -333,8 +332,8 @@ public String getSpeciesname(File file, String ref) { for(SAMRecord record : input) { if(record.getReferenceName().contains(ref)){ - specieHandler.getSpecie(record.getReferenceName()); - String spe = specieHandler.getSpecie_name(); + speciesHandler.getSpecies(record.getReferenceName()); + String spe = speciesHandler.getSpecies_name(); return spe.replace(" ", "_").trim(); } } diff --git a/src/main/java/org/damageprofiler/calculations/SpecieHandler.java b/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java similarity index 92% rename from src/main/java/org/damageprofiler/calculations/SpecieHandler.java rename to src/main/java/org/damageprofiler/calculations/SpeciesHandler.java index a6f4f01..b45c1b8 100755 --- a/src/main/java/org/damageprofiler/calculations/SpecieHandler.java +++ b/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java @@ -10,17 +10,17 @@ /** * Created by neukamm on 25.07.16. */ -public class SpecieHandler { +public class SpeciesHandler { private Logger LOG; private String gi; - private String specie_name; + private String species_name; - public SpecieHandler(){ + public SpeciesHandler(){ } - public void getSpecie(String rname){ + public void getSpecies(String rname){ if (rname != null) { String tax = ""; @@ -44,7 +44,7 @@ public void getSpecie(String rname){ "Please make sure that the SAM/BAM file reference tag contains the tax ID"); } if(!tax.equals("")){ - specie_name = getSpeciesByID(Integer.parseInt(tax)); + species_name = getSpeciesByID(Integer.parseInt(tax)); // specie_name = specie_name.replaceAll(" ", "_"); } } @@ -102,8 +102,8 @@ private String getSpeciesByID(int id) { } - public String getSpecie_name() { - return specie_name; + public String getSpecies_name() { + return species_name; } public void setLOG(Logger LOG) { diff --git a/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java index 15960e5..8962140 100755 --- a/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java +++ b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java @@ -14,19 +14,19 @@ public class SpeciesListParser { private Logger LOG; private String speciesFile; - private SpecieHandler specieHandler; + private SpeciesHandler speciesHandler; public SpeciesListParser(String speciesListFile, Logger LOG) { this.speciesFile = speciesListFile; this.LOG = LOG; - specieHandler = new SpecieHandler(); + speciesHandler = new SpeciesHandler(); } - public String getSingleSpecie(String rname) { + public String getSingleSpecies(String rname) { - specieHandler.getSpecie(rname); - return specieHandler.getSpecie_name(); + speciesHandler.getSpecies(rname); + return speciesHandler.getSpecies_name(); } public List<String> getList() { @@ -61,7 +61,7 @@ private List<String> readFile() { public void setLOG(Logger LOG) { this.LOG = LOG; - specieHandler.setLOG(LOG); + speciesHandler.setLOG(LOG); } } diff --git a/src/main/java/org/damageprofiler/calculations/StartCalculations.java b/src/main/java/org/damageprofiler/calculations/StartCalculations.java index 491107d..1401c43 100755 --- a/src/main/java/org/damageprofiler/calculations/StartCalculations.java +++ b/src/main/java/org/damageprofiler/calculations/StartCalculations.java @@ -37,7 +37,7 @@ public class StartCalculations { private String reference; private String outfolder; private String input; - private SpecieHandler specieHandler = new SpecieHandler(); + private SpeciesHandler speciesHandler = new SpeciesHandler(); private boolean use_all_reads; private double xaxis_min_id_histogram; private double xaxis_max_id_histogram; @@ -114,7 +114,7 @@ public void start(Communicator c) throws Exception { if(specieslist_filepath != null){ species_output_summary = new HashMap<>(); - specieHandler = new SpecieHandler(); + speciesHandler = new SpeciesHandler(); /* parse species references (-sf) and run DP for each reference in the file */ @@ -127,7 +127,7 @@ parse species references (-sf) and run DP for each reference in the file //String specie_name = species_real_name_list.get(i); // start DamageProfiler - damageProfiler = new DamageProfiler(specieHandler, cache); + damageProfiler = new DamageProfiler(speciesHandler, cache); String ref = specie_input_string.split("\\|")[0].trim(); speciesname = damageProfiler.getSpeciesname(new File(input), ref); @@ -194,7 +194,7 @@ parse species references (-sf) and run DP for each reference in the file } else if(species_ref_identifier != null){ // start DamageProfiler - damageProfiler = new DamageProfiler(specieHandler, cache); + damageProfiler = new DamageProfiler(speciesHandler, cache); /* parse species reference (-s) and run DP @@ -286,7 +286,7 @@ parse species reference (-s) and run DP + "x-axis max length histogram (-xaxis_histo_length_max): " + xaxis_max_length_histogram + "\n"); // start DamageProfiler - damageProfiler = new DamageProfiler(specieHandler, cache); + damageProfiler = new DamageProfiler(speciesHandler, cache); damageProfiler.init(new File(input), new File(reference), diff --git a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java index ebbab9f..ce8193f 100755 --- a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java +++ b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java @@ -39,10 +39,10 @@ public class DamageProfilerMainController { private Button btn_reference; private Button btn_output; private Button btn_run; - private Button btn_specieList; + private Button btn_speciesList; private TextField textfield_threshold; private TextField textfield_length; - private TextField textfield_specie; + private TextField textfield_species; private CheckBox checkbox_use_merged_reads; private CheckBox checkbox_ssLibs_protocol; private TextField textfield_title; @@ -69,7 +69,7 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.btn_output = mainGUI.getConfig_dialogue().getBtn_output(); this.btn_run = mainGUI.getConfig_dialogue().getBtn_run(); this.btn_estimate_runtime = mainGUI.getConfig_dialogue().getBtn_estimate_runtime(); - this.btn_specieList = mainGUI.getConfig_dialogue().getBtn_specieList(); + this.btn_speciesList = mainGUI.getConfig_dialogue().getBtn_speciesList(); this.btn_loadSpecies = mainGUI.getConfig_dialogue().getBtn_loadSpecies(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); @@ -79,7 +79,7 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.textfield_threshold = mainGUI.getConfig_dialogue().getTextfield_threshold(); this.textfield_length = mainGUI.getConfig_dialogue().getTextfield_length(); - this.textfield_specie = mainGUI.getConfig_dialogue().getTextfield_specie(); + this.textfield_species = mainGUI.getConfig_dialogue().getTextfield_species(); this.textfield_title = mainGUI.getConfig_dialogue().getTextfield_title(); this.textfield_y_axis_height = mainGUI.getConfig_dialogue().getTextfield_y_axis_height(); @@ -210,13 +210,13 @@ private void addListener() { runDamageProfiler(); }); - btn_specieList.setOnAction(e -> { + btn_speciesList.setOnAction(e -> { SpeciesListFileChooser slfc = new SpeciesListFileChooser(communicator); if (checkIfInputWasSelected()) { - btn_specieList.setDisable(false); + btn_speciesList.setDisable(false); } else { - btn_specieList.setDisable(true); + btn_speciesList.setDisable(true); } }); @@ -301,10 +301,10 @@ private void runDamageProfiler() { communicator.setColor_DP_other(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue()); - if(textfield_specie.getText().equals("")) + if(textfield_species.getText().equals("")) communicator.setSpecies_ref_identifier(null); else - communicator.setSpecies_ref_identifier(textfield_specie.getText()); + communicator.setSpecies_ref_identifier(textfield_species.getText()); if(!textfield_title.getText().equals("")){ communicator.setTitle_plots(textfield_title.getText()); From a81ec9e40d6073b7f3c95f111c5b47101fb725cd Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Tue, 21 Jul 2020 10:07:09 +0200 Subject: [PATCH 20/22] clean up, levensthein method removed (unused) --- build.gradle | 4 -- .../GUI/Dialogues/HelpDialogue.java | 1 - .../java/org/damageprofiler/IO/DOMParser.java | 7 ++ .../damageprofiler/IO/MetagenomicOutput.java | 22 ++++-- .../IO/PDFoutput/Histogram.java | 3 - .../damageprofiler/IO/PDFoutput/LinePlot.java | 4 +- .../java/org/damageprofiler/IO/Unzip.java | 45 ------------ .../calculations/DamageProfiler.java | 72 +++---------------- .../calculations/Functions.java | 34 --------- .../calculations/LengthDistribution.java | 22 +----- .../calculations/SpeciesHandler.java | 24 +++---- .../calculations/SpeciesListParser.java | 31 ++++---- .../calculations/StartCalculations.java | 55 ++++++-------- .../DamageProfilerMainController.java | 2 +- 14 files changed, 85 insertions(+), 241 deletions(-) delete mode 100755 src/main/java/org/damageprofiler/IO/Unzip.java diff --git a/build.gradle b/build.gradle index 61e08aa..a1ba6fa 100755 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,6 @@ id 'org.beryx.jlink' version '2.12.0' } -//version '0.5.0-java11-linux' version '0.5.0-java11' @@ -22,9 +21,6 @@ repositories { mainClassName = "RunDamageProfiler" dependencies { - //runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" - //runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac" - //compile fileTree(dir: 'src/main/resources/javafx-lib/libs', include: '*.jar') compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' compile group: 'commons-cli', name: 'commons-cli', version: '1.3.+' diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java index a3ee889..4862a61 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/HelpDialogue.java @@ -60,7 +60,6 @@ private void fill() { } }).start()); - // todo: one could make it a bit nicer Label label_helppage = new Label(" -h\t\t\t\t\t\t\tShows this help page.\n" + " -version\t\t\t\t\t\tShows the version of DamageProfiler.\n" + " -i <INPUT>\t\t\t\t\tREQUIRED: The input sam/bam/cram file.\n" + diff --git a/src/main/java/org/damageprofiler/IO/DOMParser.java b/src/main/java/org/damageprofiler/IO/DOMParser.java index 6040e96..fc30ae0 100755 --- a/src/main/java/org/damageprofiler/IO/DOMParser.java +++ b/src/main/java/org/damageprofiler/IO/DOMParser.java @@ -25,6 +25,13 @@ public DOMParser(Logger LOG){ this.LOG = LOG; } + + /** + * Parse file from NCBI with species information to filter species name information. + * + * @param filepathXML + * @return + */ public String parse(String filepathXML) { String species = null; diff --git a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java index 71789da..5043674 100644 --- a/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java +++ b/src/main/java/org/damageprofiler/IO/MetagenomicOutput.java @@ -18,7 +18,19 @@ public class MetagenomicOutput { - public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name) + /** + * Writes summary of the metagenomic results. Only a overview of the results is presented for + * each species. + * + * @param output_folder + * @param species_output_summary + * @param sample_name + * @param mapped_reads + * @throws FileNotFoundException + * @throws DocumentException + */ + public void generate(String output_folder, HashMap<String, List<JFreeChart>> species_output_summary, String sample_name, + HashMap<String, Integer> mapped_reads) throws FileNotFoundException, DocumentException { // step 1 @@ -50,11 +62,11 @@ public void generate(String output_folder, HashMap<String, List<JFreeChart>> spe float width = PageSize.A4.getWidth() / 2; for(String species : species_output_summary.keySet()){ - int ypos = 20; Paragraph para2 = new Paragraph(); - Phrase p2 = new Phrase("Results for species: " + species); - p2.setFont(FontFactory.getFont("Times-Roman", 14)); + Phrase p2 = new Phrase("Results for species:\n\n" + species, FontFactory.getFont("Times-Roman", 22)); + Phrase p3 = new Phrase("\n\nNumber of mapped reads:" + mapped_reads.get(species), FontFactory.getFont("Times-Roman", 18)); para2.add(p2); + para2.add(p3); document.add(para2); double xpos = 0; @@ -77,8 +89,6 @@ public void generate(String output_folder, HashMap<String, List<JFreeChart>> spe cb.addTemplate(plot, width, 500-height); } - ypos += height; - } document.newPage(); } diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java index 8620b5b..f5f053a 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java @@ -70,7 +70,6 @@ public JFreeChart createChart(HistogramDataset dataset, String title, String xla false ); -// chart.setBackgroundPaint(new Color(230,230,230)); XYPlot xyplot = (XYPlot)chart.getPlot(); xyplot.setForegroundAlpha(0.7F); xyplot.setBackgroundPaint(Color.WHITE); @@ -90,8 +89,6 @@ public JFreeChart createChart(HistogramDataset dataset, String title, String xla XYBarRenderer xybarrenderer = (XYBarRenderer)xyplot.getRenderer(); xybarrenderer.setShadowVisible(false); -// xybarrenderer.setBarPainter(new StandardXYBarPainter()); -// xybarrenderer.setMargin(0.2); return chart; diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java index 0949e48..bc4b49b 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java @@ -78,7 +78,7 @@ public void addData(double[] data, String name){ final XYSeries series = new XYSeries(name); for(int i = 0; i < threshold; i++){ - series.add((double)i, data[i]); + series.add(i, data[i]); } all_data.add(series); @@ -98,7 +98,6 @@ public XYDataset createDataset() { for(XYSeries series : all_data){ dataset.addSeries(series); if(series.getMaxY() > y_max){y_max=series.getMaxY();} - //if(series.getMinY() < y_min){y_min=series.getMinY();} } y_min = 0.0; @@ -154,7 +153,6 @@ public JFreeChart createChart(String title, final XYDataset dataset, double yMax legendItemsNew.add(legendItemsOld.get(3)); legendItemsNew.add(legendItemsOld.get(4)); - //legendItemsNew.get(0).setLinePaint(Color.RED); legendItemsNew.get(0).setLinePaint(this.awtColor_DP_C_to_T); legendItemsNew.get(1).setLinePaint(this.awtColor_DP_G_to_A); legendItemsNew.get(2).setLinePaint(this.awtColor_DP_insertions); diff --git a/src/main/java/org/damageprofiler/IO/Unzip.java b/src/main/java/org/damageprofiler/IO/Unzip.java deleted file mode 100755 index 09555b2..0000000 --- a/src/main/java/org/damageprofiler/IO/Unzip.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.damageprofiler.IO; - -import org.apache.log4j.Logger; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.util.zip.GZIPInputStream; - - -/** - * Created by neukamm on 25.07.2016. - */ -public class Unzip { - - private final Logger LOG; - - public Unzip(Logger LOG){ - this.LOG = LOG; - } - - - /** - * decompress zipped/compressed file - * - * @param infile - * @return - * @throws Exception - */ - public String decompress(String infile) throws Exception { - - GZIPInputStream in = new GZIPInputStream(new FileInputStream(infile)); - String outfile = infile.substring(0, infile.lastIndexOf('.')); - OutputStream out = new FileOutputStream(outfile); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - in.close(); - out.close(); - - return outfile; - } -} diff --git a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java index 47fd09d..81e4272 100755 --- a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java +++ b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java @@ -86,20 +86,8 @@ public void init(File input, File reference, int threshold, int length, String s this.identity = new ArrayList(); this.editDistances = new ArrayList(); this.species = specie; - useful_functions = new Functions(this.LOG); - - // number of records in file: - //numberOfRecords = inputSam.iterator().toList().size(); - // estimate number of records in file: -// double bytes = input.length(); -// double kilobytes = (bytes / 1024); -// double megabytes = (kilobytes / 1024); -// double gigabytes = (megabytes / 1024); -// -// double sizeSamRecordInBytes = 50; -// -// double estimatedNumberOfRecords = bytes/sizeSamRecordInBytes; -// System.out.println("Estimated number of records to process: " + Math.round(estimatedNumberOfRecords)); + useful_functions = new Functions(); + } catch (Exception e){ System.err.println("Invalid SAM/BAM file. Please check your file."); @@ -130,9 +118,6 @@ public void extractSAMRecords(boolean use_only_merged_reads, boolean use_all_rea } else { for(SAMRecord record : inputSam) { - -// List<SAMSequenceRecord> refs = inputSam.getFileHeader().getSequenceDictionary().getSequences(); - numberOfRecords++; if (this.species == null) { @@ -190,12 +175,6 @@ private void handleRecord(boolean use_only_merged_reads, boolean use_all_reads, private void processRecord(SAMRecord record) { numberOfUsedReads++; - // print number of processed reads - if (numberOfUsedReads % 100000 == 0) { - LOG.info(numberOfUsedReads + " Reads used."); - //System.out.println(numberOfUsedReads + " Reads used."); - } - /* If MD value is set, use it to reconstruct reference Otherwise reconstruct it based on reference. @@ -216,13 +195,7 @@ private void processRecord(SAMRecord record) { // MD tag needs to be calculated --> REF needs to be specified if (record.getStringAttribute(SAMTag.MD.name()) == null){ - -// if(!reference.isFile()){ -// System.err.println("No MD tag defined. Please specify reference file which is needed for MD tag org.damageprofiler.calculations."); -// System.exit(1); -// } SequenceUtil.calculateMdAndNmTags(record, cache.getData().get(record.getReferenceName()), true, true); - } try{ @@ -262,9 +235,6 @@ private void proceed(SAMRecord record, String record_aligned, String reference_a // calculate distance between record and reference int hamming = useful_functions.getHammingDistance(record_aligned, reference_aligned); - // todo: so far unused, could be added as user-choice - int levenshtein = useful_functions.getLevenshteinDistance(record_aligned, reference_aligned); - double id = (double)(record_aligned.length()-hamming) / (double)record_aligned.length(); this.identity.add(id); this.editDistances.add(hamming); @@ -275,31 +245,6 @@ private void proceed(SAMRecord record, String record_aligned, String reference_a // calculate base misincorporations frequencies.calculateMisincorporations(record, record_aligned, reference_aligned); - // if reference file provided: calculate fragmentation pattern -/* int algnStart = record.getAlignmentStart(); - int algnEnd = record.getAlignmentEnd(); - if ( this.cache != null ){ - // Correct indexes! - ReferenceSequence ref_chr_left = this.cache.getSubSequence(record.getReferenceName(), algnStart - 10, algnStart-1); - ReferenceSequence ref_chr_right = this.cache.getSubSequence(record.getReferenceName(), algnEnd+1, algnEnd + 10); - char[] ref_chr_left_string; - char[] ref_chr_right_string; - if(record.getReadNegativeStrandFlag()){ - ref_chr_left_string = SequenceUtil.reverseComplement(ref_chr_left.getBaseString()).toCharArray(); - ref_chr_right_string = SequenceUtil.reverseComplement(ref_chr_right.getBaseString()).toCharArray(); - } else { - ref_chr_left_string = ref_chr_left.getBaseString().toCharArray(); - ref_chr_right_string = ref_chr_right.getBaseString().toCharArray(); - } - frequencies.countRecordFlankingRegions(ref_chr_left_string.toString(), ref_chr_right_string.toString()); - - - String bases_left = ref_chr_left.getBaseString(); - String bases_right = ref_chr_right.getBaseString(); - System.out.println(bases_left + "|" + reference_aligned + "|" + bases_right); - //System.out.println(ref_chr_complete_region.getBaseString()); - } -*/ } /* @@ -322,9 +267,13 @@ public int getNumberOfUsedReads() { return numberOfUsedReads; } - public ArrayList<Double> getIdentity() { - return identity; } - + /** + * Determines the name of the species based on the NCBI ref ID. + * + * @param file + * @param ref + * @return + */ public String getSpeciesname(File file, String ref) { SamReader input = SamReaderFactory.make().enable(SamReaderFactory.Option.DONT_MEMORY_MAP_INDEX). @@ -332,8 +281,7 @@ public String getSpeciesname(File file, String ref) { for(SAMRecord record : input) { if(record.getReferenceName().contains(ref)){ - speciesHandler.getSpecies(record.getReferenceName()); - String spe = speciesHandler.getSpecies_name(); + String spe = speciesHandler.getSpecies(record.getReferenceName()); return spe.replace(" ", "_").trim(); } } diff --git a/src/main/java/org/damageprofiler/calculations/Functions.java b/src/main/java/org/damageprofiler/calculations/Functions.java index dc0e6e9..c3ee1ad 100755 --- a/src/main/java/org/damageprofiler/calculations/Functions.java +++ b/src/main/java/org/damageprofiler/calculations/Functions.java @@ -1,21 +1,12 @@ package org.damageprofiler.calculations; import org.apache.commons.text.similarity.HammingDistance; -import org.apache.commons.text.similarity.LevenshteinDistance; -import org.apache.log4j.Logger; /** * Created by neukamm on 13.03.17. */ public class Functions { - private final Logger LOG; - - public Functions(Logger LOG){ - this.LOG = LOG; - } - - /** * Get the hamming distance between two string sequences * @@ -26,31 +17,6 @@ public Functions(Logger LOG){ public int getHammingDistance(String sequence1, String sequence2){ HammingDistance hammingDistance = new HammingDistance(); return hammingDistance.apply(sequence1, sequence2); -// int distance =0; -// if(sequence1 == null || sequence2==null) -// System.exit(1); -// -// sequence1 = sequence1.toUpperCase(); -// sequence2 = sequence2.toUpperCase(); -// -// if(sequence1.length() != sequence2.length()) -// { -// System.out.println("Functions:getHammingDistance(): Different length, please enter the strings with equal length."); -// } -// -// for(int i=0;i < sequence1.length();i++) -// { -// if(sequence1.charAt(i)!=sequence2.charAt(i)) -// distance++; -// } -// -// //System.out.println("Hamming Distance: " + distance); -// return distance; - } - public int getLevenshteinDistance(String sequence1, String sequence2){ - LevenshteinDistance levenshteinDistance = new LevenshteinDistance(); - return levenshteinDistance.apply(sequence1, sequence2); - } } diff --git a/src/main/java/org/damageprofiler/calculations/LengthDistribution.java b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java index 91390db..be6995c 100755 --- a/src/main/java/org/damageprofiler/calculations/LengthDistribution.java +++ b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java @@ -82,30 +82,10 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ } } - /* - * Getter - * + Getter */ - - public HashMap<Integer, Integer> getSeqLen(LengthDistribution lengthDistribution) { - - List<Integer> length_all = lengthDistribution.getLength_all(); - HashMap<Integer, Integer> map_length_occurrences_all = new HashMap<>(); - - for(double d : length_all){ - if(!map_length_occurrences_all.containsKey(d)){ - map_length_occurrences_all.put((int)d, 1); - } else { - int count = map_length_occurrences_all.get(d); - map_length_occurrences_all.put((int)d, count + 1); - } - } - return map_length_occurrences_all; - } - - public HashMap<Integer, Integer> getLength_distribution_map_forward() { return length_distribution_map_forward; } diff --git a/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java b/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java index b45c1b8..cc3c84a 100755 --- a/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java +++ b/src/main/java/org/damageprofiler/calculations/SpeciesHandler.java @@ -14,19 +14,26 @@ public class SpeciesHandler { private Logger LOG; private String gi; - private String species_name; + /** + * This class accesses NCBI to find the name of a species based on the RefSeqID. + */ public SpeciesHandler(){ } - public void getSpecies(String rname){ - if (rname != null) { + /** + * + * @param ref_name + */ + public String getSpecies(String ref_name){ + String species_name = ""; + if (ref_name != null) { String tax = ""; // get tax id from RNAME string - String[] rname_split = rname.split("\\|"); + String[] rname_split = ref_name.split("\\|"); for (int i = 0; i < rname_split.length; i++) { switch (rname_split[i]) { case "gi": @@ -45,9 +52,9 @@ public void getSpecies(String rname){ } if(!tax.equals("")){ species_name = getSpeciesByID(Integer.parseInt(tax)); - // specie_name = specie_name.replaceAll(" ", "_"); } } + return species_name; } @@ -96,16 +103,9 @@ private String getSpeciesByID(int id) { System.out.println("'Curl' is not installed. If you would like to use this option, please install it."); } - - return species; } - - public String getSpecies_name() { - return species_name; - } - public void setLOG(Logger LOG) { this.LOG = LOG; } diff --git a/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java index 8962140..c27ee39 100755 --- a/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java +++ b/src/main/java/org/damageprofiler/calculations/SpeciesListParser.java @@ -23,17 +23,11 @@ public SpeciesListParser(String speciesListFile, Logger LOG) { } - public String getSingleSpecies(String rname) { - - speciesHandler.getSpecies(rname); - return speciesHandler.getSpecies_name(); - } - - public List<String> getList() { - - return readFile(); - } - + /** + * Read file with species listed by the user. + * + * @return + */ private List<String> readFile() { try { @@ -41,15 +35,15 @@ private List<String> readFile() { FileReader fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader(fileReader); String line; - List<String> list = new ArrayList<>(); + List<String> list_species = new ArrayList<>(); while ((line = bufferedReader.readLine()) != null) { - list.add(line.trim()); + list_species.add(line.trim()); } fileReader.close(); - return list; + return list_species; } catch (IOException e) { e.printStackTrace(); } @@ -59,9 +53,18 @@ private List<String> readFile() { } + /* + Getter and Setter + */ public void setLOG(Logger LOG) { this.LOG = LOG; speciesHandler.setLOG(LOG); } + + + public List<String> getSpeciesList() { + + return readFile(); + } } diff --git a/src/main/java/org/damageprofiler/calculations/StartCalculations.java b/src/main/java/org/damageprofiler/calculations/StartCalculations.java index 1401c43..5720336 100755 --- a/src/main/java/org/damageprofiler/calculations/StartCalculations.java +++ b/src/main/java/org/damageprofiler/calculations/StartCalculations.java @@ -26,8 +26,6 @@ public class StartCalculations { private boolean calculationsDone = false; private Logger LOG; private List<String> specieslist = null; - private List<String> species_name_list; - private SpeciesListParser speciesListParser; private boolean use_only_merged_reads; private double height_damageplot; //= 0.4; // set yaxis height to 40% as default private int threshold; @@ -51,6 +49,7 @@ public class StartCalculations { private IndexedFastaSequenceFile fastaSequenceFile; private FastACacher cache; private HashMap<String, List<JFreeChart>> species_output_summary; + private HashMap<String, Integer> number_of_used_reads_summary; // plot settings @@ -71,6 +70,11 @@ public void setVERSION(String version){ VERSION = version; } + /** + * Start all calculations. + * @param c + * @throws Exception + */ public void start(Communicator c) throws Exception { currtime_prior_execution = System.currentTimeMillis(); @@ -89,8 +93,6 @@ public void start(Communicator c) throws Exception { use_only_merged_reads = c.isUse_merged_and_mapped_reads(); use_all_reads = c.isUse_all_reads(); ssLibProtocolUsed = c.isSsLibsProtocolUsed(); - speciesListParser=null; - species_name_list=null; color_DP_C_to_T = c.getColor_DP_C_to_T(); color_DP_G_to_A = c.getColor_DP_G_to_A(); @@ -113,13 +115,14 @@ public void start(Communicator c) throws Exception { if(specieslist_filepath != null){ species_output_summary = new HashMap<>(); + number_of_used_reads_summary = new HashMap<>(); speciesHandler = new SpeciesHandler(); /* parse species references (-sf) and run DP for each reference in the file */ specieslist = new ArrayList<>(); - specieslist.addAll(speciesListParser.getList()); + specieslist.addAll(speciesListParser.getSpeciesList()); for (int i = 0; i < specieslist.size(); i++) { @@ -143,11 +146,6 @@ parse species references (-sf) and run DP for each reference in the file initLogger(output_folder + "/DamageProfiler_" + ref + "_" + speciesname +".log", "Calculate damage profile for species " + ref + " (" + speciesname + ")"); - // decompress input file if necessary - if (input.endsWith(".gz")) { - Unzip unzip = new Unzip(LOG); - input = unzip.decompress(input); - } // create new output folder // log settings @@ -180,6 +178,10 @@ parse species references (-sf) and run DP for each reference in the file outputGenerator.getEditDist_chart(), outputGenerator.getLength_chart_all()) ); + + number_of_used_reads_summary.put( + spec_no_space + " (" + speciesname + ")", + damageProfiler.getNumberOfUsedReads()); } // generate metagenomic output summary @@ -188,7 +190,7 @@ parse species references (-sf) and run DP for each reference in the file String filename = splitted[splitted.length-1]; metagenomicOutput.generate(outfolder + File.separator + inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1], - species_output_summary, filename); + species_output_summary, filename, number_of_used_reads_summary); } else if(species_ref_identifier != null){ @@ -216,11 +218,6 @@ parse species reference (-s) and run DP // init Logger initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); - // decompress input file if necessary - if (input.endsWith(".gz")) { - Unzip unzip = new Unzip(LOG); - input = unzip.decompress(input); - } // log settings LOG.info("Analysis of file (-i):" + input + "\n" @@ -254,6 +251,7 @@ parse species reference (-s) and run DP */ String inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); + // create output folder based on file name createOutputFolder( outfolder, inputfileNameWithOutExtension.split("/")[inputfileNameWithOutExtension.split("/").length - 1]); @@ -263,13 +261,6 @@ parse species reference (-s) and run DP // init Logger initLogger(output_folder + "/DamageProfiler.log", "DamageProfiler v" + VERSION); - // decompress input file if necessary - if (input.endsWith(".gz")) { - Unzip unzip = new Unzip(LOG); - input = unzip.decompress(input); - } - - // create new output folder // log settings LOG.info("Analysis of file (-i):" + input + "\n" @@ -301,18 +292,6 @@ parse species reference (-s) and run DP calculationsDone=true; - // print runtime - long currtime_post_execution = System.currentTimeMillis(); - long diff = currtime_post_execution - currtime_prior_execution; - long runtime_s = diff / 1000; - if(runtime_s > 60) { - long minutes = runtime_s / 60; - long seconds = runtime_s % 60; - LOG.info("Runtime of Module was: " + minutes + " minutes, and " + seconds + " seconds.\n\n"); - } else { - LOG.info("Runtime of Module was: " + runtime_s + " seconds.\n\n"); - } - } private void initPlot() { @@ -335,6 +314,12 @@ private void initLogger(String outfolder, String log) { } + /** + * Generate output files. + * + * @throws IOException + * @throws DocumentException + */ private void generateOutput() throws IOException, DocumentException { if (damageProfiler.getNumberOfUsedReads() != 0) { diff --git a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java index ce8193f..2a9c5f5 100755 --- a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java +++ b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java @@ -342,7 +342,7 @@ protected Object call() throws Exception { } /** - * The following methods generate the result plots after successful damage profile org.damageprofiler.calculations. + * The following methods generate the result plots after successful damage profile calculations. * todo: if plot already created, just reload */ From a4c588574b395963f54e38f846744ee65fec1da8 Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Fri, 31 Jul 2020 14:55:21 +0200 Subject: [PATCH 21/22] change file name of identity to edit distance, put legend on the right sid of the plot (length dist.) --- src/main/java/org/damageprofiler/IO/OutputGenerator.java | 9 +++++++-- .../java/org/damageprofiler/IO/PDFoutput/Histogram.java | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/damageprofiler/IO/OutputGenerator.java b/src/main/java/org/damageprofiler/IO/OutputGenerator.java index 415ae6e..30d3b37 100755 --- a/src/main/java/org/damageprofiler/IO/OutputGenerator.java +++ b/src/main/java/org/damageprofiler/IO/OutputGenerator.java @@ -16,6 +16,8 @@ import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.apache.log4j.Logger; import org.jfree.chart.JFreeChart; +import org.jfree.chart.title.LegendTitle; +import org.jfree.chart.ui.RectangleEdge; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.xy.XYDataset; import org.jfree.graphics2d.svg.SVGGraphics2D; @@ -483,6 +485,9 @@ public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_f length_chart_separated = hist_separated.createChart(dataset_separated, "", "Read length", "Occurrences", x_axis_min_length_histo, x_axis_max_length_histo, true); + LegendTitle lt = length_chart_separated.getLegend(); + lt.setPosition(RectangleEdge.RIGHT); + createPdf("/Length_plot.pdf", new JFreeChart[]{length_chart_all, length_chart_separated}, file); createSVG("/Length_plot_combined_data.svg", length_chart_all); createSVG("/Length_plot_forward_reverse_separated.svg", length_chart_separated); @@ -506,8 +511,8 @@ public void plotEditDistanceHistogram(List<Integer> distances, String title, Str HistogramDataset dataset = hist_all.createDataset(new String[]{title}, 100); editDist_chart = hist_all.createChart(dataset, "", "Edit distance", "Occurrences", x_axis_min_id_histo, x_axis_max_id_histo, false); - createPdf("/identity_histogram.pdf", new JFreeChart[]{editDist_chart}, file); - createSVG("/identity_histogram.svg", editDist_chart); + createPdf("/edit_distance.pdf", new JFreeChart[]{editDist_chart}, file); + createSVG("/edit_distance.svg", editDist_chart); } diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java index f5f053a..68f5103 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java @@ -7,6 +7,8 @@ import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYBarRenderer; +import org.jfree.chart.title.LegendTitle; +import org.jfree.chart.ui.RectangleEdge; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.statistics.HistogramType; From 988f878fe7c13f36b619b0fd76de0a7cbeaf4d2e Mon Sep 17 00:00:00 2001 From: JudithNeukamm <judith.neukamm@uzh.ch> Date: Tue, 4 Aug 2020 17:29:06 +0200 Subject: [PATCH 22/22] refactoring | adapting CLI and GUI options --- build.gradle | 4 - src/main/java/StarterGUI.java | 4 +- .../GUI/DamageProfilerMainGUI.java | 2 +- .../AdvancedCalculationOptionsDialogue.java | 4 - .../AdvancedPlottingOptionsDialogue.java | 43 +- .../GUI/Dialogues/ConfigurationDialogue.java | 5 + .../TabAdvancedSettingsDamagePlot.java | 57 ++- .../TabAdvancedSettingsEditdistance.java | 22 - ...TabAdvancedSettingsLengthDistribution.java | 22 - .../org/damageprofiler/IO/Communicator.java | 14 +- .../damageprofiler/IO/OutputGenerator.java | 415 ++++++++---------- .../IO/PDFoutput/Histogram.java | 12 +- .../damageprofiler/IO/PDFoutput/LinePlot.java | 6 +- .../damageprofiler/IO/UserOptionsParser.java | 50 +-- .../calculations/DamageProfiler.java | 16 +- .../calculations/LengthDistribution.java | 22 +- .../calculations/StartCalculations.java | 1 - .../DamageProfilerMainController.java | 72 ++- .../controller/PlottingSettingController.java | 25 ++ 19 files changed, 345 insertions(+), 451 deletions(-) delete mode 100755 src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java delete mode 100755 src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java delete mode 100755 src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java create mode 100644 src/main/java/org/damageprofiler/controller/PlottingSettingController.java diff --git a/build.gradle b/build.gradle index a1ba6fa..6af0c94 100755 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,6 @@ repositories { modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics', 'javafx.base', 'javafx.media', 'javafx.swing','javafx.web'] } - mainClassName = "RunDamageProfiler" - dependencies { compile group: 'log4j', name: 'log4j', version: '1.+' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.+' @@ -33,8 +31,6 @@ dependencies { compile 'org.jfree:jfreechart-fx:1.+' } - - jar { manifest { attributes 'Main-Class': 'RunDamageProfiler' diff --git a/src/main/java/StarterGUI.java b/src/main/java/StarterGUI.java index bf0862d..e37b4e0 100755 --- a/src/main/java/StarterGUI.java +++ b/src/main/java/StarterGUI.java @@ -1,5 +1,6 @@ import org.damageprofiler.controller.DamageProfilerMainController; import org.damageprofiler.GUI.DamageProfilerMainGUI; +import org.damageprofiler.controller.PlottingSettingController; import org.damageprofiler.controller.ProgressBarController; import javafx.application.Application; import javafx.stage.Stage; @@ -18,7 +19,8 @@ public void start(Stage primaryStage) { DamageProfilerMainGUI damageProfilerMainGUI = new DamageProfilerMainGUI(VERSION, progressBarController); damageProfilerMainGUI.init(primaryStage); - DamageProfilerMainController damageProfilerMainController = new DamageProfilerMainController(damageProfilerMainGUI, progressBarController); + PlottingSettingController plottingSettingController = new PlottingSettingController(); + new DamageProfilerMainController(damageProfilerMainGUI, progressBarController, plottingSettingController); } diff --git a/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java b/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java index 47b4e81..f1f096e 100755 --- a/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java +++ b/src/main/java/org/damageprofiler/GUI/DamageProfilerMainGUI.java @@ -73,7 +73,7 @@ private VBox generateLeftPane() { btn_leftpane_info = new Button("Run Configuration"); btn_help = new Button("Show help"); btn_leftpane_lengthDist = new Button("Length Distribution"); - btn_leftpane_identityDist = new Button("Identity Distribution"); + btn_leftpane_identityDist = new Button("Edit distance"); // style buttons btn_leftpane_info.setPrefHeight(30); diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java deleted file mode 100755 index 62f87fc..0000000 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedCalculationOptionsDialogue.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.damageprofiler.GUI.Dialogues; - -public class AdvancedCalculationOptionsDialogue { -} diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java index 8ed2f65..8f52061 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/AdvancedPlottingOptionsDialogue.java @@ -7,62 +7,39 @@ public class AdvancedPlottingOptionsDialogue { private TabPane tabPane; - private Tab tab_Length_Dist; - private Tab tab_Edit_Dist; private Tab tab_DP; - private TabAdvancedSettingsLengthDistribution tabAdvancedSettingsLengthDistribution; private TabAdvancedSettingsDamagePlot tabAdvancedSettingsDamagePlot; - private TabAdvancedSettingsEditdistance tabAdvancedSettingsEditdistance; + /** + * Tab for the configuration of all colours of the damage patterns + */ public AdvancedPlottingOptionsDialogue(){ fill(); } + /** + * Fill the empty tab pane with all components + */ private void fill() { tabAdvancedSettingsDamagePlot = new TabAdvancedSettingsDamagePlot("Damage Profile"); tab_DP = tabAdvancedSettingsDamagePlot.getTab(); - tabAdvancedSettingsEditdistance = new TabAdvancedSettingsEditdistance("Edit Distance"); - tab_Edit_Dist = tabAdvancedSettingsEditdistance.getTab(); - - tabAdvancedSettingsLengthDistribution = new TabAdvancedSettingsLengthDistribution("Length Distribution"); - tab_Length_Dist = tabAdvancedSettingsLengthDistribution.getTab(); - tabPane = new TabPane(); - tabPane.getTabs().addAll(tab_DP,tab_Edit_Dist, tab_Length_Dist); + tabPane.getTabs().addAll(tab_DP); } - - + /* + Getter + */ public TabPane getGridPane() { return tabPane; } - - public Tab getTab_Length_Dist() { - return tab_Length_Dist; - } - - public Tab getTab_Edit_Dist() { - return tab_Edit_Dist; - } - - public Tab getTab_DP() { - return tab_DP; - } - public TabAdvancedSettingsDamagePlot getTabAdvancedSettingsDamagePlot() { return tabAdvancedSettingsDamagePlot; } - public TabAdvancedSettingsLengthDistribution getTabAdvancedSettingsLengthDistribution() { - return tabAdvancedSettingsLengthDistribution; - } - - public TabAdvancedSettingsEditdistance getTabAdvancedSettingsEditdistance() { - return tabAdvancedSettingsEditdistance; - } } diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java index 47f6ba1..ddcc4fe 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/ConfigurationDialogue.java @@ -92,6 +92,7 @@ private void addComponents() { TitledPane pane_advanced_plotting_options = new TitledPane(); pane_advanced_plotting_options.setText("Advanced options (Plotting)"); + advancedPlottingOptionsDialogue = new AdvancedPlottingOptionsDialogue(); pane_advanced_plotting_options.setContent(advancedPlottingOptionsDialogue.getGridPane()); pane_advanced_plotting_options.setExpanded(false); @@ -197,6 +198,10 @@ public TextField getTextfield_title() { return textfield_title; } + public void setTextfield_title(String textfield_title) { + this.textfield_title.setText(textfield_title); + } + public TextField getTextfield_y_axis_height() { return textfield_y_axis_height; } diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java index 4f5bf8c..dd67833 100755 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java +++ b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsDamagePlot.java @@ -20,6 +20,11 @@ public class TabAdvancedSettingsDamagePlot { private Button btn_reset; private GridPane gridpane; + /** + * Tab pane to configure the visualization of the damage profile + * (misincorporation frequencies) + * @param title + */ public TabAdvancedSettingsDamagePlot(String title){ this.tab = new Tab(title); @@ -31,21 +36,20 @@ public TabAdvancedSettingsDamagePlot(String title){ generateColorPicker(Color.GREEN), generateColorPicker(Color.GREY)); - addListener(); } - private void addListener() { - this.btn_reset.setOnAction(e ->{ - gridpane.getChildren().clear(); - fill( generateColorPicker(Color.RED), - generateColorPicker(Color.BLUE), - generateColorPicker(Color.valueOf("FF00FF")), - generateColorPicker(Color.GREEN), - generateColorPicker(Color.GREY)); - }); - } - private void fill(ColorPicker c_t, ColorPicker g_a, ColorPicker insertions, ColorPicker deletions, ColorPicker others) { + + /** + * Fill grid pane with all components + * + * @param c_t + * @param g_a + * @param insertions + * @param deletions + * @param others + */ + public void fill(ColorPicker c_t, ColorPicker g_a, ColorPicker insertions, ColorPicker deletions, ColorPicker others) { gridpane = new GridPane(); gridpane.setAlignment(Pos.BOTTOM_LEFT); gridpane.setHgap(7); @@ -80,11 +84,20 @@ private void fill(ColorPicker c_t, ColorPicker g_a, ColorPicker insertions, Colo } - private ColorPicker generateColorPicker(Color color) { + /** + * Generate and return color picker + * + * @param color + * @return + */ + public ColorPicker generateColorPicker(Color color) { ColorPickerPane colorPickerPane = new ColorPickerPane(color); return colorPickerPane.getPicker(); } + /* + Getter + */ public Tab getTab() { return tab; } @@ -109,4 +122,22 @@ public ColorPicker getColorPicker_others() { return colorPicker_others; } + public Button getBtn_reset() { + return btn_reset; + } + + public GridPane getGridpane() { + return gridpane; + } + + public void reset() { + + this.gridpane.getChildren().clear(); + fill( generateColorPicker(Color.RED), + generateColorPicker(Color.BLUE), + generateColorPicker(Color.valueOf("FF00FF")), + generateColorPicker(Color.GREEN), + generateColorPicker(Color.GREY)); + + } } diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java deleted file mode 100755 index 4642b14..0000000 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsEditdistance.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.damageprofiler.GUI.Dialogues; - -import javafx.scene.control.Tab; - -public class TabAdvancedSettingsEditdistance { - - private final Tab tab; - - public TabAdvancedSettingsEditdistance(String title){ - this.tab = new Tab(title); - fill(); - } - - private void fill() { - - } - - public Tab getTab() { - - return tab; - } -} diff --git a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java b/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java deleted file mode 100755 index e6a8daa..0000000 --- a/src/main/java/org/damageprofiler/GUI/Dialogues/TabAdvancedSettingsLengthDistribution.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.damageprofiler.GUI.Dialogues; - -import javafx.scene.control.Tab; - -public class TabAdvancedSettingsLengthDistribution { - - private final Tab tab; - - public TabAdvancedSettingsLengthDistribution(String title){ - this.tab = new Tab(title); - fill(); - } - - private void fill() { - - } - - public Tab getTab() { - - return tab; - } -} diff --git a/src/main/java/org/damageprofiler/IO/Communicator.java b/src/main/java/org/damageprofiler/IO/Communicator.java index ad81a72..faf04db 100755 --- a/src/main/java/org/damageprofiler/IO/Communicator.java +++ b/src/main/java/org/damageprofiler/IO/Communicator.java @@ -16,11 +16,11 @@ public class Communicator { // damage calculation private int threshold = 25; - private double yAxis_damageplot=0.4; - private double xaxis_histo_id_min =-1; - private double xaxis_histo_id_max =-1; - private double xaxis_histo_length_min=-1; - private double xaxis_histo_length_max=-1; + private double yAxis_damageplot = 0.4; + private double xaxis_histo_id_min = -1; + private double xaxis_histo_id_max = -1; + private double xaxis_histo_length_min = -1; + private double xaxis_histo_length_max = -1; private int length = 100; private boolean use_merged_and_mapped_reads = false; private boolean use_all_reads = false; @@ -134,7 +134,6 @@ public void setSpecieslist_filepath(String specieslist_filepath) { this.specieslist_filepath = specieslist_filepath; } - public double getXaxis_histo_id_min() { return xaxis_histo_id_min; } @@ -169,7 +168,6 @@ public void setXaxis_histo_length_max(double xaxis_histo_length_max) { public void setColor_DP_C_to_T(Color color_c_to_t) { this.color_DP_C_to_T = color_c_to_t; - } public void setColor_DP_G_to_A(Color color_g_to_a) { @@ -186,7 +184,6 @@ public void setColor_DP_deletions(Color color_deletions) { public void setColor_DP_other(Color color_other) { this.color_DP_other = color_other; - } public Color getColor_DP_C_to_T() { @@ -208,4 +205,5 @@ public Color getColor_DP_deletions() { public Color getColor_DP_other() { return color_DP_other; } + } diff --git a/src/main/java/org/damageprofiler/IO/OutputGenerator.java b/src/main/java/org/damageprofiler/IO/OutputGenerator.java index 30d3b37..3a9ae86 100755 --- a/src/main/java/org/damageprofiler/IO/OutputGenerator.java +++ b/src/main/java/org/damageprofiler/IO/OutputGenerator.java @@ -52,8 +52,8 @@ public class OutputGenerator { private Frequencies frequencies; private DamageProfiler damageProfiler; private int numberOfRecords; - private int max_length; - private int min_length; + private double max_length; + private double min_length; private String species; private int threshold; private int length; @@ -151,8 +151,8 @@ public void writeJSON(String version) throws IOException { public void writeLengthDistribution() throws IOException{ BufferedWriter lgdist = new BufferedWriter(new FileWriter(this.outpath + "/lgdistribution.txt")); - HashMap<Integer, Integer> map_forward = damageProfiler.getLength_distribution_map_forward(); - HashMap<Integer, Integer> map_reverse = damageProfiler.getLength_distribution_map_reverse(); + HashMap<Double, Integer> map_forward = damageProfiler.getLength_distribution_map_forward(); + HashMap<Double, Integer> map_reverse = damageProfiler.getLength_distribution_map_reverse(); lgdist.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); lgdist.write("# using mapped file " + input + "\n"); @@ -162,17 +162,17 @@ public void writeLengthDistribution() throws IOException{ // fill file - List<Integer> key_list = new ArrayList<>(); + List<Double> key_list = new ArrayList<>(); key_list.addAll(map_forward.keySet()); Collections.sort(key_list); - HashMap<Integer,Integer> yaml_dump_fw = new HashMap<>(); + HashMap<Double,Integer> yaml_dump_fw = new HashMap<>(); if(key_list.size()>0){ min_length = key_list.get(0); max_length = key_list.get(key_list.size()-1); - for(int key : key_list){ + for(double key : key_list){ lgdist.write("+\t" + key + "\t" + map_forward.get(key) + "\n"); yaml_dump_fw.put(key, map_forward.get(key)); } @@ -183,7 +183,7 @@ public void writeLengthDistribution() throws IOException{ key_list.addAll(map_reverse.keySet()); Collections.sort(key_list); - HashMap<Integer,Integer> yaml_dump_rv = new HashMap<>(); + HashMap<Double,Integer> yaml_dump_rv = new HashMap<>(); if(key_list.size()>0){ @@ -194,7 +194,7 @@ public void writeLengthDistribution() throws IOException{ max_length = key_list.get(key_list.size()-1); } - for(int key : key_list){ + for(double key : key_list){ lgdist.write("-\t" + key + "\t" + map_reverse.get(key) + "\n"); yaml_dump_rv.put(key, map_reverse.get(key)); } @@ -265,29 +265,27 @@ public void writeDNAComp(Frequencies frequencies) throws IOException{ // write header freq_file_sample.write("End\tStd\tPos\tA\tC\tG\tT\tTotal\n"); - if(!ssLibProtocolUsed){ - // fill '3p +' - for(int i = 0; i < this.length; i++){ - double sum=frequencies.getCount_total_forward_3()[i]; + // fill '3p +' + for(int i = 0; i < this.length; i++){ + double sum=frequencies.getCount_total_forward_3()[i]; - freq_file_sample.write("3p\t+\t"+(i+1)+"\t" - +(int)frequencies.getCountA_forward_3()[i]+"\t"+(int)frequencies.getCountC_forward_3()[i]+"\t" - +(int)frequencies.getCountG_forward_3()[i]+"\t"+(int)frequencies.getCountT_forward_3()[i]+"\t" - +(int)sum+"\n" - ); + freq_file_sample.write("3p\t+\t"+(i+1)+"\t" + +(int)frequencies.getCountA_forward_3()[i]+"\t"+(int)frequencies.getCountC_forward_3()[i]+"\t" + +(int)frequencies.getCountG_forward_3()[i]+"\t"+(int)frequencies.getCountT_forward_3()[i]+"\t" + +(int)sum+"\n" + ); - } + } - // fill '3p -' - for(int i = 0; i < this.length; i++){ - double sum = frequencies.getCount_total_reverse_3()[i]; + // fill '3p -' + for(int i = 0; i < this.length; i++){ + double sum = frequencies.getCount_total_reverse_3()[i]; - freq_file_sample.write("3p\t-\t"+(i+1)+"\t" - +(int)frequencies.getCountA_reverse_3()[i]+"\t"+(int)frequencies.getCountC_reverse_3()[i]+"\t" - +(int)frequencies.getCountG_reverse_3()[i]+"\t"+(int)frequencies.getCountT_reverse_3()[i]+"\t" - +(int)sum+"\n" - ); - } + freq_file_sample.write("3p\t-\t"+(i+1)+"\t" + +(int)frequencies.getCountA_reverse_3()[i]+"\t"+(int)frequencies.getCountC_reverse_3()[i]+"\t" + +(int)frequencies.getCountG_reverse_3()[i]+"\t"+(int)frequencies.getCountT_reverse_3()[i]+"\t" + +(int)sum+"\n" + ); } @@ -344,59 +342,58 @@ public void writeFrequenciesReference(Frequencies frequencies) throws IOExceptio // write header freq_file_ref.write("Chr\tEnd\tStd\tPos\tA\tC\tG\tT\tTotal\tG>A\tC>T\tA>G\tT>C\tA>C\tA>T\tC>G\tC>A\tT>G\tT>A\tG>C\tG>T\tA>-\tT>-\tC>-\tG>-\t->A\t->T\t->C\t->G\tS\n"); - if(!ssLibProtocolUsed){ - // fill '3p +' - for(int i = 0; i < this.length; i++){ - double sum=frequencies.getCountA_ref_forward_3()[i]+frequencies.getCountC_ref_forward_3()[i]+ - frequencies.getCountG_ref_forward_3()[i]+frequencies.getCountT_ref_forward_3()[i]; - - if(this.numberOfUsedReads>0){ - freq_file_ref.write("fwd\t3p\t+\t"+(i+1)+"\t" - +frequencies.getCountA_ref_forward_3()[i]+"\t"+frequencies.getCountC_ref_forward_3()[i]+"\t" - +frequencies.getCountG_ref_forward_3()[i]+"\t"+frequencies.getCountT_ref_forward_3()[i]+"\t" - +sum+"\t" - +frequencies.getCount_forward_G_A_3()[i]+"\t"+frequencies.getCount_forward_C_T_3()[i]+"\t" - +frequencies.getCount_forward_A_G_3()[i]+"\t"+frequencies.getCount_forward_T_C_3()[i]+"\t" - +frequencies.getCount_forward_A_C_3()[i]+"\t"+frequencies.getCount_forward_A_T_3()[i]+"\t" - +frequencies.getCount_forward_C_G_3()[i]+"\t"+frequencies.getCount_forward_C_A_3()[i]+"\t" - +frequencies.getCount_forward_T_G_3()[i]+"\t"+frequencies.getCount_forward_T_A_3()[i]+"\t" - +frequencies.getCount_forward_G_C_3()[i]+"\t"+frequencies.getCount_forward_G_T_3()[i]+"\t" - +frequencies.getCount_forward_A_0_3()[i]+"\t"+frequencies.getCount_forward_T_0_3()[i]+"\t" - +frequencies.getCount_forward_C_0_3()[i]+"\t"+frequencies.getCount_forward_G_0_3()[i]+"\t" - +frequencies.getCount_forward_0_A_3()[i]+"\t"+frequencies.getCount_forward_0_T_3()[i]+"\t" - +frequencies.getCount_forward_0_C_3()[i]+"\t"+frequencies.getCount_forward_0_G_3()[i]+"\t" - +frequencies.getCountS_forward_3()[i]+"\n" - ); - } - } + // fill '3p +' + for(int i = 0; i < this.length; i++){ + double sum=frequencies.getCountA_ref_forward_3()[i]+frequencies.getCountC_ref_forward_3()[i]+ + frequencies.getCountG_ref_forward_3()[i]+frequencies.getCountT_ref_forward_3()[i]; - // fill '3p -' - for(int i = 0; i < this.length; i++){ - double sum = frequencies.getCountA_ref_reverse_3()[i]+frequencies.getCountC_ref_reverse_3()[i]+ - frequencies.getCountG_ref_reverse_3()[i]+frequencies.getCountT_ref_reverse_3()[i]; - - if(this.numberOfUsedReads>0){ - freq_file_ref.write("rev\t3p\t-\t"+(i+1)+"\t" - +frequencies.getCountA_ref_reverse_3()[i]+"\t"+frequencies.getCountC_ref_reverse_3()[i]+"\t" - +frequencies.getCountG_ref_reverse_3()[i]+"\t"+frequencies.getCountT_ref_reverse_3()[i]+"\t" - +sum+"\t" - +frequencies.getCount_reverse_G_A_3()[i]+"\t"+frequencies.getCount_reverse_C_T_3()[i]+"\t" - +frequencies.getCount_reverse_A_G_3()[i]+"\t"+frequencies.getCount_reverse_T_C_3()[i]+"\t" - +frequencies.getCount_reverse_A_C_3()[i]+"\t"+frequencies.getCount_reverse_A_T_3()[i]+"\t" - +frequencies.getCount_reverse_C_G_3()[i]+"\t"+frequencies.getCount_reverse_C_A_3()[i]+"\t" - +frequencies.getCount_reverse_T_G_3()[i]+"\t"+frequencies.getCount_reverse_T_A_3()[i]+"\t" - +frequencies.getCount_reverse_G_C_3()[i]+"\t"+frequencies.getCount_reverse_G_T_3()[i] - +frequencies.getCount_reverse_A_0_3()[i]+"\t"+frequencies.getCount_reverse_T_0_3()[i]+"\t" - +frequencies.getCount_reverse_C_0_3()[i]+"\t"+frequencies.getCount_reverse_G_0_3()[i]+"\t" - +frequencies.getCount_reverse_0_A_3()[i]+"\t"+frequencies.getCount_reverse_0_T_3()[i]+"\t" - +frequencies.getCount_reverse_0_C_3()[i]+"\t"+frequencies.getCount_reverse_0_G_3()[i]+"\t" - +frequencies.getCountS_reverse_3()[i]+"\n" - ); - } + if(this.numberOfUsedReads>0){ + freq_file_ref.write("fwd\t3p\t+\t"+(i+1)+"\t" + +frequencies.getCountA_ref_forward_3()[i]+"\t"+frequencies.getCountC_ref_forward_3()[i]+"\t" + +frequencies.getCountG_ref_forward_3()[i]+"\t"+frequencies.getCountT_ref_forward_3()[i]+"\t" + +sum+"\t" + +frequencies.getCount_forward_G_A_3()[i]+"\t"+frequencies.getCount_forward_C_T_3()[i]+"\t" + +frequencies.getCount_forward_A_G_3()[i]+"\t"+frequencies.getCount_forward_T_C_3()[i]+"\t" + +frequencies.getCount_forward_A_C_3()[i]+"\t"+frequencies.getCount_forward_A_T_3()[i]+"\t" + +frequencies.getCount_forward_C_G_3()[i]+"\t"+frequencies.getCount_forward_C_A_3()[i]+"\t" + +frequencies.getCount_forward_T_G_3()[i]+"\t"+frequencies.getCount_forward_T_A_3()[i]+"\t" + +frequencies.getCount_forward_G_C_3()[i]+"\t"+frequencies.getCount_forward_G_T_3()[i]+"\t" + +frequencies.getCount_forward_A_0_3()[i]+"\t"+frequencies.getCount_forward_T_0_3()[i]+"\t" + +frequencies.getCount_forward_C_0_3()[i]+"\t"+frequencies.getCount_forward_G_0_3()[i]+"\t" + +frequencies.getCount_forward_0_A_3()[i]+"\t"+frequencies.getCount_forward_0_T_3()[i]+"\t" + +frequencies.getCount_forward_0_C_3()[i]+"\t"+frequencies.getCount_forward_0_G_3()[i]+"\t" + +frequencies.getCountS_forward_3()[i]+"\n" + ); } + } + // fill '3p -' + for(int i = 0; i < this.length; i++){ + double sum = frequencies.getCountA_ref_reverse_3()[i]+frequencies.getCountC_ref_reverse_3()[i]+ + frequencies.getCountG_ref_reverse_3()[i]+frequencies.getCountT_ref_reverse_3()[i]; + + if(this.numberOfUsedReads>0){ + freq_file_ref.write("rev\t3p\t-\t"+(i+1)+"\t" + +frequencies.getCountA_ref_reverse_3()[i]+"\t"+frequencies.getCountC_ref_reverse_3()[i]+"\t" + +frequencies.getCountG_ref_reverse_3()[i]+"\t"+frequencies.getCountT_ref_reverse_3()[i]+"\t" + +sum+"\t" + +frequencies.getCount_reverse_G_A_3()[i]+"\t"+frequencies.getCount_reverse_C_T_3()[i]+"\t" + +frequencies.getCount_reverse_A_G_3()[i]+"\t"+frequencies.getCount_reverse_T_C_3()[i]+"\t" + +frequencies.getCount_reverse_A_C_3()[i]+"\t"+frequencies.getCount_reverse_A_T_3()[i]+"\t" + +frequencies.getCount_reverse_C_G_3()[i]+"\t"+frequencies.getCount_reverse_C_A_3()[i]+"\t" + +frequencies.getCount_reverse_T_G_3()[i]+"\t"+frequencies.getCount_reverse_T_A_3()[i]+"\t" + +frequencies.getCount_reverse_G_C_3()[i]+"\t"+frequencies.getCount_reverse_G_T_3()[i] + +frequencies.getCount_reverse_A_0_3()[i]+"\t"+frequencies.getCount_reverse_T_0_3()[i]+"\t" + +frequencies.getCount_reverse_C_0_3()[i]+"\t"+frequencies.getCount_reverse_G_0_3()[i]+"\t" + +frequencies.getCount_reverse_0_A_3()[i]+"\t"+frequencies.getCount_reverse_0_T_3()[i]+"\t" + +frequencies.getCount_reverse_0_C_3()[i]+"\t"+frequencies.getCount_reverse_0_G_3()[i]+"\t" + +frequencies.getCountS_reverse_3()[i]+"\n" + ); + } } + + // fill '5p +' for(int i = 0; i < this.length; i++){ double sum = frequencies.getCountA_ref_forward_5()[i]+frequencies.getCountC_ref_forward_5()[i]+ @@ -465,7 +462,7 @@ public void writeFrequenciesReference(Frequencies frequencies) throws IOExceptio * @throws IOException * @throws DocumentException */ - public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_forward, List<Integer> length_reverse, + public void plotLengthHistogram(List<Double> length_all, List<Double> length_forward, List<Double> length_reverse, String file) throws IOException, DocumentException { Histogram hist_all = new Histogram(LOG); @@ -504,13 +501,14 @@ public void plotLengthHistogram(List<Integer> length_all, List<Integer> length_f * @throws DocumentException * @throws IOException */ - public void plotEditDistanceHistogram(List<Integer> distances, String title, String file) throws DocumentException, IOException{ + public void plotEditDistanceHistogram(List<Double> distances, String title, String file) throws DocumentException, IOException{ Histogram hist_all = new Histogram(LOG); hist_all.addData(distances); HistogramDataset dataset = hist_all.createDataset(new String[]{title}, 100); editDist_chart = hist_all.createChart(dataset, "", "Edit distance", "Occurrences", x_axis_min_id_histo, x_axis_max_id_histo, false); + createPdf("/edit_distance.pdf", new JFreeChart[]{editDist_chart}, file); createSVG("/edit_distance.svg", editDist_chart); @@ -538,16 +536,15 @@ public void writeDamageFiles(double[] gToA_reverse, double[] cToT) throws IOExce json_map.put("dmg_3p",getSubArray(gToA_reverse,this.threshold)); - if(!ssLibProtocolUsed){ - writer3Prime = new BufferedWriter(new FileWriter(this.outpath + "/3pGtoA_freq.txt")); - writer3Prime.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); - writer3Prime.write("# using mapped file " + input + "\n"); - writer3Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - writeDamagePattern("pos\t3pG>A\n", getSubArray(gToA_reverse, this.threshold), writer3Prime); - writer3Prime.close(); - } + writer3Prime = new BufferedWriter(new FileWriter(this.outpath + "/3pGtoA_freq.txt")); + writer3Prime.write("# table produced by DamageProfiler\n"); + writer3Prime.write("# using mapped file " + input + "\n"); + writer3Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); + writeDamagePattern("pos\t3pG>A\n", getSubArray(gToA_reverse, this.threshold), writer3Prime); + writer3Prime.close(); + - writer5Prime.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); + writer5Prime.write("# table produced by DamageProfiler\n"); writer5Prime.write("# using mapped file " + input + "\n"); writer5Prime.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); writeDamagePattern("pos\t5pC>T\n", getSubArray(cToT, this.threshold), writer5Prime); @@ -571,20 +568,20 @@ private void writeDamagePattern(String title, double[] values, BufferedWriter wr } public void computeSummaryMetrics(){ - HashMap<Integer,Integer> forwardMap = damageProfiler.getLength_distribution_map_forward(); // key = length, value = occurrences - HashMap<Integer, Integer>reverseMap = damageProfiler.getLength_distribution_map_reverse(); + HashMap<Double,Integer> forwardMap = damageProfiler.getLength_distribution_map_forward(); // key = length, value = occurrences + HashMap<Double, Integer>reverseMap = damageProfiler.getLength_distribution_map_reverse(); //Create ArrayList<Integer> of read lengths DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(); - for (int key : forwardMap.keySet()){ + for (double key : forwardMap.keySet()){ int occurences = forwardMap.get(key); for (int i = 0; i <= occurences; i++) { descriptiveStatistics.addValue(key); } } - for (int key : reverseMap.keySet()){ + for (double key : reverseMap.keySet()){ int occurences = reverseMap.get(key); for (int i = 0; i <= occurences; i++) { descriptiveStatistics.addValue(key); @@ -678,74 +675,73 @@ public void writeMisincorporations(Frequencies frequencies, int threshold) throw 3 prime end */ - if(!ssLibProtocolUsed){ - BufferedWriter writer3PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/3p_freq_misincorporations.txt")); - writer3PrimeAll.write("# table produced by org.damageprofiler.calculations.DamageProfiler\n"); - writer3PrimeAll.write("# using mapped file " + input + "\n"); - writer3PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); + BufferedWriter writer3PrimeAll = new BufferedWriter(new FileWriter(this.outpath + "/3p_freq_misincorporations.txt")); + writer3PrimeAll.write("# table produced by DamageProfiler\n"); + writer3PrimeAll.write("# using mapped file " + input + "\n"); + writer3PrimeAll.write("# Sample ID: " + input.split("/")[input.split("/").length-1] + "\n"); - double[] three_A_to_C_reverse = getSubArray(frequencies.getCount_A_C_3_norm(),threshold); - double[] three_A_to_G_reverse = getSubArray(frequencies.getCount_A_G_3_norm(),threshold); - double[] three_A_to_T_reverse = getSubArray(frequencies.getCount_A_T_3_norm(),threshold); + double[] three_A_to_C_reverse = getSubArray(frequencies.getCount_A_C_3_norm(),threshold); + double[] three_A_to_G_reverse = getSubArray(frequencies.getCount_A_G_3_norm(),threshold); + double[] three_A_to_T_reverse = getSubArray(frequencies.getCount_A_T_3_norm(),threshold); - double[] three_C_to_A_reverse = getSubArray(frequencies.getCount_C_A_3_norm(), threshold); - double[] three_C_to_G_reverse = getSubArray(frequencies.getCount_C_G_3_norm(), threshold); - double[] three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); + double[] three_C_to_A_reverse = getSubArray(frequencies.getCount_C_A_3_norm(), threshold); + double[] three_C_to_G_reverse = getSubArray(frequencies.getCount_C_G_3_norm(), threshold); + double[] three_C_to_T_reverse = getSubArray(frequencies.getCount_C_T_3_norm(), threshold); - double[] three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); - double[] three_G_to_C_reverse = getSubArray(frequencies.getCount_G_C_3_norm(),threshold); - double[] three_G_to_T_reverse = getSubArray(frequencies.getCount_G_T_3_norm(),threshold); + double[] three_G_to_A_reverse = getSubArray(frequencies.getCount_G_A_3_norm(),threshold); + double[] three_G_to_C_reverse = getSubArray(frequencies.getCount_G_C_3_norm(),threshold); + double[] three_G_to_T_reverse = getSubArray(frequencies.getCount_G_T_3_norm(),threshold); - double[] three_T_to_A_reverse = getSubArray(frequencies.getCount_T_A_3_norm(),threshold); - double[] three_T_to_C_reverse = getSubArray(frequencies.getCount_T_C_3_norm(),threshold); - double[] three_T_to_G_reverse = getSubArray(frequencies.getCount_T_G_3_norm(),threshold); + double[] three_T_to_A_reverse = getSubArray(frequencies.getCount_T_A_3_norm(),threshold); + double[] three_T_to_C_reverse = getSubArray(frequencies.getCount_T_C_3_norm(),threshold); + double[] three_T_to_G_reverse = getSubArray(frequencies.getCount_T_G_3_norm(),threshold); - double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), - frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); + double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), + frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); - // green (deletions) - double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , - frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); - // write header - writer3PrimeAll.write("Pos\tC>T\tG>A\tA>C\tA>G\tA>T\tC>A\tC>G\tG>C\tG>T\tT>A\tT>C\tT>G\t" + - "->ACGT\tACGT>-\n"); + // green (deletions) + double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , + frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); + // write header + writer3PrimeAll.write("Pos\tC>T\tG>A\tA>C\tA>G\tA>T\tC>A\tC>G\tG>C\tG>T\tT>A\tT>C\tT>G\t" + + "->ACGT\tACGT>-\n"); - for(int pos = threshold-1; pos >=0; pos--){ + for(int pos = threshold-1; pos >=0; pos--){ + + writer3PrimeAll.write(pos + "\t" + + String.format("%.6f", three_C_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_A_reverse[pos])+ "\t" + + String.format("%.6f", three_A_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_A_to_G_reverse[pos]) + "\t" + + String.format("%.6f", three_A_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_C_to_A_reverse[pos]) + "\t" + + String.format("%.6f", three_C_to_G_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_G_to_T_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_A_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_C_reverse[pos]) + "\t" + + String.format("%.6f", three_T_to_G_reverse[pos]) + "\t" + + String.format("%.6f", insertions_mean_3[pos]) + "\t" + + String.format("%.6f", deletions_mean_3[pos]) + "\n"); - writer3PrimeAll.write(pos + "\t" + - String.format("%.6f", three_C_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_A_reverse[pos])+ "\t" + - String.format("%.6f", three_A_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_A_to_G_reverse[pos]) + "\t" + - String.format("%.6f", three_A_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_C_to_A_reverse[pos]) + "\t" + - String.format("%.6f", three_C_to_G_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_G_to_T_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_A_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_C_reverse[pos]) + "\t" + - String.format("%.6f", three_T_to_G_reverse[pos]) + "\t" + - String.format("%.6f", insertions_mean_3[pos]) + "\t" + - String.format("%.6f", deletions_mean_3[pos]) + "\n"); + } - } + writer3PrimeAll.close(); - writer3PrimeAll.close(); - } } - public void writeEditDistance(List<Integer> editDistances) throws IOException { + public void writeEditDistance(List<Double> editDistances) throws IOException { Collections.sort(editDistances); - Set<Integer> distances_sorted = new HashSet<Integer>(editDistances); - HashMap<Integer, Integer> edit_occurrences_map = new HashMap<>(); - for(int dist : distances_sorted){ + Set<Double> distances_sorted = new HashSet<Double>(editDistances); + HashMap<Double, Integer> edit_occurrences_map = new HashMap<>(); + for(double dist : distances_sorted){ int occurrences = Collections.frequency(editDistances, dist); edit_occurrences_map.put(dist, occurrences); @@ -755,7 +751,7 @@ public void writeEditDistance(List<Integer> editDistances) throws IOException { writerEditDistance.write("#Edit distances for file:" + input + "\n"); writerEditDistance.write("Edit distance\tOccurrences\n"); - for(int dist : edit_occurrences_map.keySet()) + for(double dist : edit_occurrences_map.keySet()) writerEditDistance.write(dist + "\t" + edit_occurrences_map.get(dist) + "\n"); writerEditDistance.close(); @@ -806,41 +802,39 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep LinePlot damagePlot_three=null; // create plots - if(!ssLibProtocolUsed){ - damagePlot_three = new LinePlot(threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, - color_DP_insertions, color_DP_deletions, color_DP_other); - - // three prime end - // red - damagePlot_three.addData(three_C_to_T_reverse, "3'C>T"); - // blue - damagePlot_three.addData(three_G_to_A_reverse, "3'G>A"); - - // purple (insertions) - double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), - frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); - damagePlot_three.addData(insertions_mean_3, "insertions"); - - // green (deletions) - double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , - frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); - damagePlot_three.addData(deletions_mean_3, "deletions"); - - - // gray - damagePlot_three.addData(three_A_to_C_reverse, "others"); - damagePlot_three.addData(three_A_to_G_reverse, "3'A>G"); - damagePlot_three.addData(three_A_to_T_reverse, "3'A>T"); - damagePlot_three.addData(three_C_to_A_reverse, "3'C>A"); - damagePlot_three.addData(three_C_to_G_reverse, "3'C>G"); - damagePlot_three.addData(three_G_to_C_reverse, "3'G>C"); - damagePlot_three.addData(three_G_to_T_reverse, "3'G>T"); - damagePlot_three.addData(three_T_to_A_reverse, "3'T>A"); - damagePlot_three.addData(three_T_to_C_reverse, "3'T>C"); - damagePlot_three.addData(three_T_to_G_reverse, "3'T>G"); + damagePlot_three = new LinePlot(threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, + color_DP_insertions, color_DP_deletions, color_DP_other); + + // three prime end + // red + damagePlot_three.addData(three_C_to_T_reverse, "3'C>T"); + // blue + damagePlot_three.addData(three_G_to_A_reverse, "3'G>A"); + + // purple (insertions) + double[] insertions_mean_3 = getMean(frequencies.getCount_0_A_3_norm(),frequencies.getCount_0_C_3_norm(), + frequencies.getCount_0_G_3_norm(),frequencies.getCount_0_T_3_norm()); + damagePlot_three.addData(insertions_mean_3, "insertions"); + + // green (deletions) + double[] deletions_mean_3 = getMean(frequencies.getCount_A_0_3_norm(), frequencies.getCount_C_0_3_norm() , + frequencies.getCount_G_0_3_norm(), frequencies.getCount_T_0_3_norm()); + damagePlot_three.addData(deletions_mean_3, "deletions"); + + + // gray + damagePlot_three.addData(three_A_to_C_reverse, "others"); + damagePlot_three.addData(three_A_to_G_reverse, "3'A>G"); + damagePlot_three.addData(three_A_to_T_reverse, "3'A>T"); + damagePlot_three.addData(three_C_to_A_reverse, "3'C>A"); + damagePlot_three.addData(three_C_to_G_reverse, "3'C>G"); + damagePlot_three.addData(three_G_to_C_reverse, "3'G>C"); + damagePlot_three.addData(three_G_to_T_reverse, "3'G>T"); + damagePlot_three.addData(three_T_to_A_reverse, "3'T>A"); + damagePlot_three.addData(three_T_to_C_reverse, "3'T>C"); + damagePlot_three.addData(three_T_to_G_reverse, "3'T>G"); - } LinePlot damagePlot_five = new LinePlot(threshold, height, LOG, color_DP_C_to_T, color_DP_G_to_A, color_DP_insertions, color_DP_deletions, color_DP_other); @@ -892,25 +886,20 @@ public void plotMisincorporations(String file) throws IOException, DocumentExcep XYDataset dataset_five = damagePlot_five.createDataset(); double ymax; - if(!ssLibProtocolUsed){ - // set equal y axis range - ymax = Math.max(damagePlot_five.getY_max(), damagePlot_three.getY_max()); - } else { - ymax = damagePlot_five.getY_max(); - } + + // set equal y axis range + ymax = Math.max(damagePlot_five.getY_max(), damagePlot_three.getY_max()); + JFreeChart[] charts; // create damage plot five prime - chart_DP_5prime = damagePlot_five.createChart("5' end", dataset_five, ymax, threshold); - if(!ssLibProtocolUsed){ - XYDataset dataset_three = damagePlot_three.createDataset(); - // create damage plot three prime - chart_DP_3prime = damagePlot_three.createChart("3' end", dataset_three, ymax, threshold); - charts = new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; - createSVG("/DamagePlot_three_prime.svg", chart_DP_3prime); - } else { - charts = new JFreeChart[]{chart_DP_5prime}; - } + chart_DP_5prime = damagePlot_five.createChart("5' end", dataset_five, ymax, threshold, ssLibProtocolUsed); + XYDataset dataset_three = damagePlot_three.createDataset(); + // create damage plot three prime + chart_DP_3prime = damagePlot_three.createChart("3' end", dataset_three, ymax, threshold, ssLibProtocolUsed); + charts = new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; + createSVG("/DamagePlot_three_prime.svg", chart_DP_3prime); + createPdf("/DamagePlot.pdf", charts, file); createSVG("/DamagePlot_five_prime.svg", chart_DP_5prime); @@ -974,6 +963,12 @@ private double[] getSubArray(double[] array, int n){ } + /** + * Save images sc svg. This is only possible when using JFreeChart library. + * @param filename + * @param chart + * @throws IOException + */ public void createSVG(String filename, JFreeChart chart) throws IOException { int height = (int)(PageSize.A4.getWidth() * (float)0.8); @@ -1013,26 +1008,14 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws DecimalFormat df = (DecimalFormat)nf; String read_per; - if(!ssLibProtocolUsed){ - if(this.species == null){ - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads)"; - } else{ - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Species: " + this.species; - } - - } else { - if(this.species == null){ - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | ssLib protocol"; - } else { - read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + - (double) (Math.round(ratio_used_reads * 10000)) / 100 + "% of all input reads) | Species: " + this.species + " | ssLib protocol"; - } + if(this.species == null){ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads)"; + } else{ + read_per = Chunk.NEWLINE + "Number of used reads: " + df.format(damageProfiler.getNumberOfUsedReads()) + " (" + + (double)(Math.round(ratio_used_reads*10000))/100 + "% of all input reads) | Species: " + this.species; } - Font fontbold = FontFactory.getFont("Times-Roman", 18, Font.BOLD); Font font = FontFactory.getFont("Times-Roman", 14); @@ -1067,22 +1050,10 @@ public void createPdf(String filename, JFreeChart[] charts, String file) throws document.close(); } - public int getThreshold() { - return threshold; - } - - public double[] getThree_C_to_T_reverse() { - return three_C_to_T_reverse; - } - - public double[] getThree_G_to_A_reverse() { - return three_G_to_A_reverse; - } - - public double getMaxYdamapePlot() { - return height; - } + /* + Getter + */ public JFreeChart[] getDP_chart() { if(chart_DP_3prime!=null){ return new JFreeChart[]{chart_DP_5prime, chart_DP_3prime}; diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java index 68f5103..7e4079e 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/Histogram.java @@ -7,8 +7,7 @@ import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYBarRenderer; -import org.jfree.chart.title.LegendTitle; -import org.jfree.chart.ui.RectangleEdge; +import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.statistics.HistogramDataset; import org.jfree.data.statistics.HistogramType; @@ -32,22 +31,21 @@ public Histogram(Logger LOG){ data_collected = new ArrayList<>(); } - public void addData(List<Integer> data){ + public void addData(List<Double> data){ double[] d = new double[data.size()]; for(int i = 0; i < data.size(); i++){ d[i] = data.get(i); } - data_collected.add(d); } - public HistogramDataset createDataset(String[] title, int max){ + public HistogramDataset createDataset(String[] title, double max){ HistogramDataset dataset = new HistogramDataset(); dataset.setType(HistogramType.FREQUENCY); - int bin = max; + int bin = (int) max; for(int i = 0; i < data_collected.size(); i++){ dataset.addSeries(title[i], data_collected.get(i), bin); @@ -62,7 +60,7 @@ public JFreeChart createChart(HistogramDataset dataset, String title, String xla double xmin, double xmax, boolean legend){ JFreeChart chart = ChartFactory.createHistogram( - title,//"Histogram read length", + title,//"Histogram edit distance", xlab, //"Read length", ylab, // "Occurrences", dataset, diff --git a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java index bc4b49b..5ac4db7 100755 --- a/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java +++ b/src/main/java/org/damageprofiler/IO/PDFoutput/LinePlot.java @@ -114,9 +114,10 @@ public XYDataset createDataset() { * Creates a chart. * * @param dataset the data for the chart. + * @param ssLibProtocolUsed * @return a chart. */ - public JFreeChart createChart(String title, final XYDataset dataset, double yMax, int threshold) { + public JFreeChart createChart(String title, final XYDataset dataset, double yMax, int threshold, boolean ssLibProtocolUsed) { // create the chart... final JFreeChart chart = ChartFactory.createXYLineChart( @@ -160,7 +161,8 @@ public JFreeChart createChart(String title, final XYDataset dataset, double yMax legendItemsNew.get(4).setLinePaint(this.awtColor_DP_other); renderer.setSeriesStroke(0, new BasicStroke(3.0f)); - renderer.setSeriesStroke(1, new BasicStroke(3.0f)); + if(!ssLibProtocolUsed) + renderer.setSeriesStroke(1, new BasicStroke(3.0f)); renderer.setAutoPopulateSeriesStroke(false); plot.setFixedLegendItems(legendItemsNew); diff --git a/src/main/java/org/damageprofiler/IO/UserOptionsParser.java b/src/main/java/org/damageprofiler/IO/UserOptionsParser.java index 473abd0..05a412a 100755 --- a/src/main/java/org/damageprofiler/IO/UserOptionsParser.java +++ b/src/main/java/org/damageprofiler/IO/UserOptionsParser.java @@ -60,7 +60,7 @@ private void parse() { options.addOption(Option.builder("s") .argName("SPECIES") - .desc("Reference sequence name (RNAME flag of SAM record). For more details see Documentation.") + .desc("Reference sequence name (Reference NAME flag of SAM record). For more details see Documentation.") .hasArg() .build()); @@ -125,34 +125,6 @@ private void parse() { .hasArg() .build()); - // Identity plot - - options.addOption(Option.builder("xaxis_id_min") - .argName("MIN_VALUE") - .desc("Identity Distribution: Minimal value x-axis.") - .hasArg() - .build()); - - options.addOption(Option.builder("xaxis_id_max") - .argName("MAX_VALUE") - .desc("Identity Distribution: Maximal value x-axis.") - .hasArg() - .build()); - - // Length plot - - options.addOption(Option.builder("xaxis_length_min") - .argName("MIN_VALUE") - .desc("Length Distribution: Minimal value x-axis.") - .hasArg() - .build()); - - options.addOption(Option.builder("xaxis_length_max") - .argName("MAX_VALUE") - .desc("Length Distribution: Maximal value x-axis.") - .hasArg() - .build()); - // others @@ -162,7 +134,7 @@ private void parse() { "it will be skipped. Default: false ") .build()); - options.addOption(Option.builder("ssLib") + options.addOption(Option.builder("sslib") .desc("Single-stranded library protocol was used. Default: false") .build()); @@ -236,24 +208,6 @@ private void parse() { communicator.setyAxis_damageplot(Double.parseDouble(cmd.getOptionValue("yaxis_dp_max"))); } - if(cmd.hasOption("xaxis_histo_id_min")) { - communicator.setXaxis_histo_id_min(Double.parseDouble(cmd.getOptionValue("xaxis_histo_id_min"))); - } - - - if(cmd.hasOption("xaxis_histo_id_max")) { - communicator.setXaxis_histo_id_max(Double.parseDouble(cmd.getOptionValue("xaxis_histo_id_max"))); - } - - if(cmd.hasOption("xaxis_histo_length_min")) { - communicator.setXaxis_histo_length_min(Double.parseDouble(cmd.getOptionValue("xaxis_histo_length_min"))); - } - - - if(cmd.hasOption("xaxis_histo_length_max")) { - communicator.setXaxis_histo_length_max(Double.parseDouble(cmd.getOptionValue("xaxis_histo_length_max"))); - } - if (cmd.hasOption('t')) { communicator.setThreshold(Integer.parseInt(cmd.getOptionValue('t'))); diff --git a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java index 81e4272..15ab029 100755 --- a/src/main/java/org/damageprofiler/calculations/DamageProfiler.java +++ b/src/main/java/org/damageprofiler/calculations/DamageProfiler.java @@ -29,7 +29,7 @@ public class DamageProfiler { LengthDistribution lengthDistribution; private ArrayList<Double> identity; private SpeciesHandler speciesHandler; - private List<Integer> editDistances; + private List<Double> editDistances; /** * constructor @@ -233,7 +233,7 @@ private void proceed(SAMRecord record, String record_aligned, String reference_a this.lengthDistribution.fillDistributionTable(record,record_aligned); // calculate distance between record and reference - int hamming = useful_functions.getHammingDistance(record_aligned, reference_aligned); + double hamming = useful_functions.getHammingDistance(record_aligned, reference_aligned); double id = (double)(record_aligned.length()-hamming) / (double)record_aligned.length(); this.identity.add(id); @@ -254,15 +254,15 @@ private void proceed(SAMRecord record, String record_aligned, String reference_a public Frequencies getFrequencies() { return frequencies; } - public HashMap<Integer, Integer> getLength_distribution_map_forward() {return lengthDistribution.getLength_distribution_map_forward(); } - public HashMap<Integer, Integer> getLength_distribution_map_reverse() {return lengthDistribution.getLength_distribution_map_reverse(); } - public List<Integer> getLength_forward() { + public HashMap<Double, Integer> getLength_distribution_map_forward() {return lengthDistribution.getLength_distribution_map_forward(); } + public HashMap<Double, Integer> getLength_distribution_map_reverse() {return lengthDistribution.getLength_distribution_map_reverse(); } + public List<Double> getLength_forward() { return lengthDistribution.getLength_forward(); } - public List<Integer> getLength_all() { + public List<Double> getLength_all() { return lengthDistribution.getLength_all(); } - public List<Integer> getLength_reverse() { return lengthDistribution.getLength_reverse(); } + public List<Double> getLength_reverse() { return lengthDistribution.getLength_reverse(); } public int getNumberOfUsedReads() { return numberOfUsedReads; } @@ -291,7 +291,7 @@ public String getSpeciesname(File file, String ref) { public int getNumberOfRecords() { return numberOfRecords; } - public List<Integer> getEditDistances() { + public List<Double> getEditDistances() { return editDistances; } } diff --git a/src/main/java/org/damageprofiler/calculations/LengthDistribution.java b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java index be6995c..f8798e8 100755 --- a/src/main/java/org/damageprofiler/calculations/LengthDistribution.java +++ b/src/main/java/org/damageprofiler/calculations/LengthDistribution.java @@ -13,12 +13,12 @@ public class LengthDistribution { private final Logger LOG; - private HashMap<Integer, Integer> length_distribution_map_forward; - private HashMap<Integer, Integer> length_distribution_map_reverse; + private HashMap<Double, Integer> length_distribution_map_forward; + private HashMap<Double, Integer> length_distribution_map_reverse; private HashMap<Double, Double> length_distribution_map; - private List<Integer> length_forward; - private List<Integer> length_reverse; - private List<Integer> length_all; + private List<Double> length_forward; + private List<Double> length_reverse; + private List<Double> length_all; public LengthDistribution(Logger LOG){ @@ -47,7 +47,7 @@ public void init(){ public void fillDistributionTable(SAMRecord record, String record_aligned){ // int record_length = record.getReadLength(); - int record_length = record_aligned.length(); + double record_length = record_aligned.length(); length_all.add(record_length); // check if record is on forward or reverse strand @@ -86,23 +86,23 @@ public void fillDistributionTable(SAMRecord record, String record_aligned){ Getter */ - public HashMap<Integer, Integer> getLength_distribution_map_forward() { + public HashMap<Double, Integer> getLength_distribution_map_forward() { return length_distribution_map_forward; } - public HashMap<Integer, Integer> getLength_distribution_map_reverse() { + public HashMap<Double, Integer> getLength_distribution_map_reverse() { return length_distribution_map_reverse; } - public List<Integer> getLength_forward() { + public List<Double> getLength_forward() { return length_forward; } - public List<Integer> getLength_reverse() { + public List<Double> getLength_reverse() { return length_reverse; } - public List<Integer> getLength_all() { + public List<Double> getLength_all() { return length_all; } diff --git a/src/main/java/org/damageprofiler/calculations/StartCalculations.java b/src/main/java/org/damageprofiler/calculations/StartCalculations.java index 5720336..c99c728 100755 --- a/src/main/java/org/damageprofiler/calculations/StartCalculations.java +++ b/src/main/java/org/damageprofiler/calculations/StartCalculations.java @@ -100,7 +100,6 @@ public void start(Communicator c) throws Exception { color_DP_deletions = c.getColor_DP_deletions(); color_DP_other = c.getColor_DP_other(); - this.inputfileNameWithOutExtension = input.substring(0, input.lastIndexOf('.')); this.communicator = c; diff --git a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java index 2a9c5f5..f65e7c7 100755 --- a/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java +++ b/src/main/java/org/damageprofiler/controller/DamageProfilerMainController.java @@ -8,19 +8,14 @@ import org.damageprofiler.calculations.RuntimeEstimator; import org.damageprofiler.calculations.StartCalculations; import org.damageprofiler.IO.Communicator; -import javafx.animation.KeyFrame; -import javafx.animation.Timeline; import javafx.concurrent.Task; import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.control.*; import javafx.scene.paint.Color; -import javafx.util.Duration; import org.jfree.chart.JFreeChart; import org.jfree.chart.fx.ChartViewer; -import java.lang.reflect.Field; - public class DamageProfilerMainController { private final Button btn_leftpane_run_config; @@ -32,7 +27,7 @@ public class DamageProfilerMainController { private final Button btn_help; private final HelpDialogue help_dialogue; private final AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue; - private final Button btn_loadSpecies; + private final PlottingSettingController plottingSettingController; private RunInfoDialogue runInfoDialogue; private Communicator communicator; private Button btn_inputfile; @@ -54,8 +49,11 @@ public class DamageProfilerMainController { * Constructor * @param damageProfilerMainGUI * @param progressBarController + * @param plottingSettingController */ - public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, ProgressBarController progressBarController){ + public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, + ProgressBarController progressBarController, + PlottingSettingController plottingSettingController){ this.mainGUI = damageProfilerMainGUI; this.progressBarController = progressBarController; @@ -70,7 +68,6 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, this.btn_run = mainGUI.getConfig_dialogue().getBtn_run(); this.btn_estimate_runtime = mainGUI.getConfig_dialogue().getBtn_estimate_runtime(); this.btn_speciesList = mainGUI.getConfig_dialogue().getBtn_speciesList(); - this.btn_loadSpecies = mainGUI.getConfig_dialogue().getBtn_loadSpecies(); this.btn_leftpane_identityDist = mainGUI.getBtn_leftpane_identityDist(); this.btn_leftpane_run_config = mainGUI.getBtn_leftpane_info(); this.btn_help = mainGUI.getBtn_help(); @@ -88,7 +85,9 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, // attributes of advanced plotting settings + this.plottingSettingController = plottingSettingController; this.advancedPlottingOptionsDialogue = this.mainGUI.getConfig_dialogue().getAdvancedPlottingOptionsDialogue(); + this.plottingSettingController.addListener(this.advancedPlottingOptionsDialogue); runtimeInfoDialogue = new RuntimeEstimatorDialogue("Runtime information", @@ -102,11 +101,11 @@ public DamageProfilerMainController(DamageProfilerMainGUI damageProfilerMainGUI, private void setColorsPlotting() { - Color color_c_to_t = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_C_to_T().getValue(); - Color color_g_to_a = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_G_to_A().getValue(); - Color color_insertions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_insertions().getValue(); - Color color_deletions = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue(); - Color color_other = this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue(); + communicator.setColor_DP_C_to_T(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_C_to_T().getValue()); + communicator.setColor_DP_G_to_A(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_G_to_A().getValue()); + communicator.setColor_DP_insertions(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_insertions().getValue()); + communicator.setColor_DP_deletions(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_deletions().getValue()); + communicator.setColor_DP_other(this.advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot().getColorPicker_others().getValue()); } @@ -115,19 +114,26 @@ private void addListener() { btn_inputfile.setOnAction(e -> { BamFileChooser fqfc = new BamFileChooser(communicator); - Tooltip tooltip_input = new Tooltip(communicator.getInput()); - //setTooltipDelay(tooltip_input); - btn_inputfile.setTooltip(tooltip_input); + if (communicator.getInput() != null){ + Tooltip tooltip_input = new Tooltip(communicator.getInput()); + //setTooltipDelay(tooltip_input); + btn_inputfile.setTooltip(tooltip_input); - if (checkIfInputWasSelected()) { - btn_run.setDisable(false); - btn_estimate_runtime.setDisable(false); + String filepath = communicator.getInput().substring(0, communicator.getInput().lastIndexOf('.')); + String filename = filepath.split("/")[filepath.split("/").length-1]; + mainGUI.getConfig_dialogue().setTextfield_title(filename); - } else { - btn_run.setDisable(true); - btn_estimate_runtime.setDisable(true); + if (checkIfInputWasSelected()) { + btn_run.setDisable(false); + btn_estimate_runtime.setDisable(false); + + } else { + btn_run.setDisable(true); + btn_estimate_runtime.setDisable(true); + } } + }); btn_help.setOnAction(e -> { @@ -421,27 +427,5 @@ private boolean checkIfInputWasSelected() { } - /** - * This method overrides the default tooltip delay and sets it to 0 seconds. So the tooptip - * pops up immediately when hovering over the item. - * - * @param tooltip - */ - public static void setTooltipDelay(Tooltip tooltip) { - try { - Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR"); - fieldBehavior.setAccessible(true); - Object objBehavior = fieldBehavior.get(tooltip); - - Field fieldTimer = objBehavior.getClass().getDeclaredField("activationTimer"); - fieldTimer.setAccessible(true); - Timeline objTimer = (Timeline) fieldTimer.get(objBehavior); - - objTimer.getKeyFrames().clear(); - objTimer.getKeyFrames().add(new KeyFrame(new Duration(0))); - } catch (Exception e) { - e.printStackTrace(); - } - } } diff --git a/src/main/java/org/damageprofiler/controller/PlottingSettingController.java b/src/main/java/org/damageprofiler/controller/PlottingSettingController.java new file mode 100644 index 0000000..43dcda7 --- /dev/null +++ b/src/main/java/org/damageprofiler/controller/PlottingSettingController.java @@ -0,0 +1,25 @@ +package org.damageprofiler.controller; + +import org.damageprofiler.GUI.Dialogues.AdvancedPlottingOptionsDialogue; +import org.damageprofiler.GUI.Dialogues.TabAdvancedSettingsDamagePlot; + +public class PlottingSettingController { + + public PlottingSettingController(){ + + } + + /** + * Adding all listener to advancedPlottingOptionsDialogue + * + * @param advancedPlottingOptionsDialogue + */ + public void addListener(AdvancedPlottingOptionsDialogue advancedPlottingOptionsDialogue) { + TabAdvancedSettingsDamagePlot dp_settings_pane = advancedPlottingOptionsDialogue.getTabAdvancedSettingsDamagePlot(); + dp_settings_pane.getBtn_reset().setOnAction(e ->{ + dp_settings_pane.reset(); + + }); + + } +}