[med-svn] [Git][med-team/bowtie2][master] 9 commits: Remove libmath-random-perl from Test-Depends (test is patched out anyway)

Andreas Tille (@tille) gitlab at salsa.debian.org
Wed Aug 7 12:42:33 BST 2024



Andreas Tille pushed to branch master at Debian Med / bowtie2


Commits:
f0bab21a by Andreas Tille at 2024-08-07T11:49:13+02:00
Remove libmath-random-perl from Test-Depends (test is patched out anyway)

- - - - -
f9b80e82 by Andreas Tille at 2024-08-07T11:49:43+02:00
Drop UNRELEASED changelog chunk

- - - - -
77f3e8ee by Andreas Tille at 2024-08-07T11:50:15+02:00
routine-update: New upstream version

- - - - -
5d6c8de7 by Andreas Tille at 2024-08-07T11:50:16+02:00
New upstream version 2.5.4
- - - - -
19ed9f35 by Andreas Tille at 2024-08-07T11:50:29+02:00
Update upstream source from tag 'upstream/2.5.4'

Update to upstream version '2.5.4'
with Debian dir 8b7925328a822ad6bb1dd4410965c4c64c4b0160
- - - - -
0825dcb8 by Andreas Tille at 2024-08-07T11:50:29+02:00
routine-update: Standards-Version: 4.7.0

- - - - -
0369ca2e by Andreas Tille at 2024-08-07T11:56:14+02:00
Refresh patches

- - - - -
145d938f by Andreas Tille at 2024-08-07T13:31:21+02:00
Really exclude all test requiring Math:Random which is non-free

- - - - -
1e7e199d by Andreas Tille at 2024-08-07T13:35:25+02:00
Upload to unstable

- - - - -


26 changed files:

- .github/workflows/random-tests.yml
- .github/workflows/simple-tests.yml
- BOWTIE2_VERSION
- MANUAL
- MANUAL.markdown
- NEWS
- README.md
- aln_sink.cpp
- bt2_idx.h
- bt2_search.cpp
- debian/changelog
- debian/control
- − debian/patches/drop-not-needed-js-from-manual.patch
- debian/patches/reproducible.patch
- debian/patches/series
- debian/patches/skip_test_requiring_non-free_libmath-random-perl.patch
- debian/tests/control
- doc/manual.html
- doc/website/manual.ssi
- doc/website/recent_news.ssi
- doc/website/rhsidebar.ssi
- filebuf.h
- opts.h
- pat.cpp
- sam.h
- tokenize.h


Changes:

=====================================
.github/workflows/random-tests.yml
=====================================
@@ -60,6 +60,10 @@ jobs:
     runs-on: macos-latest
     steps:
       - uses: actions/checkout at v2
+      - name: Pull submodules
+        run: |
+          git submodule init
+          git submodule update
       - name: Run random tests
         run: |
           make clean; make -j4 allall


=====================================
.github/workflows/simple-tests.yml
=====================================
@@ -58,6 +58,10 @@ jobs:
     runs-on: macos-latest
     steps:
       - uses: actions/checkout at v2
+      - name: Pull submodules
+        run: |
+          git submodule init
+          git submodule update
       - name: Run simple tests
         run: |
           make clean; make -j4 allall


=====================================
BOWTIE2_VERSION
=====================================
@@ -1 +1 @@
-2.5.3
+2.5.4


=====================================
MANUAL
=====================================
@@ -153,28 +153,33 @@ wrapper will help determine the appropriate index type for uncompressed
 and gzipped inputs.
 
 To build bowtie2-build with libsais first make sure that the libsais
-submodule is available. This can be done in one of the following ways: *
-first time cloning bowtie2 --
-git clone --recursive https://github.com/BenLangmead/bowtie2.git *
-existing checkout of bowtie2 --
-git submodule init && git submodule update
+submodule is available. This can be done in one of the following ways:
 
-Issue the following command line to build libsais: * with OpenMP support
--- [g]make libsais USE_SAIS_OPENMP=1 * without OpenMP support --
-[g]make libsais USE_SAIS=1
+-   first time cloning bowtie2 --
+    git clone --recursive https://github.com/BenLangmead/bowtie2.git
+-   existing checkout of bowtie2 --
+    git submodule init && git submodule update
+
+Issue the following command line to build libsais:
+
+-   with OpenMP support -- [g]make libsais USE_SAIS_OPENMP=1
+-   without OpenMP support -- [g]make libsais USE_SAIS=1
 
 The choice of using OpenMP will determine whether or not the algorithm
 runs multithreaded. The [-p/--threads] argument to bowtie2-build will be
 ignored when libsais is compiled without OpenMP support.
 
-Finally, building the build executable: * with OpenMP support --
-[g]make bowtie2-build-s USE_SAIS_OPENMP=1 * without OpenMP support --
-[g]make bowtie2-build-s USE_SAIS=1
+Finally, building the bowtie2-build executable:
+
+-   with OpenMP support -- [g]make bowtie2-build-s USE_SAIS_OPENMP=1
+-   without OpenMP support -- [g]make bowtie2-build-s USE_SAIS=1
 
 Building with CMake
 
 To build Bowtie2 with SRA and libsais support issue the following
-command: * cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .
+command:
+
+-   cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .
 
 CMake will take care of building and linking against the specified
 dependencies.
@@ -816,7 +821,7 @@ alignment to be considered valid, and x is the read length.
 
 Usage
 
-    bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | b <bam>} -S [<sam>]
+    bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | -b <bam>} -S [<sam>]
 
 Main arguments
 
@@ -1489,6 +1494,17 @@ Use '='/'X', instead of 'M', to specify matches/mismatches in SAM record
 Append FASTA/FASTQ comment to SAM record, where a comment is everything
 after the first space in the read name.
 
+    --sam-opt-config <config>
+
+Use <config> to toggle SAM Optional Fields where <config> is a string of
+comma delimited, case-insensitive, two-letter tags. Tags prefixed with a
+"-" will be turned off and hence will not be included in the SAM output.
+The example below turns off the "MD" tag and enables the
+bowtie2-specific "YP" tag. The config is additive, so, any default OPT
+flags that need to be turned off will have to explicitly specified.
+
+    `bowtie2 ... --sam-opt-config "-md,yp"
+
 Performance options
 
     -o/--offrate <int>


=====================================
MANUAL.markdown
=====================================
@@ -158,10 +158,12 @@ will help determine the appropriate index type for uncompressed and gzipped inpu
 
 To build `bowtie2-build` with [libsais] first make sure that the libsais submodule
 is available. This can be done in one of the following ways:
+
 * first time cloning bowtie2 -- `git clone --recursive https://github.com/BenLangmead/bowtie2.git`
 * existing checkout of bowtie2 -- `git submodule init && git submodule update`
 
 Issue the following command line to build libsais:
+
 * with OpenMP support -- `[g]make libsais USE_SAIS_OPENMP=1`
 * without OpenMP support -- `[g]make libsais USE_SAIS=1`
 
@@ -169,13 +171,15 @@ The choice of using OpenMP will determine whether or not the algorithm
 runs multithreaded. The [`-p/--threads`] argument to `bowtie2-build` will
 be ignored when libsais is compiled without OpenMP support.
 
-Finally, building the build executable:
+Finally, building the bowtie2-build executable:
+
 * with OpenMP support -- `[g]make bowtie2-build-s USE_SAIS_OPENMP=1`
 * without OpenMP support -- `[g]make bowtie2-build-s USE_SAIS=1`
 
 ### Building with CMake ###
 
 To build Bowtie2 with SRA and libsais support issue the following command:
+
 * `cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .`
 
 CMake will take care of building and linking against the specified dependencies.
@@ -813,7 +817,7 @@ considered valid, and `x` is the read length.
 
 ### Usage
 
-    bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | b <bam>} -S [<sam>]
+    bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | -b <bam>} -S [<sam>]
 
 ### Main arguments
 
@@ -1908,6 +1912,23 @@ Use `'='/'X'`, instead of `'M'`, to specify matches/mismatches in SAM record
 Append FASTA/FASTQ comment to SAM record, where a comment is everything
 after the first space in the read name.
 
+</td></tr>
+<tr><td id="bowtie2-options-sam-opt-config">
+
+    --sam-opt-config <config>
+
+</td><td>
+
+Use `<config>` to toggle SAM Optional Fields where `<config>` is a
+string of comma delimited, case-insensitive, two-letter tags.  Tags
+prefixed with a "-" will be turned off and hence will not be included
+in the SAM output. The example below turns off the "MD" tag and
+enables the `bowtie2`-specific "YP" tag. The config is additive, so,
+any default OPT flags that need to be turned off will have to
+explicitly specified.
+
+    `bowtie2 ... --sam-opt-config "-md,yp"
+
 </td></tr>
 </table>
 
@@ -2931,6 +2952,8 @@ for more details and variations on this process.
 [`--very-sensitive-local`]:                           #bowtie2-options-very-sensitive-local
 [`--very-sensitive`]:                                 #bowtie2-options-very-sensitive
 [`--xeq`]:                                            #bowtie2-options-xeq
+[`--sam-append-comment`]:                             #bowtie2-options-sam-append-comment
+[`--sam-opt-config`]:                                 #bowtie2-options-sam-opt-config
 [`-1`]:                                               #bowtie2-options-1
 [`-2`]:                                               #bowtie2-options-2
 [`-3`/`--trim3`]:                                     #bowtie2-options-3


=====================================
NEWS
=====================================
@@ -4,7 +4,7 @@ Bowtie 2 NEWS
 Bowtie 2 is available for download from the project website,
 http://bowtie-bio.sf.net/bowtie2 and on Github,
 https://github.com/BenLangmead/bowtie2/releases.  2.0.0-beta1 is
-the first version released to the public and 2.5.3 is the latest
+the first version released to the public and 2.5.4 is the latest
 version.  Bowtie 2 is licensed under the GPLv3 license.  See `LICENSE'
 file for details.
 
@@ -19,6 +19,20 @@ Please report any issues to the Bowtie 2 Github page or using the Sourceforge bu
 Version Release History
 =======================
 
+## Version 2.5.4 - May 16, 2024 ##
+
+### bowtie2 ###
+   * Added `--sam-opt-config` command line option for toggling SAM Opt flags.
+     See MANUAL for details.
+   * Fixed an issue causing `bowtie2`'s memory usage to increase over time
+     when aligning BAM files.
+   * Changed bowtie2 to continue flushing output in the event of a partial write.
+   * Changed the behavior of `bowtie2-build` to throw an exception if it is unable
+     to write the BWT (.1.bt2, .1.rev.bt2). In prior versions `bowtie2-build`, would silently
+     ignore the error which has led some to report the absence of the BWT files in
+     a "completed" index build.
+   * Reverted the changes made in v2.5.0 that sometimes caused unique concordant alignments to be overcounted.
+
 ## Version 2.5.3 - Jan 16, 2024 ##
 
    * Fixed an issue causing `bowtie2`'s memory usage to increase over time.


=====================================
README.md
=====================================
@@ -2,7 +2,7 @@
 <!-- badges: start -->
 ![Random Tests](https://github.com/BenLangmead/bowtie2/actions/workflows/random-tests.yml/badge.svg)
 ![Simple Tests](https://github.com/BenLangmead/bowtie2/actions/workflows/simple-tests.yml/badge.svg)
-[![Version](https://img.shields.io/badge/version-2.5.3-green.svg)](https://shields.io/)
+[![Version](https://img.shields.io/badge/version-2.5.4-green.svg)](https://shields.io/)
 <!-- [![Build Status](https://travis-ci.org/BenLangmead/bowtie2.svg?branch=master)](https://travis-ci.org/BenLangmead/bowtie2) -->
 [![License: GPL v3](https://img.shields.io/badge/license-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
 <!--badges: end -->


=====================================
aln_sink.cpp
=====================================
@@ -834,9 +834,8 @@ void AlnSinkWrap::finishRead(
 			} else {
 				met.nconcord_uni++;
 				assert(!rs1_.empty());
-				AlnScore sc1 = concordSumm.bestUnchosenP1Score();
-				AlnScore sc2 = concordSumm.bestUnchosenP2Score();
-				if(!sc1.valid() && !sc2.valid()) {
+
+				if(!concordSumm.bestUnchosenCScore().valid()) {
 					met.nconcord_uni1++;
 				} else {
 					met.nconcord_uni2++;


=====================================
bt2_idx.h
=====================================
@@ -672,14 +672,17 @@ public:
 		_in2Str = file + ".2." + gEbwt_ext + ".tmp";
 		packed_ = packed;
 		// Open output files
-		ofstream fout1(_in1Str.c_str(), ios::binary);
+                ofstream fout1(_in1Str.c_str(), ios::binary);
+          	fout1.exceptions(ofstream::failbit | ofstream::badbit | ofstream::eofbit);
 		if(!fout1.good()) {
 			cerr << "Could not open index file for writing: \"" << _in1Str.c_str() << "\"" << endl
 			     << "Please make sure the directory exists and that permissions allow writing by" << endl
 			     << "Bowtie." << endl;
 			throw 1;
-		}
-		ofstream fout2(_in2Str.c_str(), ios::binary);
+                }
+
+                ofstream fout2(_in2Str.c_str(), ios::binary);
+                fout2.exceptions(ofstream::failbit | ofstream::badbit | ofstream::eofbit);
 		if(!fout2.good()) {
 			cerr << "Could not open index file for writing: \"" << _in2Str.c_str() << "\"" << endl
 			     << "Please make sure the directory exists and that permissions allow writing by" << endl


=====================================
bt2_search.cpp
=====================================
@@ -171,6 +171,7 @@ static bool sam_print_zi;
 static bool sam_print_zp;
 static bool sam_print_zu;
 static bool sam_print_zt;
+static EList<string> sam_opt_flags;
 static bool preserve_tags;     // Only applies when aligning BAM files
 static bool align_paired_reads; // Process only the paired reads in BAM file
 static bool bwaSwLike;
@@ -670,6 +671,7 @@ static struct option long_options[] = {
 	{(char*)"sra-acc",                     required_argument,  0,                   ARG_SRA_ACC},
 #endif
 	{(char*)"sam-append-comment",          no_argument,        0,                   ARG_SAM_APPEND_COMMENT},
+        {(char*)"sam-opt-config",              required_argument,  0,                   ARG_SAM_OPT_CONFIG},
 	{(char*)0,                             0,                  0,                   0} //  terminator
 };
 
@@ -876,9 +878,11 @@ static void printUsage(ostream& out) {
 	    << "                     at the expense of generating non-standard SAM." << endl
 	    << "  --xeq              Use '='/'X', instead of 'M,' to specify matches/mismatches in SAM record." << endl
 	    << "  --soft-clipped-unmapped-tlen" << endl
-	    << "                     Exclude soft-clipped bases when reporting TLEN" << endl
+	    << "                     Exclude soft-clipped bases when reporting TLEN." << endl
 	    << "  --sam-append-comment" << endl
-	    << "                     Append FASTA/FASTQ comment to SAM record" << endl
+	    << "                     Append FASTA/FASTQ comment to SAM record." << endl
+            << "  --sam-opt-config <config>" << endl
+            << "                     Use <config>, example '-MD,YP,-AS', to toggle SAM Optional fields." << endl
 	    << endl
 	    << " Performance:" << endl
 		//    << "  -o/--offrate <int> override offrate of index; must be >= index's offrate" << endl
@@ -1555,6 +1559,16 @@ static void parseOption(int next_option, const char *arg) {
 		}
 		break;
 	}
+        case ARG_SAM_OPT_CONFIG: {
+                // string no_defaults("-as,-xs,-xn,-x0,-x1,-xm,-xo,-xg,-nm,-md,-yf,-yt,-ys");
+                // string defaults("as,xs,xn,x0,x1,xm,xo,xg,nm,md,yf,yt,ys");
+
+                // if (strncmp(arg, "-default", 8) == 0) {
+                //         no_defaults += arg;
+                // }
+                tokenize(arg, ",", sam_opt_flags);
+                break;
+        }
 	case ARG_DESC: printArgDesc(cout); throw 0;
 	case 'S': outfile = arg; break;
 	case 'U': {
@@ -4990,6 +5004,12 @@ static void driver(
 			sam_print_zp,
 			sam_print_zu,
 			sam_print_zt);
+
+                if (sam_opt_flags.size() > 0) {
+                        for (size_t i = 0; i < sam_opt_flags.size(); i++) {
+                                samc.toggleOptFlagByName(sam_opt_flags[i]);
+                        }
+                }
 		// Set up hit sink; if sanityCheck && !os.empty() is true,
 		// then instruct the sink to "retain" hits in a vector in
 		// memory so that we can easily sanity check them later on


=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+bowtie2 (2.5.4-1) unstable; urgency=medium
+
+  * Remove libmath-random-perl from Test-Depends and complete patch removing
+    tests needing this module
+    Closes: #1078087
+  * New upstream version
+  * Standards-Version: 4.7.0 (routine-update)
+
+ -- Andreas Tille <tille at debian.org>  Wed, 07 Aug 2024 13:31:40 +0200
+
 bowtie2 (2.5.3-1) unstable; urgency=medium
 
   [ Michael R. Crusoe ]
@@ -7,13 +17,6 @@ bowtie2 (2.5.3-1) unstable; urgency=medium
 
  -- Charles Plessy <plessy at debian.org>  Wed, 17 Apr 2024 08:56:57 +0900
 
-bowtie2 (2.5.2-2) UNRELEASED; urgency=medium
-
-  * Remove exclusion from architecture s390x from test since its not relevant
-    for migration any more
-
- -- Andreas Tille <tille at debian.org>  Thu, 18 Jan 2024 11:26:40 +0100
-
 bowtie2 (2.5.2-1) unstable; urgency=medium
 
   * New upstream version


=====================================
debian/control
=====================================
@@ -17,7 +17,7 @@ Build-Depends: debhelper-compat (= 13),
                libfile-which-perl <!nocheck>,
                zlib1g-dev,
                libsimde-dev
-Standards-Version: 4.6.2
+Standards-Version: 4.7.0
 Vcs-Browser: https://salsa.debian.org/med-team/bowtie2
 Vcs-Git: https://salsa.debian.org/med-team/bowtie2.git
 Homepage: https://bowtie-bio.sourceforge.net/bowtie2


=====================================
debian/patches/drop-not-needed-js-from-manual.patch deleted
=====================================
@@ -1,15 +0,0 @@
-Description: Remove link to external js lib, not needed as used for ie browsers
-Author: Alex Mestiashvili <amestia at rsh2.donotuse.de>
-Forwarded: not-needed
---- a/doc/manual.html
-+++ b/doc/manual.html
-@@ -23,9 +23,6 @@
-     .display.math{display: block; text-align: center; margin: 0.5rem auto;}
-   </style>
-   <link rel="stylesheet" href="doc/style.css" />
--  <!--[if lt IE 9]>
--    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
--  <![endif]-->
- </head>
- <body>
- <h1>Table of Contents</h1>


=====================================
debian/patches/reproducible.patch
=====================================
@@ -6,7 +6,7 @@ Author: Sascha Steinbiss <sascha at steinbiss.name>
 Forwarded: not-needed
 --- a/Makefile
 +++ b/Makefile
-@@ -26,7 +26,7 @@
+@@ -26,7 +26,7 @@ bindir := $(PREFIX)/bin
  
  LDLIBS := -lpthread -lz
  
@@ -15,7 +15,7 @@ Forwarded: not-needed
  BOWTIE_MM := 1
  BOWTIE_SHARED_MEM :=
  
-@@ -233,8 +233,8 @@
+@@ -233,8 +233,8 @@ DEBUG_FLAGS    := -O0 -g3 $(SSE_FLAG)
  RELEASE_FLAGS  := -O3 $(SSE_FLAG) -funroll-loops -g3
  NOASSERT_FLAGS := -DNDEBUG
  FILE_FLAGS     := -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
@@ -28,7 +28,7 @@ Forwarded: not-needed
    bowtie2-build-l \
 --- a/bt2_build.cpp
 +++ b/bt2_build.cpp
-@@ -580,15 +580,15 @@
+@@ -580,15 +580,15 @@ int bowtie_build(int argc, const char **
  			} else {
  				cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl;
  			}
@@ -55,7 +55,7 @@ Forwarded: not-needed
  
 --- a/bt2_inspect.cpp
 +++ b/bt2_inspect.cpp
-@@ -456,15 +456,15 @@
+@@ -456,15 +456,15 @@ int main(int argc, char **argv) {
  			} else {
  				cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl;
  			}
@@ -82,7 +82,7 @@ Forwarded: not-needed
  
 --- a/bt2_search.cpp
 +++ b/bt2_search.cpp
-@@ -5131,15 +5131,15 @@
+@@ -5151,15 +5151,15 @@ int bowtie(int argc, const char **argv)
  			} else {
  				cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl;
  			}
@@ -109,7 +109,7 @@ Forwarded: not-needed
  		{
 --- a/CMakeLists.txt
 +++ b/CMakeLists.txt
-@@ -181,7 +181,9 @@
+@@ -181,7 +181,9 @@ include_directories(${PROJECT_SOURCE_DIR
  get_directory_property(COMPILER_DEFS COMPILE_DEFINITIONS)
  string(REPLACE ";" " -D" COMPILER_DEFS "${COMPILER_DEFS}")
  string(REPLACE "\"" "" COMPILER_DEFS "${COMPILER_DEFS}")


=====================================
debian/patches/series
=====================================
@@ -1,4 +1,3 @@
-drop-not-needed-js-from-manual.patch
 wrong-interpreter-path.patch
 hardening.patch
 reproducible.patch


=====================================
debian/patches/skip_test_requiring_non-free_libmath-random-perl.patch
=====================================
@@ -16,7 +16,7 @@ Forwarded: not-needed
  use Getopt::Long;
  use List::Util qw(max min);
  
-@@ -105,7 +104,6 @@
+@@ -105,7 +104,6 @@ $rdlen_min = $rdlen_min || 40;    # min
  $frag_av   = $frag_av   || 250;   # mean fragment len
  $frag_sd   = $frag_sd   || 45;    # s.d. when drawing frag len from normal dist
  my @fraglens  = ();     # fragment lengths (for paired)
@@ -24,7 +24,7 @@ Forwarded: not-needed
  
  if($long) {
  	$nreads = 6000;
-@@ -134,77 +132,15 @@
+@@ -134,77 +132,15 @@ for(0..length($rf)-1) {
  }
  
  print STDERR "Adding microindels...\n";
@@ -102,7 +102,7 @@ Forwarded: not-needed
  sub rand_quals($) {
  	my $ret = "";
  	my $upper = (rand() < 0.2 ? 11 : 40);
-@@ -259,61 +195,10 @@
+@@ -259,61 +195,10 @@ if($paired) {
  		}
  		# Possibly reverse complement
  		$fstr = revcomp($fstr) if (int(rand(2)) == 0);
@@ -166,7 +166,7 @@ Forwarded: not-needed
  print STDERR "DONE\n";
 --- a/Makefile
 +++ b/Makefile
-@@ -547,12 +547,12 @@
+@@ -547,12 +547,12 @@ install: all
  	done
  
  .PHONY: simple-test
@@ -181,7 +181,7 @@ Forwarded: not-needed
  	eval `perl -I $(CURDIR)/.tmp/lib/perl5 -Mlocal::lib=$(CURDIR)/.tmp` ; \
  	sh ./scripts/sim/run.sh $(if $(NUM_CORES), $(NUM_CORES), 2)
  
-@@ -563,8 +563,7 @@
+@@ -563,8 +563,7 @@ perl-deps:
  	fi
  	DL=$$( ( which wget >/dev/null 2>&1 && echo "wget --no-check-certificate -O-" ) || echo "curl -L") ; \
  	$$DL http://cpanmin.us | perl - -l $(CURDIR)/.tmp App::cpanminus local::lib ; \
@@ -191,7 +191,7 @@ Forwarded: not-needed
  
  .PHONY: static-libs
  static-libs:
-@@ -636,7 +635,7 @@
+@@ -636,7 +635,7 @@ sra-deps:
  	fi ;
  
  .PHONY: test
@@ -200,3 +200,617 @@ Forwarded: not-needed
  
  .PHONY: clean
  clean:
+--- a/scripts/sim/RandDNA.pm
++++ b/scripts/sim/RandDNA.pm
+@@ -26,7 +26,6 @@ use FindBin qw($Bin);
+ use lib $Bin;
+ use DNA;
+ use Test;
+-use Math::Random;
+ 
+ ##
+ # Create a new random DNA generator
+@@ -182,10 +181,10 @@ sub test2 {
+ }
+ 
+ if($0 =~ /[^0-9a-zA-Z_]?RandDNA\.pm$/) {
+-	print "Running unit tests\n";
++	print "Skipping unit tests requiring Math::Random which is non-free\n";
+ 	# Run unit tests
+-	Test::shouldSucceed("test1", \&test1);
+-	Test::shouldSucceed("test2", \&test2);
++#	Test::shouldSucceed("test1", \&test1);
++#	Test::shouldSucceed("test2", \&test2);
+ }
+ 
+ 1;
+--- a/scripts/sim/SampleRead.pm
++++ b/scripts/sim/SampleRead.pm
+@@ -27,7 +27,7 @@ use lib $Bin;
+ use DNA;
+ use Test;
+ use List::Util qw(max min);
+-use Math::Random;
++#use Math::Random;
+ 
+ ##
+ # Default sequencing miscall rate generator.
+@@ -235,10 +235,10 @@ sub test2 {
+ }
+ 
+ if($0 =~ /[^0-9a-zA-Z_]?SampleRead\.pm$/) {
+-	print "Running unit tests\n";
++	print "Skipping unit tests requiring Math::Random which is non-free\n";
+ 	# Run unit tests
+-	Test::shouldSucceed("test1", \&test1);
+-	Test::shouldSucceed("test2", \&test2);
++#	Test::shouldSucceed("test1", \&test1);
++#	Test::shouldSucceed("test2", \&test2);
+ }
+ 
+ 1;
+--- a/scripts/sim/Sim.pm
++++ b/scripts/sim/Sim.pm
+@@ -28,9 +28,9 @@ use DNA;
+ use Test;
+ use RandDNA;
+ use SampleRead;
+-use Mutate;
++#use Mutate;
+ use AlignmentCheck;
+-use Math::Random;
++#use Math::Random;
+ use List::Util qw(max min);
+ use POSIX;
+ use Sys::Info;
+@@ -60,120 +60,6 @@ sub randStr($) {
+ }
+ 
+ ##
+-# Default random generator for number of reference per test case.
+-#
+-sub defaultRefNumGen() { return int(Math::Random::random_exponential(1, 8))+1; }
+-
+-##
+-# Default random generator for reference length.
+-#
+-sub defaultRefLenGen() {
+-	return int(Math::Random::random_exponential(1, 50000))+1;
+-}
+-
+-##
+-# Default random generator for number of reference per test case.
+-#
+-sub defaultReadNumGen() {
+-	return int(Math::Random::random_exponential(1, 10000))+1;
+-}
+-
+-##
+-# Default random generator for read length.
+-#
+-sub defaultFragLenGen() {
+-	return int(Math::Random::random_normal(1, 200, 40))+1;
+-}
+-
+-##
+-# Default random generator for reference length.
+-#
+-sub defaultReadLenGen() {
+-	my $r = int(rand(3));
+-	if($r == 0) {
+-		return int(Math::Random::random_exponential(1, 60))+1;
+-	} elsif($r == 1) {
+-		return int(Math::Random::random_exponential(1, 20))+1;
+-	} else {
+-		return int(Math::Random::random_exponential(1, 150))+1;
+-	}
+-}
+-
+-##
+-# Default random generator for fraction of reference characters = N.
+-#
+-sub defaultNGen() {
+-	return Math::Random::random_uniform(1, 0, 0.05);
+-}
+-
+-##
+-# Default random generator for fraction of reference characters = an
+-# ambiguous IUPAC code.
+-#
+-sub defaultIupacGen() {
+-	return Math::Random::random_uniform(1, 0, 0.01);
+-}
+-
+-##
+-# Default random generator for AT/ACGT fraction.
+-#
+-sub defaultAtGen() {
+-	return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1);
+-}
+-
+-##
+-# Default random generator for A/AT fraction.
+-#
+-sub defaultAGen() {
+-	return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1);
+-}
+-
+-##
+-# Default random generator for C/CG fraction.
+-#
+-sub defaultCGen() {
+-	return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1);
+-}
+-
+-##
+-# Default SNP rate generator.  Doesn't generate the SNP per se, just
+-# the rate.
+-#
+-sub defaultSNPGen() {
+-	return Math::Random::random_uniform(1, 0, 0.05);
+-}
+-
+-##
+-# Default read gap rate generator.  Doesn't generate the gaps or
+-# lengths, just the rate.
+-#
+-sub defaultRdGapGen() {
+-	return Math::Random::random_uniform(1, 0, 0.005);
+-}
+-
+-##
+-# Default reference gap rate generator.  Doesn't generate the gaps or
+-# lengths, just the rate.
+-#
+-sub defaultRfGapGen() {
+-	return Math::Random::random_uniform(1, 0, 0.005);
+-}
+-
+-##
+-# Default rearrangement rate generator.
+-#
+-sub defaultRearrGen() {
+-	return Math::Random::random_uniform(1, 0, 0.005);
+-}
+-
+-##
+-# Default function for generating gap lengths when introducing a gap.
+-#
+-sub defaultGapLenGen($) {
+-	return int(Math::Random::random_exponential(1, 3))+1;
+-}
+-
+-##
+ # Default function for generating random sequence to insert into a gap.
+ #
+ sub defaultSeqGen($) {
+@@ -187,77 +73,6 @@ sub defaultSeqGen($) {
+ 	return $ret;
+ }
+ 
+-##
+-# Default sequencing miscall rate generator.
+-#
+-sub defaultSeqMmGen() {
+-	return Math::Random::random_uniform(1, 0, 0.1);
+-}
+-
+-##
+-# Create a new test case simulator
+-#
+-sub new {
+-	my (
+-		$class,
+-		$name,       # name of simulator
+-		$rfnumgen,   # number of reference sequences
+-		$rflengen,   # reference length
+-		$rdnumgen,   # number of read sequences per run
+-		$rdlengen,   # read length generator
+-		$fraglengen, # fragment length generator
+-		$ngen,       # N fraction
+-		$iupacgen,   # Non-A/C/G/T/N IUPAC fraction (after N fraction removed)
+-		$atgen,      # AT fraction (after N/IUPAC fractions removed)
+-		$agen,       # A fraction (of AT)
+-		$cgen,       # C fraction (of CG)
+-		$snpgen,     # SNP rate gen
+-		$rdgapgen,   # read gap generator
+-		$rfgapgen,   # ref gap generator
+-		$rearrgen,   # rearrangement generator
+-		$gaplengen,  # gap length generator
+-		$seqgen,     # gap filler sequence generator
+-		$seqmm,      # sequencing error generator
+-	) = @_;
+-	$rfnumgen   = \&defaultRefNumGen  unless defined($rfnumgen);
+-	$rflengen   = \&defaultRefLenGen  unless defined($rflengen);
+-	$rdnumgen   = \&defaultReadNumGen unless defined($rdnumgen);
+-	$rdlengen   = \&defaultReadLenGen unless defined($rdlengen);
+-	$fraglengen = \&defaultFragLenGen unless defined($fraglengen);
+-	$ngen       = \&defaultNGen       unless defined($ngen);
+-	$iupacgen   = \&defaultIupacGen   unless defined($iupacgen);
+-	$atgen      = \&defaultAtGen      unless defined($atgen);
+-	$agen       = \&defaultAGen       unless defined($agen);
+-	$cgen       = \&defaultCGen       unless defined($cgen);
+-	$snpgen     = \&defaultSNPGen     unless defined($snpgen);
+-	$rdgapgen   = \&defaultRdGapGen   unless defined($rdgapgen);
+-	$rfgapgen   = \&defaultRfGapGen   unless defined($rfgapgen);
+-	$rearrgen   = \&defaultRearrGen   unless defined($rearrgen);
+-	$gaplengen  = \&defaultGapLenGen  unless defined($gaplengen);
+-	$seqgen     = \&defaultSeqGen     unless defined($seqgen);
+-	$seqmm      = \&defaultSeqMmGen   unless defined($seqmm);
+-	$name = "noname" unless defined($name);
+-	return bless {
+-		_name       => $name,
+-		_rfnumgen   => $rfnumgen,
+-		_rflengen   => $rflengen,
+-		_rdnumgen   => $rdnumgen,
+-		_rdlengen   => $rdlengen,
+-		_fraglengen => $fraglengen,
+-		_ngen       => $ngen,
+-		_iupacgen   => $iupacgen,
+-		_atgen      => $atgen,
+-		_agen       => $agen,
+-		_cgen       => $cgen,
+-		_snpgen     => $snpgen,
+-		_rdgapgen   => $rdgapgen,
+-		_rfgapgen   => $rfgapgen,
+-		_rearrgen   => $rearrgen,
+-		_gaplengen  => $gaplengen,
+-		_seqgen     => $seqgen,
+-		_seqmm      => $seqmm,
+-	}, $class;
+-}
+ sub rfnumgen   { return $_[0]->{_rfnumgen}   }
+ sub rflengen   { return $_[0]->{_rflengen}   }
+ sub rdnumgen   { return $_[0]->{_rdnumgen}   }
+@@ -302,112 +117,6 @@ sub genDNAgen {
+ 	return $refdnagen;
+ }
+ 
+-##
+-# Generate and print reference sequences to file of given name.  Also,
+-# install reference sequences into hash ref $ref.  To allow for
+-# "overhang" (alignment that hang off the end of the reference), we
+-# actually write out a little bit less than the full reference sequence
+-# for each sequence.
+-#
+-sub genRef {
+-	my ($self, $ref, $refdnagen, $conf, $tmpfn) = @_;
+-	# Get a generator for reference length
+-	my $reflen = $self->rflengen;
+-	# Generate the number of references
+-	my $refnum = $self->rfnumgen->();
+-	$refnum = sqrt($refnum) if $conf->{small};
+-	$refnum = 1 if $refnum <= 0;
+-	$refnum = sqrt($refnum) if $conf->{small};
+-	$refnum = 1 if $refnum <= 0;
+-	$refnum = ceil($refnum);
+-	$refnum = $conf->{numrefs} if defined($conf->{numrefs});
+-	# Open output file
+-	open (FA, ">$tmpfn") ||
+-		mydie("Could not open temporary fasta file '$tmpfn' for writing");
+-	my %ccnt = ();
+-	print STDERR "Generating $refnum references\n";
+-	for (1..$refnum) {
+-		# Randomly generate length
+-		my $len = $reflen->();
+-		$len = sqrt($len) if $conf->{small};
+-		$len = 1 if $len <= 0;
+-		$len = ceil($len);
+-		my $seq = $refdnagen->nextSeq($len);
+-		length($seq) >= $len || die;
+-		my $name = "Sim.pm.$_";
+-		$ref->{$name} = $seq;
+-		# Select amount to trim from LHS
+-		my $trimleft = int(Math::Random::random_exponential(1, 200));
+-		# Select amount to trim from RHS
+-		my $trimright = int(Math::Random::random_exponential(1, 200));
+-		# Make sure we're leaving some sequence after trimming
+-		while($trimleft + $trimright > $len) {
+-			if(int(rand(2))) {
+-				$trimleft = int($trimleft*0.5);
+-			} else {
+-				$trimright = int($trimright*0.5);
+-			}
+-		}
+-		# Trim the sequence
+-		substr($seq, 0, $trimleft) = "";
+-		$seq = substr($seq, 0, length($seq)-$trimright);
+-		my $trimlen = length($seq);
+-		$trimlen == $len - $trimleft - $trimright ||
+-			mydie("Unexpected trim combo: $len, $trimleft, $trimright, $trimlen");
+-		print STDERR "  Generated reference '$name' of untrimmed length $len, trimmed length $trimlen\n";
+-		print FA ">$name\n";
+-		my $buf = "";
+-		length($seq) >= $trimlen || die;
+-		for my $i (1..$trimlen) {
+-			my $c = substr($seq, $i-1, 1);
+-			defined($c) || die;
+-			$ccnt{$c}++;
+-			$buf .= $c;
+-			$ref->{$name} .= $c;
+-			if($i % 60 == 0) {
+-				print FA "$buf\n";
+-				$buf = "";
+-			}
+-		}
+-		print FA "$buf\n" if $buf ne "";
+-	}
+-	close(FA);
+-	print STDERR "Wrote references to $tmpfn\n";
+-	for my $k (sort keys %ccnt) {
+-		print STDERR "  $k: $ccnt{$k}\n";
+-	}
+-}
+-
+-##
+-# Generate a hash of key/value arguments to pass to bowtie2.
+-#
+-sub genBuildArgs {
+-	my ($self, $large_index) = @_;
+-	my %args = ();
+-	my $r1 = int(rand(3));
+-	if($r1 == 0) {
+-		$args{"--bmaxdivn"} = int(Math::Random::random_exponential(1, 4))+1;
+-	} elsif($r1 == 1) {
+-		$args{"--bmax"} = int(Math::Random::random_exponential(1, 10000))+100;
+-	}
+-	my $r2 = int(rand(2));
+-	if($r2 == 0) {
+-		$args{"--dcv"} = 2 ** (int(rand(10))+4);
+-	}
+-	my $r3 = int(rand(5));
+-	if($r3 == 0) {
+-		$args{"--packed"} = "";
+-	}
+-	my $r4 = int(rand(3));
+-	if($r4 == 0) {
+-		$args{"--offrate"} = int(rand(8))+1;
+-	}
+-	my $info = Sys::Info->new;
+-	my $cpu = $info->device('CPU');
+-	$args{"--threads"} = int(rand($cpu->count || 1)) + 1;
+-	$args{"--large-index"} = "" if $large_index;
+-	return \%args;
+-}
+ 
+ ##
+ # Given a fasta filename, an index basename, and a path to the
+@@ -659,193 +368,6 @@ sub mutateSeq {
+ }
+ 
+ ##
+-# Generate a setting for MA (match bonus).
+-#
+-sub genPolicyMA($) {
+-	my $local = shift;
+-	return undef if $local;
+-	return Math::Random::random_uniform(1, 1, 40)
+-}
+-
+-##
+-# Generate a setting for MMP (mismatch penalty).
+-#
+-sub genPolicyMMP() {
+-	#my $op = substr("CQR", int(rand(3)), 1);
+-	#if($op eq "C") {
+-		my $op1 = Math::Random::random_uniform(1, 1, 10);
+-		my $op2 = Math::Random::random_uniform(1, 1, 10);
+-	#}
+-	return max($op1, $op2).",".min($op1, $op2);
+-}
+-
+-##
+-# Generate a setting for NP (penalty for a mismatch involving an N).
+-#
+-sub genPolicyNP() {
+-	#my $op = substr("CQR", int(rand(3)), 1);
+-	#if($op eq "C") {
+-		my $op = int(Math::Random::random_exponential(1, 3))+1;
+-	#}
+-	return $op;
+-}
+-
+-##
+-# Generate a setting for RDG (read gap open and extend penalties).
+-#
+-sub genPolicyRDG() {
+-	my $op = Math::Random::random_uniform(1, 1, 50);
+-	if(int(rand(2)) == 0) {
+-		$op .= ",";
+-		$op .= Math::Random::random_uniform(1, 1, 20);
+-	}
+-	return "$op";
+-}
+-
+-##
+-# Generate a setting for RFG (ref gap open and extend penalties).
+-#
+-sub genPolicyRFG() {
+-	my $op = Math::Random::random_uniform(1, 1, 50);
+-	if(int(rand(2)) == 0) {
+-		$op .= ",";
+-		$op .= Math::Random::random_uniform(1, 1, 20);
+-	}
+-	return "$op";
+-}
+-
+-##
+-# Generate a setting for MIN (function determining minimum acceptable score).
+-#
+-sub genPolicyMIN($) {
+-	my $local = shift;
+-	my $xx = Math::Random::random_uniform(1, 1, 10);
+-	my $yy = Math::Random::random_uniform(1, 1, 10);
+-	return "L,$xx,$yy";
+-}
+-
+-##
+-# Generate a setting for NCEIL (function determining maximum number of Ns
+-# allowed).
+-#
+-sub genPolicyNCEIL() {
+-	return undef if int(rand(2)) == 0;
+-	my $xx = Math::Random::random_uniform(1, 0, 1.5);
+-	my $yy = Math::Random::random_uniform(1, 0, 1.5);
+-	return "$xx,$yy";
+-}
+-
+-##
+-# Generate a setting for SEED (# mismatches, length, interval).
+-#
+-sub genPolicySEED() {
+-	return undef if int(rand(2)) == 0;
+-	# Pick a number of mismatches
+-	my $sd = substr("012", int(rand(2)), 1);
+-	if(rand() < 0.9) {
+-		# Length
+-		$sd .= " -L".int(Math::Random::random_uniform(1, 12, 32));
+-	}
+-	return $sd;
+-}
+-
+-##
+-# Generate a setting for -D (# DP fails in a row).
+-#
+-sub genPolicyFailStreak() {
+-	return undef if int(rand(2)) == 0;
+-	return int(Math::Random::random_uniform(1, 2, 50));
+-}
+-
+-##
+-# Generate a setting for -R (# seeding rounds).
+-#
+-sub genPolicySeedRounds() {
+-	return undef if int(rand(2)) == 0;
+-	return int(Math::Random::random_uniform(1, 1, 5));
+-}
+-
+-##
+-# Generate a setting for IVAL.  Interval between seeds is a function of the
+-# read length OR sqaure root of read length OR cube root of read length.
+-#
+-sub genPolicyIVAL() {
+-	return undef if int(rand(2)) == 0;
+-	# Pick a number of mismatches
+-	my $iv = substr("LSC", int(rand(3)), 1);
+-	if($iv eq "L") {
+-		if(rand() < 0.9) {
+-			# Multiplier
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 0.5);
+-		}
+-		if(rand() < 0.3) {
+-			# Offset
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 4.0);
+-		}
+-	} elsif($iv eq "S") {
+-		if(rand() < 0.9) {
+-			# Multiplier
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 3.0);
+-		}
+-		if(rand() < 0.3) {
+-			# Offset
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 7.0);
+-		}
+-	} elsif($iv eq "C") {
+-		if(rand() < 0.9) {
+-			# Multiplier
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 5.0);
+-		}
+-		if(rand() < 0.3) {
+-			# Offset
+-			$iv .= ",".Math::Random::random_uniform(1, 0.0, 14.0);
+-		}
+-	}
+-	return $iv;
+-}
+-
+-##
+-# Generate a hash of key/value arguments to pass to bowtie2.
+-#
+-sub genAlignArgs {
+-	my ($self, $input, $color, $large_index, $conf) = @_;
+-	my %args = ();
+-	my $local = int(rand(2)) == 0;
+-	$args{"-u"}         = $conf->{maxreads} if defined($conf->{maxreads});
+-	$args{"--mm"}       = "" if int(rand(2)) == 0;
+-	$args{"--trim3"}    = int(rand(10)) if int(rand(2)) == 0;
+-	$args{"--trim5"}    = int(rand(10)) if int(rand(2)) == 0;
+-	$args{"--nofw"}     = "" if int(rand(4)) == 0;
+-	$args{"--norc"}     = "" if int(rand(4)) == 0;
+-	$args{"--col-keepends"} = "" if ($color && int(rand(3)) == 0);
+-	$args{"--gbar"}     = int(Math::Random::random_exponential(1, 3))+1 if int(rand(4)) == 0;
+-	$args{"--local"}    = "" if $local;
+-	my $rep = int(rand(5));
+-	if($rep == 0) {
+-		$args{"-a"} = "";
+-	} elsif($rep == 1) {
+-		$args{"-k"} = int(Math::Random::random_exponential(1, 3))+2;
+-	} elsif($rep == 2) {
+-		$args{"-M"} = int(Math::Random::random_exponential(1, 3))+2;
+-	}
+-	$args{"--rdg"} = genPolicyRDG() if rand() < 0.5;
+-	$args{"--rfg"} = genPolicyRFG() if rand() < 0.5;
+-	$args{"--score-min"} = genPolicyMIN($local);
+-	$args{"--n-ceil"} = genPolicyNCEIL() if rand() < 0.5;
+-	$args{"-N"} = genPolicySEED() if rand() < 0.5;
+-	$args{"-D"} = genPolicyFailStreak() if rand() < 0.5;
+-	$args{"-R"} = genPolicySeedRounds() if rand() < 0.5;
+-	$args{"--ma"} = genPolicyMA($local) if rand() < 0.5;
+-	$args{"--mp"} = genPolicyMMP() if rand() < 0.5;
+-	$args{"--np"} = genPolicyNP() if rand() < 0.5;
+-	$args{"-i"} = genPolicyIVAL() if rand() < 0.5;
+-	$args{"--large-index"} = "" if $large_index;
+-	$args{"--cp-min"} = int(Math::Random::random_exponential(1, 3)) + 2;
+-	$args{"--cp-ival"} = int(Math::Random::random_exponential(1, 1)) + 1;
+-	return \%args;
+-}
+-
+-##
+ # Align the given input set against the given index using the given
+ # bowtie2 binary and arguments.  Sanity-check the SAM output.
+ #
+--- a/scripts/sim/Mutate.pm
++++ b/scripts/sim/Mutate.pm
+@@ -27,7 +27,7 @@ use lib $Bin;
+ use DNA;
+ use Test;
+ use List::Util qw(max min);
+-use Math::Random;
++#use Math::Random;
+ 
+ ##
+ # Default SNP rate generator.  Doesn't generate the SNP per se, just
+@@ -292,10 +292,10 @@ sub test2 {
+ }
+ 
+ if($0 =~ /[^0-9a-zA-Z_]?Mutate\.pm$/) {
+-	print "Running unit tests\n";
++	print "Skipping unit tests requiring Math::Random which is non-free\n";
+ 	# Run unit tests
+-	Test::shouldSucceed("test1", \&test1);
+-	Test::shouldSucceed("test2", \&test2);
++#	Test::shouldSucceed("test1", \&test1);
++#	Test::shouldSucceed("test2", \&test2);
+ }
+ 
+ 1;
+--- a/scripts/sim/run.pl
++++ b/scripts/sim/run.pl
+@@ -90,7 +90,7 @@ if($help) {
+ 	exit 0;
+ }
+ 
+-my $sim = Sim->new();
++# my $sim = Sim->new();
+ my $pm = new Parallel::ForkManager($cpus); 
+ 
+ # Callback for when a child finishes so we can get its exit code
+@@ -112,7 +112,7 @@ for(1..$totcases) {
+ 	if($childPid != 0) {
+ 		next; # spawn the next child
+ 	}
+-	$sim->nextCase(\%conf);
++	#$sim->nextCase(\%conf);
+ 	$pm->finish;
+ }
+ $pm->wait_all_children;


=====================================
debian/tests/control
=====================================
@@ -1,3 +1,3 @@
 Tests: run-unit-test
-Depends: @, libclone-perl, libtest-deep-perl, libclone-perl, libfile-which-perl, libmath-random-perl, libsys-info-perl
+Depends: @, libclone-perl, libtest-deep-perl, libclone-perl, libfile-which-perl, libsys-info-perl
 Restrictions: allow-stderr


=====================================
doc/manual.html
=====================================
@@ -23,9 +23,6 @@
     .display.math{display: block; text-align: center; margin: 0.5rem auto;}
   </style>
   <link rel="stylesheet" href="doc/style.css" />
-  <!--[if lt IE 9]>
-    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
-  <![endif]-->
 </head>
 <body>
 <h1>Table of Contents</h1>
@@ -372,24 +369,37 @@ index type for uncompressed and gzipped inputs.</p>
 <p>To build <code>bowtie2-build</code> with <a
 href="https://github.com/IlyaGrebnov/libsais">libsais</a> first make
 sure that the libsais submodule is available. This can be done in one of
-the following ways: * first time cloning bowtie2 --
-<code>git clone --recursive https://github.com/BenLangmead/bowtie2.git</code>
-* existing checkout of bowtie2 --
-<code>git submodule init && git submodule update</code></p>
-<p>Issue the following command line to build libsais: * with OpenMP
-support -- <code>[g]make libsais USE_SAIS_OPENMP=1</code> * without
-OpenMP support -- <code>[g]make libsais USE_SAIS=1</code></p>
+the following ways:</p>
+<ul>
+<li>first time cloning bowtie2 --
+<code>git clone --recursive https://github.com/BenLangmead/bowtie2.git</code></li>
+<li>existing checkout of bowtie2 --
+<code>git submodule init && git submodule update</code></li>
+</ul>
+<p>Issue the following command line to build libsais:</p>
+<ul>
+<li>with OpenMP support --
+<code>[g]make libsais USE_SAIS_OPENMP=1</code></li>
+<li>without OpenMP support --
+<code>[g]make libsais USE_SAIS=1</code></li>
+</ul>
 <p>The choice of using OpenMP will determine whether or not the
 algorithm runs multithreaded. The [<code>-p/--threads</code>] argument
 to <code>bowtie2-build</code> will be ignored when libsais is compiled
 without OpenMP support.</p>
-<p>Finally, building the build executable: * with OpenMP support --
-<code>[g]make bowtie2-build-s USE_SAIS_OPENMP=1</code> * without OpenMP
-support -- <code>[g]make bowtie2-build-s USE_SAIS=1</code></p>
+<p>Finally, building the bowtie2-build executable:</p>
+<ul>
+<li>with OpenMP support --
+<code>[g]make bowtie2-build-s USE_SAIS_OPENMP=1</code></li>
+<li>without OpenMP support --
+<code>[g]make bowtie2-build-s USE_SAIS=1</code></li>
+</ul>
 <h3 id="building-with-cmake">Building with CMake</h3>
 <p>To build Bowtie2 with SRA and libsais support issue the following
-command: *
-<code>cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .</code></p>
+command:</p>
+<ul>
+<li><code>cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .</code></li>
+</ul>
 <p>CMake will take care of building and linking against the specified
 dependencies.</p>
 <h2 id="adding-to-path">Adding to PATH</h2>
@@ -1027,7 +1037,7 @@ the function <code>f(x)</code> sets the minimum alignment score
 necessary for an alignment to be considered valid, and <code>x</code> is
 the read length.</p>
 <h3 id="usage">Usage</h3>
-<pre><code>bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | b <bam>} -S [<sam>]</code></pre>
+<pre><code>bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | -b <bam>} -S [<sam>]</code></pre>
 <h3 id="main-arguments">Main arguments</h3>
 <table>
 <tr>
@@ -2183,6 +2193,22 @@ matches/mismatches in SAM record</p>
 everything after the first space in the read name.</p>
 </td>
 </tr>
+<tr>
+<td id="bowtie2-options-sam-opt-config">
+<pre><code>--sam-opt-config <config></code></pre>
+</td>
+<td>
+<p>Use <code><config></code> to toggle SAM Optional Fields where
+<code><config></code> is a string of comma delimited,
+case-insensitive, two-letter tags. Tags prefixed with a "-" will be
+turned off and hence will not be included in the SAM output. The example
+below turns off the "MD" tag and enables the
+<code>bowtie2</code>-specific "YP" tag. The config is additive, so, any
+default OPT flags that need to be turned off will have to explicitly
+specified.</p>
+<pre><code>`bowtie2 ... --sam-opt-config "-md,yp"</code></pre>
+</td>
+</tr>
 </table>
 <h4 id="performance-options">Performance options</h4>
 <table>


=====================================
doc/website/manual.ssi
=====================================
@@ -338,24 +338,37 @@ index type for uncompressed and gzipped inputs.</p>
 <p>To build <code>bowtie2-build</code> with <a
 href="https://github.com/IlyaGrebnov/libsais">libsais</a> first make
 sure that the libsais submodule is available. This can be done in one of
-the following ways: * first time cloning bowtie2 --
-<code>git clone --recursive https://github.com/BenLangmead/bowtie2.git</code>
-* existing checkout of bowtie2 --
-<code>git submodule init && git submodule update</code></p>
-<p>Issue the following command line to build libsais: * with OpenMP
-support -- <code>[g]make libsais USE_SAIS_OPENMP=1</code> * without
-OpenMP support -- <code>[g]make libsais USE_SAIS=1</code></p>
+the following ways:</p>
+<ul>
+<li>first time cloning bowtie2 --
+<code>git clone --recursive https://github.com/BenLangmead/bowtie2.git</code></li>
+<li>existing checkout of bowtie2 --
+<code>git submodule init && git submodule update</code></li>
+</ul>
+<p>Issue the following command line to build libsais:</p>
+<ul>
+<li>with OpenMP support --
+<code>[g]make libsais USE_SAIS_OPENMP=1</code></li>
+<li>without OpenMP support --
+<code>[g]make libsais USE_SAIS=1</code></li>
+</ul>
 <p>The choice of using OpenMP will determine whether or not the
 algorithm runs multithreaded. The [<code>-p/--threads</code>] argument
 to <code>bowtie2-build</code> will be ignored when libsais is compiled
 without OpenMP support.</p>
-<p>Finally, building the build executable: * with OpenMP support --
-<code>[g]make bowtie2-build-s USE_SAIS_OPENMP=1</code> * without OpenMP
-support -- <code>[g]make bowtie2-build-s USE_SAIS=1</code></p>
+<p>Finally, building the bowtie2-build executable:</p>
+<ul>
+<li>with OpenMP support --
+<code>[g]make bowtie2-build-s USE_SAIS_OPENMP=1</code></li>
+<li>without OpenMP support --
+<code>[g]make bowtie2-build-s USE_SAIS=1</code></li>
+</ul>
 <h3 id="building-with-cmake">Building with CMake</h3>
 <p>To build Bowtie2 with SRA and libsais support issue the following
-command: *
-<code>cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .</code></p>
+command:</p>
+<ul>
+<li><code>cmake . -D USE_SRA=1 -D USE_SAIS=1 && cmake --build .</code></li>
+</ul>
 <p>CMake will take care of building and linking against the specified
 dependencies.</p>
 <h2 id="adding-to-path">Adding to PATH</h2>
@@ -993,7 +1006,7 @@ the function <code>f(x)</code> sets the minimum alignment score
 necessary for an alignment to be considered valid, and <code>x</code> is
 the read length.</p>
 <h3 id="usage">Usage</h3>
-<pre><code>bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | b <bam>} -S [<sam>]</code></pre>
+<pre><code>bowtie2 [options]* -x <bt2-idx> {-1 <m1> -2 <m2> | -U <r> | --interleaved <i> | --sra-acc <acc> | -b <bam>} -S [<sam>]</code></pre>
 <h3 id="main-arguments">Main arguments</h3>
 <table>
 <tr>
@@ -2149,6 +2162,22 @@ matches/mismatches in SAM record</p>
 everything after the first space in the read name.</p>
 </td>
 </tr>
+<tr>
+<td id="bowtie2-options-sam-opt-config">
+<pre><code>--sam-opt-config <config></code></pre>
+</td>
+<td>
+<p>Use <code><config></code> to toggle SAM Optional Fields where
+<code><config></code> is a string of comma delimited,
+case-insensitive, two-letter tags. Tags prefixed with a "-" will be
+turned off and hence will not be included in the SAM output. The example
+below turns off the "MD" tag and enables the
+<code>bowtie2</code>-specific "YP" tag. The config is additive, so, any
+default OPT flags that need to be turned off will have to explicitly
+specified.</p>
+<pre><code>`bowtie2 ... --sam-opt-config "-md,yp"</code></pre>
+</td>
+</tr>
 </table>
 <h4 id="performance-options">Performance options</h4>
 <table>


=====================================
doc/website/recent_news.ssi
=====================================
@@ -1,3 +1,28 @@
+<h2 id="version-2.5.4---may-16-2024">Version 2.5.4 - May 16, 2024</h2>
+<h3 id="bowtie2">bowtie2</h3>
+<ul>
+  <li>Added <code><a href="manual.shtml#bowtie2-sam-opt-config">--sam-opt-config</a></code> command line option for toggling
+    SAM Opt flags. See MANUAL for details.</li>
+  <li>Fixed an issue causing <code>bowtie2</code>’s memory usage to
+    increase over time when aligning BAM files.</li>
+  <li>Changed bowtie2 to continue flushing output in the event of a
+    partial write.</li>
+  <li>Changed the behavior of <code>bowtie2-build</code> to throw an
+    exception if it is unable to write the BWT (.1.bt2, .1.rev.bt2). In
+    prior versions <code>bowtie2-build</code>, would silently ignore the
+    error which has led some to report the absence of the BWT files in a
+    “completed” index build.</li>
+  <li>Reverted the changes made in v2.5.0 that sometimes caused unique
+    concordant alignments to be overcounted.</li>
+</ul>
+
+<h2>New Indexes for Cow, Chimp, and Rat, added to the sidebar - May 08, 2024</h2>
+<ul>
+   <li><a href="https://genome-idx.s3.amazonaws.com/bt/ARS-UCD2.0.zip"><i>B. taurus</i>, ARS-UCD2.0</a></li>
+   <li><a href="https://genome-idx.s3.amazonaws.com/bt/NHGRI_mPanTro3-v2.0.zip"><i>P. troglodytes</i>, mPanTro3-v2</a></li>
+   <li><a href="https://genome-idx.s3.amazonaws.com/bt/GRCr8.zip"><i>R. norvegicus</i>, GRCr8</a></li>
+</ul>
+
 <h2>Version 2.5.3 - Jan 16, 2024</h2>
 <h3 id="bowtie2">bowtie2</h3>
 <ul>


=====================================
doc/website/rhsidebar.ssi
=====================================
@@ -18,10 +18,10 @@
         </tr>
       <tr>
       <td>
-        <a href="https://sourceforge.net/projects/bowtie-bio/files/bowtie2/2.5.3">Bowtie2 v2.5.3</a>
+        <a href="https://sourceforge.net/projects/bowtie-bio/files/bowtie2/2.5.4">Bowtie2 v2.5.4</a>
       </td>
       <td align="right">
-        01/16/24 
+        05/16/24 
       </td>
       </tr>
       <tr>
@@ -49,7 +49,7 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCh38_noalt_as.zip"><i>H. sapiens</i>, GRCh38 no-alt analysis set</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -58,7 +58,7 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCh38_noalt_decoy_as.zip"><i>H. sapiens</i>, GRCh38 no-alt +decoy set</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -67,7 +67,7 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/grch38_1kgmaj.zip"><i>H. sapiens</i>, GRCh38 + major SNVs</a>
         </td>
         <td align="right">
-            NCBI+1KG
+            GRC
         </td>
       </tr>
       <tr>
@@ -80,43 +80,43 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCh37.zip"><i>H. sapiens</i>, GRCh37</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/Ash1v1.7.zip"><i>H. sapiens</i>, Ash1v1.7</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/chm13v2.0.zip"><i>H. sapiens</i>, CHM13 v2</a>
         </td>
         <td align="right">
-            JHU
+            <a href="https://github.com/nanopore-wgs-consortium/CHM13">T2T</a>
         </td>
       </tr>
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/Ash1_v2.0.zip"><i>H. sapiens</i>, Ash1v2.0</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/chm13.draft_v1.0_plusY.zip"><i>H. sapiens</i>, CHM13 v1, plus Y</a>
         </td>
         <td align="right">
-            JHU
+            <a href="https://github.com/nanopore-wgs-consortium/CHM13">T2T</a>
         </td>
       </tr>
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/chm13v2.0.zip"><i>H. sapiens</i>, CHM13 v2</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/Ash1_v2.0.zip"><i>H. sapiens</i>, Ash1v2.0</a>
         </td>
         <td align="right">
-            <a href="https://github.com/nanopore-wgs-consortium/CHM13">T2T</a>
+            JHU
         </td>
       </tr>
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/chm13.draft_v1.0_plusY.zip"><i>H. sapiens</i>, CHM13 v1, plus Y</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/Ash1v1.7.zip"><i>H. sapiens</i>, Ash1v1.7</a>
         </td>
         <td align="right">
-            <a href="https://github.com/nanopore-wgs-consortium/CHM13">T2T</a>
+            JHU
         </td>
       </tr>
 
@@ -140,19 +140,19 @@
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/GRCm38.zip"><i>M. Musculus</i>, GRCm38</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/GRCm39.zip"><i>M. Musculus</i>, GRCm39</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/GRCm39.zip"><i>M. Musculus</i>, GRCm39</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/GRCm38.zip"><i>M. Musculus</i>, GRCm38</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -174,6 +174,15 @@
         </td>
       </tr>
 
+      <tr>
+        <td>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/NHGRI_mPanTro3-v2.0.zip"><i>P. troglodytes</i>, mPanTro3-v2</a>
+        </td>
+        <td align="right">
+            NHGRI
+        </td>
+      </tr>
+
       <tr>
         <td>
             <a href="https://genome-idx.s3.amazonaws.com/bt/Clint_PTRv2.zip"><i>P. troglodytes</i>, Clint_PTRv2</a>
@@ -203,7 +212,7 @@
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/ARS-UCD1.2.zip"><i>B. taurus</i>, ARS-UCD1.2</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/ARS-UCD2.0.zip"><i>B. taurus</i>, ARS-UCD2.0</a>
         </td>
         <td align="right">
             NCBI
@@ -212,7 +221,7 @@
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/Sscrofa11.1.zip"><i>S. scrofa</i>, Sscrofa11.1</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/ARS-UCD1.2.zip"><i>B. taurus</i>, ARS-UCD1.2</a>
         </td>
         <td align="right">
             NCBI
@@ -221,10 +230,10 @@
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/CanFam3.1.zip"><i>C. familiaris</i>, CanFam3.1</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/Sscrofa11.1.zip"><i>S. scrofa</i>, Sscrofa11.1</a>
         </td>
         <td align="right">
-            Ensembl
+            NCBI
         </td>
       </tr>
 
@@ -239,10 +248,19 @@
 
       <tr>
         <td>
-            <a href="https://genome-idx.s3.amazonaws.com/bt/rn4.zip"><i>R. norvegicus</i>, rn4</a>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/CanFam3.1.zip"><i>C. familiaris</i>, CanFam3.1</a>
         </td>
         <td align="right">
-            UCSC
+            Ensembl
+        </td>
+      </tr>
+
+      <tr>
+        <td>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/GRCr8.zip"><i>R. norvegicus</i>, GRCr8</a>
+        </td>
+        <td align="right">
+            GRC
         </td>
       </tr>
 
@@ -255,12 +273,21 @@
         </td>
       </tr>
 
+      <tr>
+        <td>
+            <a href="https://genome-idx.s3.amazonaws.com/bt/rn4.zip"><i>R. norvegicus</i>, rn4</a>
+        </td>
+        <td align="right">
+            UCSC
+        </td>
+      </tr>
+
       <tr>
         <td>
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCg6a.zip"><i>G. gallus</i>, GRCg6a</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -278,7 +305,7 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCz11.zip"><i>D. rerio</i>, GRCz11</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -287,7 +314,7 @@
             <a href="https://genome-idx.s3.amazonaws.com/bt/GRCz10.zip"><i>D. rerio</i>, GRCz10</a>
         </td>
         <td align="right">
-            NCBI
+            GRC
         </td>
       </tr>
 
@@ -387,4 +414,3 @@
     </ul>
   </div>
 </div> <!-- End of "rightside" -->
-


=====================================
filebuf.h
=====================================
@@ -951,16 +951,27 @@ private:
 	static void writeAsync(AsyncData *asyncDataPtr) {
 		AsyncData &asyncData = *asyncDataPtr;
 		bool abort = false;
+                size_t written = 0;
 		while(!abort) {
 			abort = asyncData.waitForBuf();
 			if(abort) break;
-			if(asyncData.cur != fwrite((const void *)asyncData.buf, 1, asyncData.cur, asyncData.out)) {
+			while (asyncData.cur != 0) {
+                                written += fwrite((const void *)(asyncData.buf + written), 1, asyncData.cur, asyncData.out);
 				if (errno == EPIPE) {
 					exit(EXIT_SUCCESS);
 				}
-				std::cerr << "Error while flushing and closing output" << std::endl;
-				throw 1;
+                                if (feof(asyncData.out) || written == 0)
+                                        break;
+                                // asyncData.buf += written;
+                                asyncData.cur -= written;
+                                written = 0;
 			}
+
+                        if (written != asyncData.cur) {
+                                // std::cerr << "Error while flushing and closing output" << std::endl;
+                                perror("fwrite");
+				throw 1;
+                        }
 			abort = asyncData.writeComplete();
 		}
 


=====================================
opts.h
=====================================
@@ -162,6 +162,7 @@ enum {
 	ARG_ALIGN_PAIRED_READS,     // --align-paired-reads
 	ARG_SRA_ACC,                // --sra-acc
         ARG_SAM_APPEND_COMMENT,     // --sam-append-comment
+        ARG_SAM_OPT_CONFIG,         // --sam-opt-config
 };
 
 #endif


=====================================
pat.cpp
=====================================
@@ -253,9 +253,18 @@ pair<bool, int> DualPatternComposer::nextBatch(PerThreadReadBuf& pt) {
 				assert_eq((*srca_)[cur]->readCount(),
 				          (*srcb_)[cur]->readCount());
 			}
-			if(resa.second < resb.second) {
-				cerr << "Error, fewer reads in file specified with -1 "
-				     << "than in file specified with -2" << endl;
+                        if (resa.second < resb.second) {
+                                cerr << "Error, fewer reads in file specified with -1 "
+                                     << "than in file specified with -2.";
+                                if (resb.second > 0) {
+                                        const char *readOrigBuf = pt.bufb_[resb.second - 1].readOrigBuf.buf();
+                                        const char *newline = strchr(readOrigBuf, '\n');
+
+                                        size_t headerLength = newline - readOrigBuf;
+                                        string header = string(readOrigBuf, headerLength);
+                                        cerr << " Last successfully parsed mate: " << header << ".";
+                                }
+                                cerr << endl;
 				throw 1;
 			} else if(resa.second == 0 && resb.second == 0) {
 				ThreadSafe ts(mutex_m);
@@ -264,9 +273,19 @@ pair<bool, int> DualPatternComposer::nextBatch(PerThreadReadBuf& pt) {
 				}
 				cur = cur_; // Move on to next PatternSource
 				continue; // on to next pair of PatternSources
-			} else if(resb.second < resa.second) {
-				cerr << "Error, fewer reads in file specified with -2 "
-				     << "than in file specified with -1" << endl;
+                        } else if (resb.second < resa.second) {
+                                cerr << "Error, fewer reads in file specified with -2 "
+                                     << "than in file specified with -1.";
+
+                                if (resa.second > 0) {
+                                        const char *readOrigBuf = pt.bufa_[resa.second - 1].readOrigBuf.buf();
+                                        const char *newline = strchr(readOrigBuf, '\n');
+
+                                        size_t headerLength = newline - readOrigBuf;
+                                        string header = string(readOrigBuf, headerLength);
+                                        cerr << " Last successfully parsed mate: " << header << ".";
+                                }
+                                cerr << endl;
 				throw 1;
 			}
 			assert_eq(resa.first, resb.first);
@@ -1426,7 +1445,7 @@ int BAMPatternSource::decompress_bgzf_block(uint8_t *dst, size_t dst_len, uint8_
 		return ret;
 	}
 
-	return inflateReset(&stream);
+	return inflateEnd(&stream);
 }
 
 bool BAMPatternSource::parse(Read& ra, Read& rb, TReadId rdid) const {


=====================================
sam.h
=====================================
@@ -22,6 +22,8 @@
 
 #include <string>
 #include <vector>
+#include <string.h>
+
 #include "ds.h"
 #include "read.h"
 #include "util.h"
@@ -157,6 +159,97 @@ public:
 		assert_eq(refnames_.size(), reflens_.size());
 	}
 
+        void toggleOptFlagByName(string& str) {
+                bool value = false;
+                const char *name = str.c_str();
+
+                if (str.size() < 2) {
+                        cerr << "Error: " << name << " is not a valid SAM Optional flag." << endl;
+                        return;
+                }
+
+                if (name[0] == '-') {
+                        name += 1;
+                } else {
+                        value = true;
+                }
+
+                if (strcasecmp(name, "as") == 0) {
+                        print_yn_ = value;
+                } else if(strcasecmp(name, "xs") == 0) {
+                        print_xs_ = value;
+                } else if(strcasecmp(name, "xss") == 0) {
+                        print_xss_ = value;
+                } else if(strcasecmp(name, "yn") == 0) {
+                        print_yn_ = value;
+                } else if(strcasecmp(name, "xn") == 0) {
+                        print_xn_ = value;
+                } else if(strcasecmp(name, "x0") == 0) {
+                        print_x0_ = value;
+                } else if(strcasecmp(name, "x1") == 0) {
+                        print_x1_ = value;
+                } else if(strcasecmp(name, "xm") == 0) {
+                        print_xm_ = value;
+                } else if(strcasecmp(name, "xo") == 0) {
+                        print_xo_ = value;
+                } else if(strcasecmp(name, "xg") == 0) {
+                        print_xg_ = value;
+                } else if(strcasecmp(name, "nm") == 0) {
+                        print_nm_ = value;
+                } else if(strcasecmp(name, "md") == 0) {
+                        print_md_ = value;
+                } else if(strcasecmp(name, "yf") == 0) {
+                        print_yf_ = value;
+                } else if(strcasecmp(name, "yi") == 0) {
+                        print_yi_ = value;
+                } else if(strcasecmp(name, "ym") == 0) {
+                        print_ym_ = value;
+                } else if(strcasecmp(name, "yp") == 0) {
+                        print_yp_ = value;
+                } else if(strcasecmp(name, "yt") == 0) {
+                        print_yt_ = value;
+                } else if(strcasecmp(name, "ys") == 0) {
+                        print_ys_ = value;
+                } else if(strcasecmp(name, "zs") == 0) {
+                        print_zs_ = value;
+                } else if(strcasecmp(name, "xr") == 0) {
+                        print_xr_ = value;
+                } else if(strcasecmp(name, "xt") == 0) {
+                        print_xt_ = value;
+                } else if(strcasecmp(name, "xd") == 0) {
+                        print_xd_ = value;
+                } else if(strcasecmp(name, "xu") == 0) {
+                        print_xu_ = value;
+                } else if(strcasecmp(name, "ye") == 0) {
+                        print_ye_ = value;
+                } else if(strcasecmp(name, "yl") == 0) {
+                        print_yl_ = value;
+                } else if(strcasecmp(name, "yu") == 0) {
+                        print_yu_ = value;
+                } else if(strcasecmp(name, "xp") == 0) {
+                        print_xp_ = value;
+                } else if(strcasecmp(name, "yr") == 0) {
+                        print_yr_ = value;
+                } else if(strcasecmp(name, "zb") == 0) {
+                        print_zb_ = value;
+                } else if(strcasecmp(name, "zr") == 0) {
+                        print_zr_ = value;
+                } else if(strcasecmp(name, "zf") == 0) {
+                        print_zf_ = value;
+                } else if(strcasecmp(name, "zm") == 0) {
+                        print_zm_ = value;
+                } else if(strcasecmp(name, "zi") == 0) {
+                        print_zi_ = value;
+                } else if(strcasecmp(name, "zp") == 0) {
+                        print_zp_ = value;
+                } else if(strcasecmp(name, "zu") == 0) {
+                        print_zu_ = value;
+                } else if(strcasecmp(name, "zt") == 0) {
+                        print_zt_ = value;
+                } else {
+                        cerr << "Error: " << name << " is not a valid SAM Optional flag." << endl;
+                }
+        }
 	/**
 	 * Print a reference name in a way that doesn't violate SAM's character
 	 * constraints. \*|[!-()+-<>-~][!-~]*


=====================================
tokenize.h
=====================================
@@ -20,6 +20,7 @@
 #ifndef TOKENIZE_H_
 #define TOKENIZE_H_
 
+#include <ctype.h>
 #include <string>
 #include <sstream>
 #include <limits>
@@ -40,8 +41,15 @@ static inline void tokenize(
 	//string::size_type lastPos = s.find_first_not_of(delims, 0);
 	string::size_type lastPos = 0;
 	string::size_type pos = s.find_first_of(delims, lastPos);
+
 	while (string::npos != pos || string::npos != lastPos) {
-		ss.push_back(s.substr(lastPos, pos - lastPos));
+                if (pos == string::npos) {
+                        pos = s.size();
+                }
+                string::size_type rtrim = pos;
+                while (isspace(s[lastPos])) lastPos++;
+                while (rtrim > 0 && isspace(s[rtrim - 1])) rtrim--;
+		ss.push_back(s.substr(lastPos, rtrim - lastPos));
 		lastPos = s.find_first_not_of(delims, pos);
 		pos = s.find_first_of(delims, lastPos);
 		if(ss.size() == (max - 1)) {



View it on GitLab: https://salsa.debian.org/med-team/bowtie2/-/compare/96faea04c484a6e44a75b2f68d77663bb182cff7...1e7e199d3541c5901090f713f0bd6e429f8d5f50

-- 
View it on GitLab: https://salsa.debian.org/med-team/bowtie2/-/compare/96faea04c484a6e44a75b2f68d77663bb182cff7...1e7e199d3541c5901090f713f0bd6e429f8d5f50
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20240807/240f70c6/attachment-0001.htm>


More information about the debian-med-commit mailing list