diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..2c1dd2f
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "milib"]
+ path = milib
+ url = https://github.com/milaboratory/milib.git
diff --git a/CHANGELOG b/CHANGELOG
index 84d4ba5..d666e57 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,11 @@
+MiTools 1.4 (14 Jul 2016)
+========================
+
+-- added new action: `mitools cut` to cut sequences to a fixed or random length (see help `mitools
+ cut -h`)
+
+
MiTools 1.3 ( 1 Feb 2016)
========================
diff --git a/milib b/milib
new file mode 160000
index 0000000..f551baa
--- /dev/null
+++ b/milib
@@ -0,0 +1 @@
+Subproject commit f551baa70fb383bdb182f0679822c1be1fb18dec
diff --git a/mitools b/mitools
new file mode 100755
index 0000000..8970a6a
--- /dev/null
+++ b/mitools
@@ -0,0 +1,146 @@
+#!/bin/bash
+
+java="java"
+
+sedString="s/.*1\.\(.*\)\..*/\1/"
+jVersion=$($java -version 2>&1 | grep version | awk '{ print $3 }' | sed $sedString)
+if [[ $jVersion -lt 7 ]];
+then
+ echo "Wrong version of java. Please use Java 7 or higher."
+ exit 1
+fi
+
+# Linux readlink -f alternative for Mac OS X
+function readlinkUniversal() {
+ targetFile=$1
+
+ cd `dirname $targetFile`
+ targetFile=`basename $targetFile`
+
+ # iterate down a (possible) chain of symlinks
+ while [ -L "$targetFile" ]
+ do
+ targetFile=`readlink $targetFile`
+ cd `dirname $targetFile`
+ targetFile=`basename $targetFile`
+ done
+
+ # compute the canonicalized name by finding the physical path
+ # for the directory we're in and appending the target file.
+ phys_dir=`pwd -P`
+ result=$phys_dir/$targetFile
+ echo $result
+}
+
+os=`uname`
+delta=100
+
+dir=""
+
+case $os in
+ Darwin)
+ freeBlocks=$(vm_stat | grep free | awk '{ print $3 }' | sed 's/\.//')
+ inactiveBlocks=$(vm_stat | grep inactive | awk '{ print $3 }' | sed 's/\.//')
+ speculativeBlocks=$(vm_stat | grep speculative | awk '{ print $3 }' | sed 's/\.//')
+ freeMb=$((($freeBlocks+$speculativeBlocks)*4096/1048576))
+ inactiveMb=$(($inactiveBlocks*4096/1048576))
+ maxMb=$((($freeMb+$inactiveMb-$delta)))
+ dir=$(dirname "$(readlinkUniversal "$0")")
+ ;;
+ Linux)
+ rFreeMb=$(free -m | head -n 3 | tail -n 1 | awk '{ print $4 }')
+ maxMb=$(($rFreeMb-$delta))
+ dir="$(dirname "$(readlink -f "$0")")"
+ ;;
+ *)
+ echo "Unknown OS."
+ exit 1
+ ;;
+esac
+
+bin=${dir}/$0
+
+jarBase="mitools"
+
+appArgs=()
+javaArgs=()
+
+needXmxXms=true
+otherJar=""
+
+while [[ $# > 0 ]]
+do
+ key="$1"
+ shift
+ case $key in
+ -D*|-X*|-ea|-agentlib*)
+ javaArgs+=(${key})
+
+ case $key in
+ -Xmx*|-Xms*)
+ needXmxXms=false
+ ;;
+ esac
+
+ ;;
+ -jar|-V)
+ otherJar="$1"
+ shift
+ ;;
+ *)
+ appArgs+=("${key}")
+ ;;
+ esac
+done
+
+if [[ ${needXmxXms} == true ]]
+then
+ targetXmx=3000
+
+ if [[ $targetXmx -gt $maxMb ]];
+ then
+ targetXmx=$maxMb
+ fi
+
+ javaArgs+=("-Xmx${targetXmx}m")
+
+ targetXms=$((${targetXmx}*2/3))
+
+ if [[ $targetXms -lt 2000 ]];
+ then
+ targetXms=$targetXmx
+ fi
+
+ javaArgs+=("-Xms${targetXms}m")
+fi
+
+jar=""
+
+if [[ -z "$otherJar" ]];
+then
+ for j in "$dir/../jar/${jarBase}.jar" "$dir/${jarBase}.jar" $(ls -d -1 $dir/target/* 2> /dev/null | grep distribution.jar)
+ do
+ if [[ -e "$j" ]];
+ then
+ jar=$j
+ break
+ fi
+ done
+else
+ for j in $(ls -1 ${dir}/* | grep "${jarBase}" | grep ".jar" | grep ${otherJar});
+ do
+ if [[ -e "$j" ]];
+ then
+ jar=$j
+ break
+ fi
+ done
+fi
+
+if [[ "$jar" == "" ]];
+then
+ echo "No jar."
+ exit 1
+fi
+
+$java -Dapp.path=$dir -Dapp.command=mixcr -XX:+AggressiveOpts "${javaArgs[@]}" -jar $jar "${appArgs[@]}"
diff --git a/pom.xml b/pom.xml
index 7e363d5..0416e14 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,10 +19,10 @@
com.milaboratory
mitools
- 1.3
+ 1.4
jar
MiTools
- http://milaboratory.com/
+ https://github.com/milaboratory/mitools
org.sonatype.oss
@@ -94,7 +94,13 @@
com.milaboratory
milib
- ${project.version}
+ 1.5-SNAPSHOT
+
+
+ com.beust
+ jcommander
+ 1.48
+ true
com.milaboratory
@@ -115,16 +121,6 @@
1.9.5
test
-
- com.beust
- jcommander
- 1.30
-
-
- cc.redberry
- pipe
- 0.9.4
-
@@ -135,11 +131,6 @@
scm:git:https://github.com/milaboratory/mitools.git
-
- YouTrack
- http://youtrack.milaboratory.com/
-
-
release
diff --git a/src/main/java/com/milaboratory/core/PairedEndReadsLayout.java b/src/main/java/com/milaboratory/core/PairedEndReadsLayout.java
deleted file mode 100644
index c7bc411..0000000
--- a/src/main/java/com/milaboratory/core/PairedEndReadsLayout.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.core;
-
-import com.milaboratory.core.io.sequence.PairedRead;
-
-public enum PairedEndReadsLayout implements java.io.Serializable {
- Opposite(new PairedTargetProvider() {
- @Override
- public PairedTarget[] createTargets(PairedRead read) {
- return new PairedTarget[]{
- new PairedTarget(
- read.getRead(0).getData(),
- read.getRead(1).getData().getReverseComplement()),
- new PairedTarget(
- read.getRead(1).getData(),
- read.getRead(0).getData().getReverseComplement())};
- }
- }, true
- ),
- Collinear(new PairedTargetProvider() {
- @Override
- public PairedTarget[] createTargets(PairedRead read) {
- return new PairedTarget[]{
- new PairedTarget(
- read.getRead(0).getData(),
- read.getRead(1).getData()),
- new PairedTarget(
- read.getRead(1).getData().getReverseComplement(),
- read.getRead(0).getData().getReverseComplement())};
- }
- }, false
- ),
- Unknown(new PairedTargetProvider() {
- @Override
- public PairedTarget[] createTargets(PairedRead read) {
- return new PairedTarget[]{
- new PairedTarget(
- read.getRead(0).getData(),
- read.getRead(1).getData()),
- new PairedTarget(
- read.getRead(0).getData(),
- read.getRead(1).getData().getReverseComplement()),
- new PairedTarget(
- read.getRead(1).getData(),
- read.getRead(0).getData().getReverseComplement()),
- new PairedTarget(
- read.getRead(1).getData().getReverseComplement(),
- read.getRead(0).getData().getReverseComplement())};
- }
- }, false, true
- );
- private final PairedTargetProvider provider;
- private final boolean[] possibleRelativeStrands;
-
- PairedEndReadsLayout(PairedTargetProvider provider, boolean... possibleRelativeStrands) {
- this.provider = provider;
- this.possibleRelativeStrands = possibleRelativeStrands;
- }
-
- public PairedTarget[] createTargets(PairedRead read) {
- return provider.createTargets(read);
- }
-
- public boolean[] getPossibleRelativeStrands() {
- return possibleRelativeStrands;
- }
-
- private interface PairedTargetProvider {
- PairedTarget[] createTargets(PairedRead read);
- }
-}
diff --git a/src/main/java/com/milaboratory/core/PairedTarget.java b/src/main/java/com/milaboratory/core/PairedTarget.java
deleted file mode 100644
index c77bbe6..0000000
--- a/src/main/java/com/milaboratory/core/PairedTarget.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.core;
-
-import com.milaboratory.core.sequence.NSequenceWithQuality;
-
-/**
- * Created by dbolotin on 24/07/14.
- */
-public final class PairedTarget {
- public final NSequenceWithQuality[] targets;
-
- PairedTarget(NSequenceWithQuality... targets) {
- this.targets = targets;
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/Action.java b/src/main/java/com/milaboratory/mitools/cli/Action.java
deleted file mode 100644
index 69e7111..0000000
--- a/src/main/java/com/milaboratory/mitools/cli/Action.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.cli;
-
-/**
- * Created by dbolotin on 20/08/14.
- */
-public interface Action {
- void go(ActionHelper helper) throws Exception;
-
- String command();
-
- ActionParameters params();
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/ActionHelper.java b/src/main/java/com/milaboratory/mitools/cli/ActionHelper.java
deleted file mode 100644
index 0b03786..0000000
--- a/src/main/java/com/milaboratory/mitools/cli/ActionHelper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.cli;
-
-import java.io.PrintStream;
-
-public interface ActionHelper {
- PrintStream getDefaultPrintStream();
-
- String getCommandLineArguments();
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/ActionParameters.java b/src/main/java/com/milaboratory/mitools/cli/ActionParameters.java
deleted file mode 100644
index 1227a81..0000000
--- a/src/main/java/com/milaboratory/mitools/cli/ActionParameters.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.cli;
-
-import com.beust.jcommander.Parameter;
-
-public abstract class ActionParameters {
- @Parameter(names = {"-h", "--help"}, help = true, description = "Displays help for this command.")
- public Boolean help = false;
-
- public boolean help() {
- return help != null && help;
- }
-
- public void validate() {
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/CheckAction.java b/src/main/java/com/milaboratory/mitools/cli/CheckAction.java
index 84345e7..18d41df 100644
--- a/src/main/java/com/milaboratory/mitools/cli/CheckAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/CheckAction.java
@@ -18,6 +18,9 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
import com.milaboratory.core.io.sequence.PairedRead;
import com.milaboratory.core.io.sequence.SingleRead;
import com.milaboratory.core.io.sequence.fastq.FastqRecordsReader;
diff --git a/src/main/java/com/milaboratory/mitools/cli/CutAction.java b/src/main/java/com/milaboratory/mitools/cli/CutAction.java
new file mode 100644
index 0000000..bf39b42
--- /dev/null
+++ b/src/main/java/com/milaboratory/mitools/cli/CutAction.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2016 MiLaboratory.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.milaboratory.mitools.cli;
+
+import cc.redberry.pipe.CUtils;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.Parameters;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
+import com.milaboratory.core.io.sequence.SingleRead;
+import com.milaboratory.core.io.sequence.SingleSequenceWriter;
+import com.milaboratory.core.io.sequence.fastq.SingleFastqReader;
+import com.milaboratory.mitools.processors.CutSide;
+import com.milaboratory.mitools.processors.RandomCutter;
+import com.milaboratory.util.SmartProgressReporter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static cc.redberry.pipe.CUtils.wrap;
+
+public class CutAction implements Action {
+ final AParams actionParameters = new AParams();
+
+ @Override
+ public void go(ActionHelper helper) throws Exception {
+ try (SingleFastqReader reader = MiCLIUtil.createSingleReader(actionParameters.getInput(), false);
+ SingleSequenceWriter writer = MiCLIUtil.createSingleWriter(actionParameters.getOutput())) {
+ SmartProgressReporter.startProgressReport("Processing", reader, System.err);
+
+ RandomCutter cutter = new RandomCutter(actionParameters.getPosition(), actionParameters.getMinLengt(),
+ actionParameters.getMaxLengt(), actionParameters.getSeed());
+
+ for (SingleRead read : CUtils.it(wrap(reader, cutter)))
+ writer.write(read);
+ }
+ }
+
+ @Override
+ public String command() {
+ return "cut";
+ }
+
+ @Override
+ public ActionParameters params() {
+ return actionParameters;
+ }
+
+ @Parameters(commandDescription = "Cut sequences.", optionPrefixes = "-")
+ public static final class AParams extends ActionParameters {
+ @Parameter(description = "[ input_file_R1.fastq[.gz] [ output_file.fastq[.gz] ] ]", variableArity = true)
+ public List parameters = new ArrayList<>();
+
+ @Parameter(description = "Length.",
+ names = {"-l", "--length"})
+ Integer length;
+
+ @Parameter(description = "Minimal length; inclusive (random value will be selected for each sequence; use with " +
+ "--max-length; don't use with --length option).",
+ names = {"-al", "--min-length"})
+ Integer minLength;
+
+ @Parameter(description = "Maximal length; inclusive (random value will be selected for each sequence; use with " +
+ "--min-length; don't use with --length option).",
+ names = {"-bl", "--max-length"})
+ Integer maxLength;
+
+ @Parameter(description = "Position to cut from. (possible values 'Left', 'Right', 'Random')",
+ names = {"-p", "--position"})
+ String position = "Left";
+
+ @Parameter(description = "Seed for random generator.",
+ names = {"-s", "--seed"})
+ Integer seed;
+
+ public String getInput() {
+ return parameters.size() == 0 ? "-" : parameters.get(0);
+ }
+
+ public String getOutput() {
+ return parameters.size() < 2 ? "-" : parameters.get(1);
+ }
+
+ public int getSeed() {
+ return seed == null ? 0 : seed;
+ }
+
+ public int getMinLengt() {
+ if (length != null)
+ return length;
+ return minLength;
+ }
+
+ public int getMaxLengt() {
+ if (length != null)
+ return length;
+ return maxLength;
+ }
+
+ public CutSide getPosition() {
+ return CutSide.valueOf(position);
+ }
+
+ @Override
+ public void validate() {
+ if (parameters.size() > 2)
+ throw new ParameterException("Wrong number of parameters.");
+ if (length == null && minLength == null && maxLength == null)
+ throw new ParameterException("Please specify the length to cut: --length or --max-length and --min-length.");
+ if (length != null && (minLength != null || maxLength != null))
+ throw new ParameterException("--length option is not compatible with --max-length and --min-length");
+ if ((minLength == null) != (maxLength == null))
+ throw new ParameterException("Please specify both options --max-length and --min-length.");
+ }
+ }
+}
diff --git a/src/main/java/com/milaboratory/mitools/cli/HiddenAction.java b/src/main/java/com/milaboratory/mitools/cli/HiddenAction.java
deleted file mode 100644
index b348539..0000000
--- a/src/main/java/com/milaboratory/mitools/cli/HiddenAction.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.cli;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Created by dbolotin on 03/09/14.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface HiddenAction {
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/JCommanderBasedMain.java b/src/main/java/com/milaboratory/mitools/cli/JCommanderBasedMain.java
deleted file mode 100644
index eb75c35..0000000
--- a/src/main/java/com/milaboratory/mitools/cli/JCommanderBasedMain.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.cli;
-
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class JCommanderBasedMain implements ActionHelper {
- // LinkedHashMap to preserve order of actions
- protected final Map actions = new LinkedHashMap<>();
- protected final String command;
- protected boolean printHelpOnError = false;
- protected boolean printStackTrace = false;
- protected Runnable versionInfoCallback = null;
- protected PrintStream outputStream = System.err;
- protected String[] arguments;
-
- public JCommanderBasedMain(String command, Action... actions) {
- this.command = command;
- for (Action action : actions)
- reg(action);
- }
-
- public void setOutputStream(PrintStream outputStream) {
- this.outputStream = outputStream;
- }
-
- @Override
- public PrintStream getDefaultPrintStream() {
- return outputStream;
- }
-
- @Override
- public String getCommandLineArguments() {
- StringBuilder builder = new StringBuilder();
- for (String arg : arguments) {
- if (builder.length() != 0)
- builder.append(" ");
- builder.append(arg);
- }
- return builder.toString();
- }
-
- public boolean isPrintStackTrace() {
- return printStackTrace;
- }
-
- public void setPrintStackTrace(boolean printStackTrace) {
- this.printStackTrace = printStackTrace;
- }
-
- protected void reg(Action a) {
- actions.put(a.command(), a);
- }
-
- public void main(String... args) throws Exception {
- // Saving current arguments
- this.arguments = args;
-
- if (args.length == 0) {
- printGlobalHelp();
- return;
- }
-
- // Setting up JCommander
- MainParameters mainParameters = getMainParameters();
- JCommander commander = new JCommander(mainParameters);
- commander.setProgramName(command);
- for (Action a : actions.values())
- commander.addCommand(a.command(), a.params());
-
- // Getting command name
- String commandName = args[0];
-
- // Getting corresponding action
- Action action = actions.get(commandName);
-
- try {
- if (action != null && (action instanceof ActionParametersParser)) {
- ((ActionParametersParser) action).parseParameters(Arrays.copyOfRange(args, 1, args.length));
- } else {
- commander.parse(args);
-
- // Print Version information if requested and exit.
- if (mainParameters instanceof MainParametersWithVersion &&
- ((MainParametersWithVersion) mainParameters).version()) {
- versionInfoCallback.run();
- return;
- }
-
- // Print complete help if requested
- if (mainParameters.help()) {
- // Creating new instance of jCommander to add only non-hidden actions
- JCommander tmpCommander = new JCommander(mainParameters);
- tmpCommander.setProgramName(command);
- for (Action a : actions.values())
- if (!a.getClass().isAnnotationPresent(HiddenAction.class))
- tmpCommander.addCommand(a.command(), a.params());
- StringBuilder builder = new StringBuilder();
- tmpCommander.usage(builder);
- outputStream.print(builder);
- return;
- }
-
- // Getting parsed command
- // assert parsedCommand.equals(commandName)
- final String parsedCommand = commander.getParsedCommand();
-
- // Processing potential errors
- if (parsedCommand == null || !actions.containsKey(parsedCommand)) {
- if (parsedCommand == null)
- outputStream.println("No command specified.");
- else
- outputStream.println("Command " + parsedCommand + " not supported.");
- outputStream.println("Use -h option to get a list of supported commands.");
- return;
- }
-
- action = actions.get(parsedCommand);
- }
-
- if (action.params().help()) {
- printActionHelp(commander, action);
- } else {
- action.params().validate();
- action.go(this);
- }
- } catch (ParameterException pe) {
- printException(pe, commander, action);
- }
- }
-
- private MainParameters getMainParameters() {
- return versionInfoCallback != null ?
- new MainParametersWithVersion() :
- new MainParameters();
- }
-
- protected void printGlobalHelp() {
- // Creating new instance of jCommander to add only non-hidden actions
- JCommander tmpCommander = new JCommander(getMainParameters());
- tmpCommander.setProgramName(command);
- for (Action a : actions.values())
- if (!a.getClass().isAnnotationPresent(HiddenAction.class))
- tmpCommander.addCommand(a.command(), a.params());
- StringBuilder builder = new StringBuilder();
- tmpCommander.usage(builder);
- outputStream.print(builder);
- }
-
- protected void printActionHelp(JCommander commander, Action action) {
- StringBuilder builder = new StringBuilder();
- if (action instanceof ActionHelpProvider)
- ((ActionHelpProvider) action).printHelp(builder);
- else
- commander.usage(action.command(), builder);
- outputStream.print(builder);
- }
-
- protected void printException(ParameterException e,
- JCommander commander, Action action) {
- outputStream.println("Error: " + e.getMessage());
- if (printStackTrace)
- e.printStackTrace(new PrintStream(outputStream));
- if (printHelpOnError)
- printActionHelp(commander, action);
- }
-
- /**
- * Enables -v / --version parameter.
- *
- * Sets callback that will be invoked if this option is specified by user.
- *
- * {@literal null} disables -v parameter.
- *
- * @param versionInfoCallback callback to be will be invoked if user specified -v option. {@literal null} disables
- * -v parameter.
- */
- public void setVersionInfoCallback(Runnable versionInfoCallback) {
- this.versionInfoCallback = versionInfoCallback;
- }
-
- public static class MainParameters {
- @Parameter(names = {"-h", "--help"}, help = true, description = "Displays this help message.")
- public Boolean help;
-
- public boolean help() {
- return help != null && help;
- }
- }
-
- public static class MainParametersWithVersion extends MainParameters {
- @Parameter(names = {"-v", "--version"}, help = true, description = "Output version information.")
- public Boolean version;
-
- public boolean version() {
- return version != null && version;
- }
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/Main.java b/src/main/java/com/milaboratory/mitools/cli/Main.java
index 49bc6fb..8dcc063 100644
--- a/src/main/java/com/milaboratory/mitools/cli/Main.java
+++ b/src/main/java/com/milaboratory/mitools/cli/Main.java
@@ -15,15 +15,58 @@
*/
package com.milaboratory.mitools.cli;
+import com.milaboratory.cli.JCommanderBasedMain;
+import com.milaboratory.util.VersionInfo;
+import sun.misc.Signal;
+import sun.misc.SignalHandler;
+
public class Main {
public static void main(String[] args) throws Exception {
+ Signal.handle(new Signal("PIPE"), new SignalHandler() {
+ @Override
+ public void handle(Signal signal) {
+ System.exit(0);
+ }
+ });
+
JCommanderBasedMain main = new JCommanderBasedMain("mitools",
new MergeAction(),
new TrimAction(),
new RCAction(),
new RenameAction(),
new SplitAction(),
- new CheckAction());
+ new CheckAction(),
+ new CutAction());
+
+ main.setVersionInfoCallback(new Runnable() {
+ @Override
+ public void run() {
+ VersionInfo milib = VersionInfo.getVersionInfoForArtifact("milib");
+ VersionInfo mitools = VersionInfo.getVersionInfoForArtifact("mitools");
+
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("MiTools v")
+ .append(mitools.getVersion())
+ .append(" (built ")
+ .append(mitools.getTimestamp())
+ .append("; rev=")
+ .append(mitools.getRevision())
+ .append("; branch=")
+ .append(mitools.getBranch())
+ .append(")")
+ .append("\n");
+
+ builder.append("MiLib v")
+ .append(milib.getVersion())
+ .append(" (rev=").append(milib.getRevision())
+ .append("; branch=").append(milib.getBranch())
+ .append(")");
+
+ System.out.println(builder.toString());
+ }
+ });
+
main.main(args);
}
}
diff --git a/src/main/java/com/milaboratory/mitools/cli/MergeAction.java b/src/main/java/com/milaboratory/mitools/cli/MergeAction.java
index ab78bec..206d344 100644
--- a/src/main/java/com/milaboratory/mitools/cli/MergeAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/MergeAction.java
@@ -23,15 +23,18 @@
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.validators.PositiveInteger;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
import com.milaboratory.core.PairedEndReadsLayout;
import com.milaboratory.core.io.sequence.PairedRead;
import com.milaboratory.core.io.sequence.SingleReadImpl;
import com.milaboratory.core.io.sequence.fastq.PairedFastqReader;
import com.milaboratory.core.io.sequence.fastq.SingleFastqWriter;
-import com.milaboratory.mitools.merger.MergerParameters;
-import com.milaboratory.mitools.merger.MismatchOnlyPairedReadMerger;
-import com.milaboratory.mitools.merger.PairedReadMergingResult;
-import com.milaboratory.mitools.merger.QualityMergingAlgorithm;
+import com.milaboratory.core.merger.MergerParameters;
+import com.milaboratory.core.merger.MismatchOnlyPairedReadMerger;
+import com.milaboratory.core.merger.PairedReadMergingResult;
+import com.milaboratory.core.merger.QualityMergingAlgorithm;
import com.milaboratory.util.SmartProgressReporter;
import java.io.File;
@@ -144,12 +147,6 @@ public static final class MergingParameters extends ActionParameters {
names = {"-r", "--report"})
String report;
- //@Parameter(description = "Output FASTQ file or \"-\" for STDOUT to put non-overlapped " +
- // "reverse reads (supported formats: *.fastq and *.fastq.gz).",
- // names = {"-o", "--out"},
- // required = true)
- //String output;
-
@Parameter(description = "Include both paired-end reads for pairs where no overlap was found.",
names = {"-i", "--include-non-overlapped"})
boolean includeNonOverlapped;
@@ -162,10 +159,11 @@ public static final class MergingParameters extends ActionParameters {
names = {"-ss", "--same-strand"})
boolean sameStrand;
- @Parameter(description = "Possible values: 'max' - take maximal score value in letter conflicts, 'sub' - " +
- "subtract minimal quality from maximal",
+ @Parameter(description = "Possible values: SumMax, SumSubtraction, MaxSubtraction, MaxMax. " +
+ "First word (match behaviour): Sum = sum quality values (result is limited by value of -m option); Max = maximal quality. " +
+ "Second word (mismatch behaviour): Max = take maximal score value, Subtraction = subtract minimal quality from maximal.",
names = {"-q", "--quality-merging-algorithm"})
- String qualityMergingAlgorithm = QualityMergingAlgorithm.SumSubtraction.cliName;
+ String qualityMergingAlgorithm = QualityMergingAlgorithm.MaxSubtraction.name();
@Parameter(description = "Minimal overlap.",
names = {"-p", "--overlap"}, validateWith = PositiveInteger.class)
@@ -192,7 +190,7 @@ public String getR2() {
}
public String getOutput() {
- return parameters.size() == 2 ? "-" : parameters.get(2);
+ return parameters.size() == 2 ? "." : parameters.get(2);
}
public QualityMergingAlgorithm getQualityMergingAlgorithm() {
diff --git a/src/main/java/com/milaboratory/mitools/cli/MiCLIUtil.java b/src/main/java/com/milaboratory/mitools/cli/MiCLIUtil.java
index 23bdde5..faccbdf 100644
--- a/src/main/java/com/milaboratory/mitools/cli/MiCLIUtil.java
+++ b/src/main/java/com/milaboratory/mitools/cli/MiCLIUtil.java
@@ -28,13 +28,13 @@
public class MiCLIUtil {
public static SingleFastqWriter createSingleWriter(String fileName) throws IOException {
- if (fileName.equals("-"))
+ if (fileName.equals("-") || fileName.equals("."))
return new SingleFastqWriter(System.out);
return new SingleFastqWriter(fileName);
}
public static SingleFastqReader createSingleReader(String fileName, boolean replaceWildcards) throws IOException {
- if (fileName.equals("-"))
+ if (fileName.equals("-") || fileName.equals("."))
return new SingleFastqReader(System.in, replaceWildcards);
return new SingleFastqReader(fileName, replaceWildcards);
}
diff --git a/src/main/java/com/milaboratory/mitools/cli/RCAction.java b/src/main/java/com/milaboratory/mitools/cli/RCAction.java
index 9ae9400..b6123b1 100644
--- a/src/main/java/com/milaboratory/mitools/cli/RCAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/RCAction.java
@@ -19,6 +19,10 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
+import com.milaboratory.cli.AllowNoArguments;
import com.milaboratory.core.io.sequence.SingleRead;
import com.milaboratory.core.io.sequence.SingleReadImpl;
import com.milaboratory.core.io.sequence.SingleSequenceWriter;
@@ -28,6 +32,7 @@
import java.util.ArrayList;
import java.util.List;
+@AllowNoArguments
public class RCAction implements Action {
final RCParameters actionParameters = new RCParameters();
@@ -53,17 +58,17 @@ public ActionParameters params() {
return actionParameters;
}
- @Parameters(commandDescription = "Reverse complement.", optionPrefixes = "-")
+ @Parameters(commandDescription = "Reverse complement.")
public static final class RCParameters extends ActionParameters {
@Parameter(description = "[ input_file_R1.fastq[.gz] [ output_file.fastq[.gz] ] ]", variableArity = true)
public List parameters = new ArrayList<>();
public String getInput() {
- return parameters.size() == 0 ? "-" : parameters.get(0);
+ return parameters.size() == 0 ? "." : parameters.get(0);
}
public String getOutput() {
- return parameters.size() < 2 ? "-" : parameters.get(1);
+ return parameters.size() < 2 ? "." : parameters.get(1);
}
@Override
diff --git a/src/main/java/com/milaboratory/mitools/cli/RenameAction.java b/src/main/java/com/milaboratory/mitools/cli/RenameAction.java
index 88ec675..c1a400b 100644
--- a/src/main/java/com/milaboratory/mitools/cli/RenameAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/RenameAction.java
@@ -19,6 +19,9 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
import com.milaboratory.core.io.sequence.SingleRead;
import com.milaboratory.core.io.sequence.SingleReadImpl;
import com.milaboratory.core.io.sequence.SingleSequenceWriter;
@@ -27,19 +30,38 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class RenameAction implements Action {
final RenameParameters actionParameters = new RenameParameters();
@Override
public void go(ActionHelper helper) throws Exception {
- final String pattern = actionParameters.pattern;
+ final String newName = actionParameters.name;
+
+ Pattern pattern = actionParameters.pattern == null ?
+ null :
+ Pattern.compile(actionParameters.pattern);
+
+ Matcher matcher;
+
try (SingleFastqReader reader = MiCLIUtil.createSingleReader(actionParameters.getInput(), false);
SingleSequenceWriter writer = MiCLIUtil.createSingleWriter(actionParameters.getOutput())) {
SmartProgressReporter.startProgressReport("Processing", reader, System.err);
for (SingleRead read : CUtils.it(reader)) {
- String description = pattern.replace("%n", Long.toString(read.getId()));
+ // Replacing index
+ String description = newName.replace("%n", Long.toString(read.getId()));
+
+ // Replacing old description
description = description.replace("%o", read.getDescription());
+
+ // Replacing caption groups
+ if (pattern != null)
+ if ((matcher = pattern.matcher(read.getDescription())).find())
+ for (int i = 1; i <= matcher.groupCount(); i++)
+ description = description.replace("%g" + i, matcher.group(i));
+
SingleRead rc = new SingleReadImpl(read.getId(), read.getData(), description);
writer.write(rc);
}
@@ -56,21 +78,26 @@ public ActionParameters params() {
return actionParameters;
}
- @Parameters(commandDescription = "Relabel sequences.", optionPrefixes = "-")
+ @Parameters(commandDescription = "Relabel sequences (change sequence headers).")
public static final class RenameParameters extends ActionParameters {
@Parameter(description = "[ input_file_R1.fastq[.gz] [ output_file.fastq[.gz] ] ]", variableArity = true)
public List parameters = new ArrayList<>();
- @Parameter(description = "Pattern (%n - for index; %o - for old description)",
+ @Parameter(description = "New header (%n - for index; %o - for old description; %g1, %g2, ... - for old description)",
names = {"-p", "--pattern"})
String pattern;
+ @Parameter(description = "New name (%n - for index; %o - for old description; " +
+ "%g1, %g2, ... - extracted regexp groups, if -p option used), example: -n \"R%n %o\" to add read index to header",
+ names = {"-n", "--name"})
+ String name;
+
public String getInput() {
- return parameters.size() == 0 ? "-" : parameters.get(0);
+ return parameters.size() == 0 ? "." : parameters.get(0);
}
public String getOutput() {
- return parameters.size() < 2 ? "-" : parameters.get(1);
+ return parameters.size() < 2 ? "." : parameters.get(1);
}
@Override
diff --git a/src/main/java/com/milaboratory/mitools/cli/SplitAction.java b/src/main/java/com/milaboratory/mitools/cli/SplitAction.java
index b5c1d9e..fba7c18 100644
--- a/src/main/java/com/milaboratory/mitools/cli/SplitAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/SplitAction.java
@@ -18,6 +18,9 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
import com.milaboratory.core.io.sequence.SequenceRead;
import com.milaboratory.core.io.sequence.SequenceReaderCloseable;
import com.milaboratory.core.io.sequence.SequenceWriter;
@@ -111,8 +114,8 @@ public SequenceReaderCloseable> getSequenceReader() throws IOException {
}
@Parameters(commandDescription = "Splits input fastq file(s) into several parts. \"{P}\" in output file name " +
- "will be substituted with sequential part index, \n\"{R}\" will be substituted with read index (in case " +
- "of one input file will always be substituted with \"1\").", optionPrefixes = "-")
+ "will be substituted with sequential part index, \"{R}\" will be substituted with read index (in case " +
+ "of one input file will always be substituted with \"1\").")
public static final class AParameters extends ActionParameters {
@Parameter(description = "input_file_R1.fastq[.gz] [ input_file_R2.fastq[.gz] ] output_file_part{P}_R{R}.fastq[.gz]",
variableArity = true)
diff --git a/src/main/java/com/milaboratory/mitools/cli/TrimAction.java b/src/main/java/com/milaboratory/mitools/cli/TrimAction.java
index fda457a..910775d 100644
--- a/src/main/java/com/milaboratory/mitools/cli/TrimAction.java
+++ b/src/main/java/com/milaboratory/mitools/cli/TrimAction.java
@@ -22,6 +22,9 @@
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.validators.PositiveInteger;
+import com.milaboratory.cli.Action;
+import com.milaboratory.cli.ActionHelper;
+import com.milaboratory.cli.ActionParameters;
import com.milaboratory.core.io.sequence.SingleRead;
import com.milaboratory.core.io.sequence.fastq.SingleFastqReader;
import com.milaboratory.core.io.sequence.fastq.SingleFastqWriter;
@@ -51,8 +54,8 @@ public void go(ActionHelper helper) throws Exception {
final Merger buffered = buffered(stats, 256);
- final SequenceTrimmer trimmer = new SequenceTrimmer(actionParameters.qualutyThreshold,
- actionParameters.trimmLeft(), actionParameters.trimmRight());
+ final SequenceTrimmer trimmer = new SequenceTrimmer(actionParameters.qualityThreshold,
+ actionParameters.trimLeft(), actionParameters.trimRight());
ParallelProcessor processor =
new ParallelProcessor<>(buffered, trimmer, 1024, actionParameters.threads);
@@ -91,20 +94,20 @@ public ActionParameters params() {
return actionParameters;
}
- @Parameters(commandDescription = "Trim low quality ends of reads.", optionPrefixes = "-")
+ @Parameters(commandDescription = "Trim low quality ends of reads.")
private final static class TrimParameters extends ActionParameters {
@Parameter(description = "input_file.fastq[.gz] -|output_file.fastq[.gz]", variableArity = true)
public List parameters = new ArrayList<>();
- @Parameter(description = "Trim left", names = {"-tl", "--left"})
+ @Parameter(description = "Trim from left side", names = {"-tl", "--left"})
public Boolean left;
- @Parameter(description = "Trim right", names = {"-tr", "--right"})
+ @Parameter(description = "Trim from right side", names = {"-tr", "--right"})
public Boolean right;
@Parameter(description = "Quality threshold", names = {"-q", "--quality"},
validateWith = PositiveInteger.class)
- public int qualutyThreshold = 15;
+ public int qualityThreshold = 15;
@Parameter(description = "Length threshold", names = {"-l", "--length"})
public int length = 10;
@@ -125,11 +128,11 @@ public String getOutput() {
return parameters.get(1);
}
- public boolean trimmLeft() {
+ public boolean trimLeft() {
return left == null ? false : left;
}
- public boolean trimmRight() {
+ public boolean trimRight() {
return right == null ? false : right;
}
diff --git a/src/main/java/com/milaboratory/mitools/merger/MergerParameters.java b/src/main/java/com/milaboratory/mitools/merger/MergerParameters.java
deleted file mode 100644
index 10046fa..0000000
--- a/src/main/java/com/milaboratory/mitools/merger/MergerParameters.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.milaboratory.core.PairedEndReadsLayout;
-import com.milaboratory.primitivio.annotations.Serializable;
-
-/**
- * @author Dmitry Bolotin
- * @author Stanislav Poslavsky
- */
-@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
- getterVisibility = JsonAutoDetect.Visibility.NONE)
-@Serializable(asJson = true)
-public final class MergerParameters implements java.io.Serializable {
- public static final int DEFAULT_MAX_QUALITY_VALUE = 50;
-
- final QualityMergingAlgorithm qualityMergingAlgorithm;
- final PairedEndReadsLayout partsLayout;
- final int minimalOverlap, maxQuality;
- final double minimalIdentity;
-
- @JsonCreator
- public MergerParameters(
- @JsonProperty("qualityMergingAlgorithm") QualityMergingAlgorithm qualityMergingAlgorithm,
- @JsonProperty("partsLayout") PairedEndReadsLayout partsLayout,
- @JsonProperty("minimalOverlap") int minimalOverlap,
- @JsonProperty("maxQuality") Integer maxQuality,
- @JsonProperty("minimalIdentity") double minimalIdentity) {
- this.qualityMergingAlgorithm = qualityMergingAlgorithm;
- this.partsLayout = partsLayout;
- this.minimalOverlap = minimalOverlap;
- this.minimalIdentity = minimalIdentity;
- this.maxQuality = maxQuality == null ? DEFAULT_MAX_QUALITY_VALUE : maxQuality;
- }
-
- public int getMinimalOverlap() {
- return minimalOverlap;
- }
-
- public double getMinimalIdentity() {
- return minimalIdentity;
- }
-
- public int getMaxQuality() {
- return maxQuality;
- }
-
- public QualityMergingAlgorithm getQualityMergingAlgorithm() {
- return qualityMergingAlgorithm;
- }
-
- public PairedEndReadsLayout getPartsLayout() {
- return partsLayout;
- }
-
- public MergerParameters overrideReadsLayout(PairedEndReadsLayout partsLayout) {
- return new MergerParameters(qualityMergingAlgorithm, partsLayout, minimalOverlap, maxQuality, minimalIdentity);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- MergerParameters that = (MergerParameters) o;
-
- if (minimalOverlap != that.minimalOverlap) return false;
- if (maxQuality != that.maxQuality) return false;
- if (Double.compare(that.minimalIdentity, minimalIdentity) != 0) return false;
- if (qualityMergingAlgorithm != that.qualityMergingAlgorithm) return false;
- return partsLayout == that.partsLayout;
-
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- result = qualityMergingAlgorithm != null ? qualityMergingAlgorithm.hashCode() : 0;
- result = 31 * result + (partsLayout != null ? partsLayout.hashCode() : 0);
- result = 31 * result + minimalOverlap;
- result = 31 * result + maxQuality;
- temp = Double.doubleToLongBits(minimalIdentity);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMerger.java b/src/main/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMerger.java
deleted file mode 100644
index edc18c1..0000000
--- a/src/main/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMerger.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-import cc.redberry.pipe.Processor;
-import com.milaboratory.core.PairedEndReadsLayout;
-import com.milaboratory.core.io.sequence.PairedRead;
-import com.milaboratory.core.motif.BitapMatcher;
-import com.milaboratory.core.motif.BitapPattern;
-import com.milaboratory.core.motif.Motif;
-import com.milaboratory.core.motif.MotifUtils;
-import com.milaboratory.core.sequence.NSequenceWithQuality;
-import com.milaboratory.core.sequence.NucleotideSequence;
-import com.milaboratory.core.sequence.SequenceBuilder;
-import com.milaboratory.core.sequence.SequenceQualityBuilder;
-
-import static com.milaboratory.core.sequence.SequencesUtils.mismatchCount;
-import static java.lang.Math.*;
-
-public final class MismatchOnlyPairedReadMerger implements Processor,
- java.io.Serializable {
- public static final int MIN_SCORE_VALUE = 3; // 50-50
- final int minOverlap;
- final double maxMismatchesPart;
- final int maxScoreValue;
- // opposite reads direction or collinear
- final boolean[] strands;
- final int motifLength;
- final int maxMismatchesInMotif;
- final QualityMergingAlgorithm qualityMergingAlgorithm;
- final PairedEndReadsLayout pairedEndReadsLayout;
-
- /**
- * Creates paired-end reads merger for Illumina (or other opposite reads) data.
- *
- * @param parameters merger parameters
- */
- public MismatchOnlyPairedReadMerger(MergerParameters parameters) {
- this(parameters.getMinimalOverlap(), parameters.getMinimalIdentity(), parameters.getMaxQuality(),
- parameters.qualityMergingAlgorithm, parameters.getPartsLayout());
- }
-
- /**
- * Creates paired-end reads merger.
- *
- * @param minOverlap minimal number of nucleotide in overlap region
- * @param minimalIdentity maximal allowed percent of mismatches in overlap region
- * @param maxScoreValue maximal output quality score value
- * @param qualityMergingAlgorithm algorithm to infer quality of merged reads from it's pairs
- * @param pairedEndReadsLayout orientation of read pairs
- */
- public MismatchOnlyPairedReadMerger(int minOverlap, double minimalIdentity, int maxScoreValue,
- QualityMergingAlgorithm qualityMergingAlgorithm,
- PairedEndReadsLayout pairedEndReadsLayout) {
- if (qualityMergingAlgorithm == null || pairedEndReadsLayout == null)
- throw new NullPointerException();
- this.qualityMergingAlgorithm = qualityMergingAlgorithm;
- this.pairedEndReadsLayout = pairedEndReadsLayout;
- this.minOverlap = minOverlap;
- this.maxMismatchesPart = 1.0 - minimalIdentity;
- this.strands = pairedEndReadsLayout.getPossibleRelativeStrands();
- this.maxScoreValue = maxScoreValue;
-
- // Calculating length fo motif to be used in Bitap search.
- this.motifLength = min(minOverlap, 62);
- this.maxMismatchesInMotif = (int) round(motifLength * maxMismatchesPart);
- }
-
- @Override
- public PairedReadMergingResult process(PairedRead pairedRead) {
- NSequenceWithQuality read1p = pairedRead.getR1().getData();
- NSequenceWithQuality read2p = pairedRead.getR2().getData();
-
- // If there is no sufficient letters in one of read overlapping is impossible
- if (read1p.size() < minOverlap || read2p.size() < minOverlap)
- // Return failed result
- return new PairedReadMergingResult(pairedRead);
-
- PairedReadMergingResult ret = null;
-
- for (boolean strand : strands) {
- NSequenceWithQuality read1 = read1p;
-
- // Making reverse complement from second read to bring reads to the same strand
- // (if reads configuration is opposite)
- NSequenceWithQuality read2 = strand ? read2p.getReverseComplement() : read2p;
-
- // read2 always smaller then read1
- if (read2.size() > read1.size()) {
- NSequenceWithQuality tmp = read1;
- read1 = read2;
- read2 = tmp;
- }
-
- // Searching
-
- // Creating bitap pattern for beginning and ending of read2
- Motif motif = MotifUtils.twoSequenceMotif(
- read2.getSequence(), 0,
- read2.getSequence(), read2.size() - motifLength,
- motifLength
- );
- BitapPattern bitapPattern = motif.getBitapPattern();
- BitapMatcher bitapMatcher = bitapPattern.substitutionOnlyMatcherFirst(maxMismatchesInMotif, read1.getSequence());
-
- int matchPosition, mismatches, overlap;
-
- PairedReadMergingResult tmp = null;
- while ((matchPosition = bitapMatcher.findNext()) != -1) {
-
- // Case: beginning of r2 matched
-
- // Finally checking current hit position
- overlap = min(read1.size() - matchPosition, read2.size());
- if ((mismatches = mismatchCount(
- read1.getSequence(), matchPosition,
- read2.getSequence(), 0,
- overlap)) <= overlap * maxMismatchesPart) {
- tmp = new PairedReadMergingResult(pairedRead, overlap(read1, read2, matchPosition),
- overlap, mismatches);
- break;
- }
-
- // Case: ending of r2 matched
- matchPosition += motifLength; // Calculating position of right overlap boundary
- overlap = min(matchPosition, read2.size());
- if ((mismatches = mismatchCount(
- read1.getSequence(), matchPosition - overlap,
- read2.getSequence(), max(0, read2.size() - overlap),
- overlap)) <= overlap * maxMismatchesPart) {
- tmp = new PairedReadMergingResult(pairedRead, overlap(read1, read2, min(matchPosition - read2.size(), 0)),
- overlap, mismatches);
- break;
- }
- }
- if (tmp != null && (ret == null || ret.score() < tmp.score()))
- ret = tmp;
- }
-
- if (ret == null)
- return new PairedReadMergingResult(pairedRead);
- else
- return ret;
- }
-
- /**
- * @param seq1 sequence 1
- * @param seq2 sequence 2
- * @param offset position of first nucleotide of seq2 in seq1
- * @return overlapped sequence
- */
- private NSequenceWithQuality overlap(NSequenceWithQuality seq1, NSequenceWithQuality seq2, int offset) {
- // Calculating length of resulting sequence
- int length = abs(offset) +
- (offset >= 0 ?
- max(seq1.size() - offset, seq2.size()) :
- max(seq1.size(), seq2.size() + offset) // offset is negative here
- );
-
- SequenceBuilder seqBuilder = NucleotideSequence.ALPHABET.getBuilder()
- .ensureCapacity(length);
- SequenceQualityBuilder qualBuilder = new SequenceQualityBuilder().ensureCapacity(length);
-
- byte quality, letter, l, q;
- int from = min(0, offset);
- int position, to = length + from;
- for (int i = from; i < to; ++i) {
- quality = 0;
- letter = -1;
-
- // Checking read 1
- if (i >= 0 && i < seq1.size()) {
- quality = seq1.getQuality().value(i);
- letter = seq1.getSequence().codeAt(i);
- }
-
- // Checking read 2
- position = i - offset;
- if (position >= 0 && position < seq2.size()) {
- l = seq2.getSequence().codeAt(position);
- q = seq2.getQuality().value(position);
- if (letter == -1) {
- letter = l;
- quality = q;
- } else if (letter == l)
- quality = (byte) min(maxScoreValue, quality + q);
- else
- switch (qualityMergingAlgorithm) {
- case SumSubtraction:
- if (q > quality) {
- letter = l;
- quality = (byte) max(MIN_SCORE_VALUE, q - quality);
- } else
- quality = (byte) max(MIN_SCORE_VALUE, quality - q);
- break;
- case SumMax:
- if (q > quality) {
- letter = l;
- quality = q;
- }
- break;
- }
- }
-
- assert letter != -1;
-
- seqBuilder.append(letter);
- qualBuilder.append(quality);
- }
-
- return new NSequenceWithQuality(seqBuilder.createAndDestroy(), qualBuilder.createAndDestroy());
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/merger/PairedReadMergingResult.java b/src/main/java/com/milaboratory/mitools/merger/PairedReadMergingResult.java
deleted file mode 100644
index c262d63..0000000
--- a/src/main/java/com/milaboratory/mitools/merger/PairedReadMergingResult.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-import com.milaboratory.core.io.sequence.PairedRead;
-import com.milaboratory.core.sequence.NSequenceWithQuality;
-
-public class PairedReadMergingResult implements java.io.Serializable {
- private static final int MATCH_SCORE = 2;
- private static final int MISMATCH_SCORE = -5;
-
- final PairedRead originalRead;
- final NSequenceWithQuality overlappedSequence;
- final int overlap;
- final int errors;
-
- /**
- * Constructor for failed merging result.
- *
- * @param originalRead original read
- */
- public PairedReadMergingResult(PairedRead originalRead) {
- this.originalRead = originalRead;
- this.overlappedSequence = null;
- this.overlap = 0;
- this.errors = -1;
- }
-
- /**
- * Constructor for successful merging result.
- *
- * @param originalRead original read
- * @param overlappedSequence reconstructed (overlapped) sequence from paired-end reads
- * @param overlap number of overlapped nucleotides
- * @param errors number of mismatches/insertions/deletions found in overlapping region
- */
- public PairedReadMergingResult(PairedRead originalRead, NSequenceWithQuality overlappedSequence,
- int overlap, int errors) {
- this.originalRead = originalRead;
- this.overlappedSequence = overlappedSequence;
- this.overlap = overlap;
- this.errors = errors;
- }
-
- public boolean isSuccessful() {
- return overlappedSequence != null;
- }
-
- public PairedRead getOriginalRead() {
- return originalRead;
- }
-
- public NSequenceWithQuality getOverlappedSequence() {
- return overlappedSequence;
- }
-
- public int getOverlap() {
- return overlap;
- }
-
- public int getErrors() {
- return errors;
- }
-
- int score() {
- return (overlap - errors) * MATCH_SCORE + errors * MISMATCH_SCORE;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- PairedReadMergingResult that = (PairedReadMergingResult) o;
-
- if (overlap != that.overlap) return false;
- if (errors != that.errors) return false;
- if (!originalRead.equals(that.originalRead)) return false;
- return overlappedSequence.equals(that.overlappedSequence);
-
- }
-
- @Override
- public int hashCode() {
- int result = originalRead.hashCode();
- result = 31 * result + overlappedSequence.hashCode();
- result = 31 * result + overlap;
- result = 31 * result + errors;
- return result;
- }
-
- @Override
- public String toString() {
- return "PairedReadMergingResult{" +
- "originalRead=" + originalRead +
- ", overlappedSequence=" + overlappedSequence +
- ", overlap=" + overlap +
- ", errors=" + errors +
- '}';
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/merger/QualityMergingAlgorithm.java b/src/main/java/com/milaboratory/mitools/merger/QualityMergingAlgorithm.java
deleted file mode 100644
index e20f629..0000000
--- a/src/main/java/com/milaboratory/mitools/merger/QualityMergingAlgorithm.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-public enum QualityMergingAlgorithm {
- SumMax("max"), SumSubtraction("sub");
- public final String cliName;
-
- QualityMergingAlgorithm(String cliName) {
- this.cliName = cliName;
- }
-
- public static QualityMergingAlgorithm getFromCLIName(String cliName) {
- for (QualityMergingAlgorithm qma : values())
- if (qma.cliName.equals(cliName))
- return qma;
- return null;
- }
-}
diff --git a/src/main/java/com/milaboratory/mitools/cli/ActionParametersParser.java b/src/main/java/com/milaboratory/mitools/processors/CutSide.java
similarity index 78%
rename from src/main/java/com/milaboratory/mitools/cli/ActionParametersParser.java
rename to src/main/java/com/milaboratory/mitools/processors/CutSide.java
index e52b270..3e5a8d9 100644
--- a/src/main/java/com/milaboratory/mitools/cli/ActionParametersParser.java
+++ b/src/main/java/com/milaboratory/mitools/processors/CutSide.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 MiLaboratory.com
+ * Copyright 2016 MiLaboratory.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.milaboratory.mitools.cli;
+package com.milaboratory.mitools.processors;
-public interface ActionParametersParser {
- void parseParameters(String[] args);
+public enum CutSide {
+ Left, Random, Right
}
diff --git a/src/main/java/com/milaboratory/mitools/processors/RandomCutter.java b/src/main/java/com/milaboratory/mitools/processors/RandomCutter.java
new file mode 100644
index 0000000..421c2cd
--- /dev/null
+++ b/src/main/java/com/milaboratory/mitools/processors/RandomCutter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 MiLaboratory.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.milaboratory.mitools.processors;
+
+import cc.redberry.pipe.Processor;
+import com.milaboratory.core.io.sequence.SingleRead;
+import com.milaboratory.core.io.sequence.SingleReadImpl;
+import com.milaboratory.util.RandomUtil;
+import org.apache.commons.math3.random.RandomGenerator;
+import org.apache.commons.math3.random.Well44497b;
+
+public final class RandomCutter implements Processor {
+ private final CutSide side;
+ private final int minLength, maxLength;
+ private final long seed;
+
+ public RandomCutter(CutSide side, int minLength, int maxLength) {
+ this(side, minLength, maxLength, 0);
+ }
+
+ public RandomCutter(CutSide side, int minLength, int maxLength, long seed) {
+ if (side == null)
+ throw new NullPointerException();
+ this.side = side;
+ this.minLength = minLength;
+ this.maxLength = maxLength;
+ this.seed = seed;
+ }
+
+ @Override
+ public SingleRead process(SingleRead input) {
+ RandomGenerator rnd;
+ if (seed == 0)
+ rnd = RandomUtil.getThreadLocalRandom();
+ else {
+ Well44497b w = new Well44497b(seed);
+ w.setSeed(5147 * w.nextLong() + 7549 * input.getId());
+ rnd = w;
+ }
+ int length;
+ if (minLength == maxLength)
+ length = minLength;
+ else
+ length = minLength + rnd.nextInt(maxLength - minLength + 1);
+ if (length > input.getData().size())
+ length = input.getData().size();
+
+ int startPosition;
+
+ switch (side) {
+ case Left:
+ startPosition = 0;
+ break;
+ case Right:
+ startPosition = input.getData().size() - length;
+ break;
+ case Random:
+ startPosition = length == input.getData().size() ? 0 : rnd.nextInt(input.getData().size() - length + 1);
+ break;
+ default:
+ // Will never be thrown
+ throw new IllegalArgumentException();
+ }
+
+ return new SingleReadImpl(input.getId(), input.getData().getRange(startPosition, startPosition + length), input.getDescription());
+ }
+}
diff --git a/src/main/java/com/milaboratory/mitools/cli/ActionHelpProvider.java b/src/main/java/com/milaboratory/mitools/util/VersionInfoUtils.java
similarity index 75%
rename from src/main/java/com/milaboratory/mitools/cli/ActionHelpProvider.java
rename to src/main/java/com/milaboratory/mitools/util/VersionInfoUtils.java
index 26e475c..2d47bd7 100644
--- a/src/main/java/com/milaboratory/mitools/cli/ActionHelpProvider.java
+++ b/src/main/java/com/milaboratory/mitools/util/VersionInfoUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 MiLaboratory.com
+ * Copyright 2016 MiLaboratory.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.milaboratory.mitools.cli;
+package com.milaboratory.mitools.util;
/**
- * Created by dbolotin on 28/08/14.
+ * Created by dbolotin on 12/07/16.
*/
-public interface ActionHelpProvider {
- void printHelp(StringBuilder builder);
+public class VersionInfoUtils {
}
diff --git a/src/test/java/com/milaboratory/mitools/merger/MergerParametersTest.java b/src/test/java/com/milaboratory/mitools/merger/MergerParametersTest.java
deleted file mode 100644
index a2749b4..0000000
--- a/src/test/java/com/milaboratory/mitools/merger/MergerParametersTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-import com.milaboratory.core.PairedEndReadsLayout;
-import com.milaboratory.test.TestUtil;
-import com.milaboratory.util.GlobalObjectMappers;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class MergerParametersTest {
- @Test
- public void test1() throws Exception {
- MergerParameters parameters = new MergerParameters(QualityMergingAlgorithm.SumMax, null, 15, 50, 0.8);
- TestUtil.assertJson(parameters);
- }
-
- @Test
- public void test2() throws Exception {
- MergerParameters parameters = new MergerParameters(QualityMergingAlgorithm.SumSubtraction,
- PairedEndReadsLayout.Collinear, 15, 50, 0.8);
- TestUtil.assertJson(parameters, true);
- }
-
- @Test
- public void test3() throws Exception {
- MergerParameters parameters = new MergerParameters(QualityMergingAlgorithm.SumSubtraction,
- PairedEndReadsLayout.Collinear, 15, 50, 0.8);
- String value = "{\n" +
- " \"qualityMergingAlgorithm\" : \"SumSubtraction\",\n" +
- " \"partsLayout\" : \"Collinear\",\n" +
- " \"minimalOverlap\" : 15,\n" +
- " \"minimalIdentity\" : 0.8\n" +
- "}";
- MergerParameters deserialized = GlobalObjectMappers.PRETTY.readValue(value, MergerParameters.class);
- Assert.assertEquals(parameters, deserialized);
- }
-
-}
\ No newline at end of file
diff --git a/src/test/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMergerTest.java b/src/test/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMergerTest.java
deleted file mode 100644
index 37ed68e..0000000
--- a/src/test/java/com/milaboratory/mitools/merger/MismatchOnlyPairedReadMergerTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2015 MiLaboratory.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.milaboratory.mitools.merger;
-
-import com.milaboratory.core.PairedEndReadsLayout;
-import com.milaboratory.core.io.sequence.PairedRead;
-import com.milaboratory.core.io.sequence.SingleReadImpl;
-import com.milaboratory.core.sequence.NSequenceWithQuality;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class MismatchOnlyPairedReadMergerTest {
- @Test
- public void test1() throws Exception {
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCC
- // CGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //AAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbbbbbbbbbbbbbbbbbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCC",
- "CGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 0, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
- }
-
- @Test
- public void test2() throws Exception {
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- // TGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTT
- //AAAAAAAAAAbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "TGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTT",
- 0, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
- }
-
- @Test
- public void test3() throws Exception {
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATC
- // TCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbbbbbbbbbbbbbbbbbbbBBBBBBBBBBBBBBBBBBBBBBBBBBBB
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATC",
- "TCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 0, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
- }
-
- @Test
- public void test1mm() throws Exception {
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGACGACCGGCC
- // CGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //AAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbbbbbbbbBbbbbbbbbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGACGACCGGCC",
- "CGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 1, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXX$XXXXXXXXBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGACGACCGGCC",
- "CGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 0, 10, null, null);
- }
-
- @Test
- public void test2mm() throws Exception {
- //CGCACAGTGTTGTCAAAGACAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- // TGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTT
- //AAAAAAAAAAbbbbbbbbbBbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
- mAssert("CGCACAGTGTTGTCAAAGACAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "TGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTT",
- 1, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAXXXXXXXXX$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
- mAssert("CGCACAGTGTTGTCAAAGACAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "TGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTT",
- 0, 10, null, null);
- }
-
- @Test
- public void test3mm() throws Exception {
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTACTCCTTTGACATGATTGGATC
- // TCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG
- //AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbbbbbbbbbbbbbbbbbbbbbBBBBBBBBBBBBBBBBBBBBBBBBBBBB
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTACTCCTTTGACATGATTGGATC",
- "TCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 1, 10,
- "CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTTCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$XXXXXXXXXXXXXXXXXXXXXBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
- mAssert("CGCACAGTGTTGTCAAAGAAAACGCGTACGACATTGAGAAGACCGGCCGTACTCCTTTGACATGATTGGATC",
- "TCTCCTTTGACATGATTGGATCGGTTGCTGCCGGCCCAGAATCCTAGCAG",
- 0, 10, null, null);
- }
-
- public static void mAssert(String seq1, String seq2, int maxMuts, int overlap,
- String expectedSequence, String expectedQuality) {
- MismatchOnlyPairedReadMerger merger = new MismatchOnlyPairedReadMerger(overlap, 1.0 - 1.0 * maxMuts / overlap, 55,
- QualityMergingAlgorithm.SumSubtraction,
- PairedEndReadsLayout.Collinear);
- PairedReadMergingResult processed = merger.process(new PairedRead(
- new SingleReadImpl(0, new NSequenceWithQuality(seq1, lets('A', seq1.length())), "A"),
- new SingleReadImpl(0, new NSequenceWithQuality(seq2, lets('B', seq2.length())), "B")));
- if (expectedSequence == null)
- Assert.assertFalse(processed.isSuccessful());
- else {
- Assert.assertTrue(processed.isSuccessful());
- Assert.assertEquals(expectedSequence, processed.getOverlappedSequence().getSequence().toString());
- Assert.assertEquals(expectedQuality, processed.getOverlappedSequence().getQuality().toString());
- }
-
- merger = new MismatchOnlyPairedReadMerger(overlap, 1.0 - 1.0 * maxMuts / overlap, 55,
- QualityMergingAlgorithm.SumSubtraction,
- PairedEndReadsLayout.Unknown);
- processed = merger.process(new PairedRead(
- new SingleReadImpl(0, new NSequenceWithQuality(seq1, lets('A', seq1.length())), "A"),
- new SingleReadImpl(0, new NSequenceWithQuality(seq2, lets('B', seq2.length())).getReverseComplement(), "B")));
- if (expectedSequence == null)
- Assert.assertFalse(processed.isSuccessful());
- else {
- Assert.assertTrue(processed.isSuccessful());
- Assert.assertEquals(expectedSequence, processed.getOverlappedSequence().getSequence().toString());
- Assert.assertEquals(expectedQuality, processed.getOverlappedSequence().getQuality().toString());
- }
- }
-
- public static String lets(char letter, int count) {
- char[] chars = new char[count];
- Arrays.fill(chars, letter);
- return new String(chars);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/milaboratory/mitools/merger/PairedReadMergingResultTest.java b/src/test/java/com/milaboratory/mitools/merger/PairedReadMergingResultTest.java
deleted file mode 100644
index a26104c..0000000
--- a/src/test/java/com/milaboratory/mitools/merger/PairedReadMergingResultTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.milaboratory.mitools.merger;
-
-import com.milaboratory.core.io.sequence.PairedRead;
-import com.milaboratory.core.io.sequence.SingleReadImpl;
-import com.milaboratory.core.io.util.TestUtil;
-import com.milaboratory.core.sequence.NSequenceWithQuality;
-import com.milaboratory.core.sequence.NucleotideSequence;
-import com.milaboratory.core.sequence.SequenceQuality;
-import org.junit.Test;
-
-/**
- * Created by poslavsky on 15/04/15.
- */
-public class PairedReadMergingResultTest {
- @Test
- public void test1() throws Exception {
- PairedReadMergingResult se = new PairedReadMergingResult(new PairedRead(
- new SingleReadImpl(12, new NSequenceWithQuality(new NucleotideSequence("atgc"), new SequenceQuality("++++")), "x"),
- new SingleReadImpl(12, new NSequenceWithQuality(new NucleotideSequence("atgc"), new SequenceQuality("++++")), "x")),
- new NSequenceWithQuality(new NucleotideSequence("atgc"), new SequenceQuality("++++")), 12, 3);
- TestUtil.assertJavaSerialization(se);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/milaboratory/mitools/processors/RandomCutterTest.java b/src/test/java/com/milaboratory/mitools/processors/RandomCutterTest.java
new file mode 100644
index 0000000..c3e395a
--- /dev/null
+++ b/src/test/java/com/milaboratory/mitools/processors/RandomCutterTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 MiLaboratory.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.milaboratory.mitools.processors;
+
+import com.milaboratory.core.io.sequence.SingleRead;
+import com.milaboratory.core.io.sequence.SingleReadImpl;
+import com.milaboratory.core.sequence.NSequenceWithQuality;
+import gnu.trove.set.hash.TIntHashSet;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Created by dbolotin on 10/03/16.
+ */
+public class RandomCutterTest {
+ @Test
+ public void test1() throws Exception {
+ RandomCutter cutter = new RandomCutter(CutSide.Random, 10, 20);
+ SingleReadImpl read = new SingleReadImpl(1, new NSequenceWithQuality("ATTAGACA"), "Hi!");
+ SingleRead processed = cutter.process(read);
+ Assert.assertEquals(processed, read);
+
+ TIntHashSet vals = new TIntHashSet();
+
+ for (int i = 0; i < 1000; i++) {
+ read = new SingleReadImpl(1, new NSequenceWithQuality("ATTAGACAATTAGACAATTAGACAATTAGACA"), "Hi!");
+ processed = cutter.process(read);
+ Assert.assertTrue(processed.getData().size() >= 10 && processed.getData().size() <= 20);
+ vals.add(processed.getData().size());
+ }
+ Assert.assertTrue(vals.contains(20));
+ Assert.assertTrue(vals.contains(10));
+
+ cutter = new RandomCutter(CutSide.Left, 10, 20);
+ vals = new TIntHashSet();
+ for (int i = 0; i < 1000; i++) {
+ read = new SingleReadImpl(1, new NSequenceWithQuality("ATTAGACAATTAGACAATTAGACAATTAGACA"), "Hi!");
+ processed = cutter.process(read);
+ Assert.assertTrue(processed.getData().size() >= 10 && processed.getData().size() <= 20);
+ Assert.assertTrue(read.getData().getSequence().toString().startsWith(processed.getData().getSequence().toString()));
+ vals.add(processed.getData().size());
+
+ }
+ Assert.assertTrue(vals.contains(20));
+ Assert.assertTrue(vals.contains(10));
+
+ cutter = new RandomCutter(CutSide.Right, 10, 20);
+ vals = new TIntHashSet();
+ for (int i = 0; i < 1000; i++) {
+ read = new SingleReadImpl(1, new NSequenceWithQuality("ATTAGACAATTAGACAATTAGACAATTAGACA"), "Hi!");
+ processed = cutter.process(read);
+ Assert.assertTrue(processed.getData().size() >= 10 && processed.getData().size() <= 20);
+ Assert.assertTrue(read.getData().getSequence().toString().endsWith(processed.getData().getSequence().toString()));
+ vals.add(processed.getData().size());
+ }
+ Assert.assertTrue(vals.contains(20));
+ Assert.assertTrue(vals.contains(10));
+ }
+}
\ No newline at end of file